github.com/yankunsam/loki/v2@v2.6.3-0.20220817130409-389df5235c27/pkg/util/ring_config.go (about)

     1  package util
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	"os"
     7  	"time"
     8  
     9  	"github.com/go-kit/log"
    10  
    11  	"github.com/go-kit/log/level"
    12  	"github.com/grafana/dskit/flagext"
    13  	"github.com/grafana/dskit/kv"
    14  	"github.com/grafana/dskit/netutil"
    15  	"github.com/grafana/dskit/ring"
    16  
    17  	util_log "github.com/grafana/loki/pkg/util/log"
    18  )
    19  
    20  // RingConfig masks the ring lifecycler config which contains
    21  // many options not really required by the distributors ring. This config
    22  // is used to strip down the config to the minimum, and avoid confusion
    23  // to the user.
    24  type RingConfig struct {
    25  	KVStore              kv.Config     `yaml:"kvstore"`
    26  	HeartbeatPeriod      time.Duration `yaml:"heartbeat_period"`
    27  	HeartbeatTimeout     time.Duration `yaml:"heartbeat_timeout"`
    28  	TokensFilePath       string        `yaml:"tokens_file_path"`
    29  	ZoneAwarenessEnabled bool          `yaml:"zone_awareness_enabled"`
    30  
    31  	// Instance details
    32  	InstanceID             string   `yaml:"instance_id"`
    33  	InstanceInterfaceNames []string `yaml:"instance_interface_names" doc:"default=[<private network interfaces>]"`
    34  	InstancePort           int      `yaml:"instance_port"`
    35  	InstanceAddr           string   `yaml:"instance_addr"`
    36  	InstanceZone           string   `yaml:"instance_availability_zone"`
    37  
    38  	// Injected internally
    39  	ListenPort int `yaml:"-"`
    40  
    41  	ObservePeriod time.Duration `yaml:"-"`
    42  }
    43  
    44  // RegisterFlagsWithPrefix adds the flags required to config this to the given FlagSet
    45  // storePrefix is used to set the path in the KVStore and should end with a /
    46  func (cfg *RingConfig) RegisterFlagsWithPrefix(flagsPrefix, storePrefix string, f *flag.FlagSet) {
    47  	hostname, err := os.Hostname()
    48  	if err != nil {
    49  		level.Error(util_log.Logger).Log("msg", "failed to get hostname", "err", err)
    50  		os.Exit(1)
    51  	}
    52  
    53  	// Ring flags
    54  	cfg.KVStore.RegisterFlagsWithPrefix(flagsPrefix+"ring.", storePrefix, f)
    55  	f.DurationVar(&cfg.HeartbeatPeriod, flagsPrefix+"ring.heartbeat-period", 15*time.Second, "Period at which to heartbeat to the ring. 0 = disabled.")
    56  	f.DurationVar(&cfg.HeartbeatTimeout, flagsPrefix+"ring.heartbeat-timeout", time.Minute, "The heartbeat timeout after which compactors are considered unhealthy within the ring. 0 = never (timeout disabled).")
    57  	f.StringVar(&cfg.TokensFilePath, flagsPrefix+"ring.tokens-file-path", "", "File path where tokens are stored. If empty, tokens are not stored at shutdown and restored at startup.")
    58  	f.BoolVar(&cfg.ZoneAwarenessEnabled, flagsPrefix+"ring.zone-awareness-enabled", false, "True to enable zone-awareness and replicate blocks across different availability zones.")
    59  
    60  	// Instance flags
    61  	cfg.InstanceInterfaceNames = netutil.PrivateNetworkInterfacesWithFallback([]string{"eth0", "en0"}, util_log.Logger)
    62  	f.Var((*flagext.StringSlice)(&cfg.InstanceInterfaceNames), flagsPrefix+"ring.instance-interface-names", "Name of network interface to read address from.")
    63  	f.StringVar(&cfg.InstanceAddr, flagsPrefix+"ring.instance-addr", "", "IP address to advertise in the ring.")
    64  	f.IntVar(&cfg.InstancePort, flagsPrefix+"ring.instance-port", 0, "Port to advertise in the ring (defaults to server.grpc-listen-port).")
    65  	f.StringVar(&cfg.InstanceID, flagsPrefix+"ring.instance-id", hostname, "Instance ID to register in the ring.")
    66  	f.StringVar(&cfg.InstanceZone, flagsPrefix+"ring.instance-availability-zone", "", "The availability zone where this instance is running. Required if zone-awareness is enabled.")
    67  }
    68  
    69  // ToLifecyclerConfig returns a LifecyclerConfig based on the compactor ring config.
    70  func (cfg *RingConfig) ToLifecyclerConfig(numTokens int, logger log.Logger) (ring.BasicLifecyclerConfig, error) {
    71  	instanceAddr, err := ring.GetInstanceAddr(cfg.InstanceAddr, cfg.InstanceInterfaceNames, logger)
    72  	if err != nil {
    73  		return ring.BasicLifecyclerConfig{}, err
    74  	}
    75  
    76  	instancePort := ring.GetInstancePort(cfg.InstancePort, cfg.ListenPort)
    77  
    78  	return ring.BasicLifecyclerConfig{
    79  		ID:                  cfg.InstanceID,
    80  		Addr:                fmt.Sprintf("%s:%d", instanceAddr, instancePort),
    81  		Zone:                cfg.InstanceZone,
    82  		HeartbeatPeriod:     cfg.HeartbeatPeriod,
    83  		TokensObservePeriod: 0,
    84  		NumTokens:           numTokens,
    85  	}, nil
    86  }
    87  
    88  func CortexLifecyclerConfigToRingConfig(cfg ring.LifecyclerConfig) RingConfig {
    89  	return RingConfig{
    90  		KVStore: kv.Config{
    91  			Store:       cfg.RingConfig.KVStore.Store,
    92  			Prefix:      cfg.RingConfig.KVStore.Prefix,
    93  			StoreConfig: cfg.RingConfig.KVStore.StoreConfig,
    94  		},
    95  		HeartbeatPeriod:        cfg.HeartbeatPeriod,
    96  		HeartbeatTimeout:       cfg.RingConfig.HeartbeatTimeout,
    97  		TokensFilePath:         cfg.TokensFilePath,
    98  		ZoneAwarenessEnabled:   cfg.RingConfig.ZoneAwarenessEnabled,
    99  		InstanceID:             cfg.ID,
   100  		InstanceInterfaceNames: cfg.InfNames,
   101  		InstancePort:           cfg.Port,
   102  		InstanceAddr:           cfg.Addr,
   103  		InstanceZone:           cfg.Zone,
   104  		ListenPort:             cfg.ListenPort,
   105  		ObservePeriod:          cfg.ObservePeriod,
   106  	}
   107  }
   108  
   109  func (cfg *RingConfig) ToRingConfig(replicationFactor int) ring.Config {
   110  	rc := ring.Config{}
   111  	flagext.DefaultValues(&rc)
   112  
   113  	rc.KVStore = cfg.KVStore
   114  	rc.HeartbeatTimeout = cfg.HeartbeatTimeout
   115  	rc.ZoneAwarenessEnabled = cfg.ZoneAwarenessEnabled
   116  	rc.ReplicationFactor = replicationFactor
   117  
   118  	return rc
   119  }