github.com/grafana/pyroscope@v1.18.0/pkg/util/ring_config.go (about)

     1  // SPDX-License-Identifier: AGPL-3.0-only
     2  
     3  package util
     4  
     5  import (
     6  	"flag"
     7  	"fmt"
     8  	"os"
     9  	"time"
    10  
    11  	"github.com/go-kit/log"
    12  	"github.com/go-kit/log/level"
    13  	"github.com/grafana/dskit/flagext"
    14  	"github.com/grafana/dskit/kv"
    15  	"github.com/grafana/dskit/netutil"
    16  	"github.com/grafana/dskit/ring"
    17  )
    18  
    19  // CommonRingConfig is the configuration commonly used by components that use a ring
    20  // for various coordination tasks such as sharding or service discovery.
    21  type CommonRingConfig struct {
    22  	// KV store details
    23  	KVStore          kv.Config     `yaml:"kvstore" doc:"description=The key-value store used to share the hash ring across multiple instances."`
    24  	HeartbeatPeriod  time.Duration `yaml:"heartbeat_period" category:"advanced"`
    25  	HeartbeatTimeout time.Duration `yaml:"heartbeat_timeout" category:"advanced"`
    26  
    27  	// Instance details
    28  	InstanceID             string   `yaml:"instance_id" doc:"default=<hostname>" category:"advanced"`
    29  	InstanceInterfaceNames []string `yaml:"instance_interface_names" doc:"default=[<private network interfaces>]"`
    30  	InstancePort           int      `yaml:"instance_port" category:"advanced"`
    31  	InstanceAddr           string   `yaml:"instance_addr" category:"advanced"`
    32  	EnableIPv6             bool     `yaml:"instance_enable_ipv6" category:"advanced"`
    33  
    34  	// Injected internally
    35  	ListenPort int `yaml:"-"`
    36  }
    37  
    38  // RegisterFlags adds the flags required to config this to the given FlagSet
    39  func (cfg *CommonRingConfig) RegisterFlags(flagPrefix, kvStorePrefix, componentPlural string, f *flag.FlagSet, logger log.Logger) {
    40  	hostname, err := os.Hostname()
    41  	if err != nil {
    42  		level.Error(logger).Log("msg", "failed to get hostname", "err", err)
    43  		os.Exit(1)
    44  	}
    45  
    46  	// Ring flags
    47  	cfg.KVStore.Store = "memberlist"
    48  	cfg.KVStore.RegisterFlagsWithPrefix(flagPrefix, kvStorePrefix, f)
    49  	f.DurationVar(&cfg.HeartbeatPeriod, flagPrefix+"heartbeat-period", 15*time.Second, "Period at which to heartbeat to the ring. 0 = disabled.")
    50  	f.DurationVar(&cfg.HeartbeatTimeout, flagPrefix+"heartbeat-timeout", time.Minute, fmt.Sprintf("The heartbeat timeout after which %s are considered unhealthy within the ring. 0 = never (timeout disabled).", componentPlural))
    51  
    52  	// Instance flags
    53  	cfg.InstanceInterfaceNames = netutil.PrivateNetworkInterfacesWithFallback([]string{"eth0", "en0"}, logger)
    54  	f.Var((*flagext.StringSlice)(&cfg.InstanceInterfaceNames), flagPrefix+"instance-interface-names", "List of network interface names to look up when finding the instance IP address.")
    55  	f.StringVar(&cfg.InstanceAddr, flagPrefix+"instance-addr", "", "IP address to advertise in the ring. Default is auto-detected.")
    56  	f.IntVar(&cfg.InstancePort, flagPrefix+"instance-port", 0, "Port to advertise in the ring (defaults to -server.http-listen-port).")
    57  	f.StringVar(&cfg.InstanceID, flagPrefix+"instance-id", hostname, "Instance ID to register in the ring.")
    58  	f.BoolVar(&cfg.EnableIPv6, flagPrefix+"instance-enable-ipv6", false, "Enable using a IPv6 instance address. (default false)")
    59  }
    60  
    61  func (cfg *CommonRingConfig) ToRingConfig() ring.Config {
    62  	rc := ring.Config{}
    63  	flagext.DefaultValues(&rc)
    64  
    65  	rc.KVStore = cfg.KVStore
    66  	rc.HeartbeatTimeout = cfg.HeartbeatTimeout
    67  	return rc
    68  }