github.com/go-graphite/carbonapi@v0.17.0/zipper/config/config.go (about)

     1  package config
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/barkimedes/go-deepcopy"
     7  	"go.uber.org/zap"
     8  
     9  	"github.com/go-graphite/carbonapi/zipper/types"
    10  )
    11  
    12  // Config is a structure that contains zipper-related configuration bits
    13  type Config struct {
    14  	SumBuckets                bool             `mapstructure:"sumBuckets"`
    15  	Buckets                   int              `mapstructure:"buckets"`
    16  	BucketsWidth              []int64          `mapstructure:"bucketsWidth"`
    17  	BucketsLabels             []string         `mapstructure:"bucketsLabels"`
    18  	ExtendedStat              bool             `mapstructure:"extendedStat"` // extended stat metrics
    19  	SlowLogThreshold          time.Duration    `mapstructure:"slowLogThreshold"`
    20  	ConcurrencyLimitPerServer int              `mapstructure:"concurrencyLimitPerServer"`
    21  	MaxIdleConnsPerHost       int              `mapstructure:"maxIdleConnsPerHost"`
    22  	Backends                  []string         `mapstructure:"backends"`
    23  	BackendsV2                types.BackendsV2 `mapstructure:"backendsv2"`
    24  	MaxBatchSize              *int             `mapstructure:"maxBatchSize"`
    25  	FallbackMaxBatchSize      int              `mapstructure:"-"`
    26  	MaxTries                  int              `mapstructure:"maxTries"`
    27  	DoMultipleRequestsIfSplit bool             `mapstructure:"doMultipleRequestsIfSplit"`
    28  	RequireSuccessAll         bool             `mapstructure:"requireSuccessAll"` // require full success for upstreams queries (for multi-target query)
    29  
    30  	ExpireDelaySec       int32
    31  	TLDCacheDisabled     bool `mapstructure:"tldCacheDisabled"`
    32  	InternalRoutingCache time.Duration
    33  	Timeouts             types.Timeouts
    34  	KeepAliveInterval    time.Duration `mapstructure:"keepAliveInterval"`
    35  
    36  	// ScaleToCommonStep controls if metrics in one target should be aggregated to common step
    37  	ScaleToCommonStep bool `mapstructure:"scaleToCommonStep"`
    38  
    39  	isSanitized bool
    40  }
    41  
    42  func (cfg *Config) IsSanitized() bool {
    43  	return cfg.isSanitized
    44  }
    45  
    46  var defaultTimeouts = types.Timeouts{
    47  	Render:  10000 * time.Second,
    48  	Find:    100 * time.Second,
    49  	Connect: 200 * time.Millisecond,
    50  }
    51  
    52  func sanitizeTimeouts(timeouts, defaultTimeouts types.Timeouts) types.Timeouts {
    53  	if timeouts.Render == 0 {
    54  		timeouts.Render = defaultTimeouts.Render
    55  	}
    56  	if timeouts.Find == 0 {
    57  		timeouts.Find = defaultTimeouts.Find
    58  	}
    59  
    60  	if timeouts.Connect == 0 {
    61  		timeouts.Connect = defaultTimeouts.Connect
    62  	}
    63  
    64  	return timeouts
    65  }
    66  
    67  // SanitizeConfig perform old kind of checks and conversions for zipper's configuration
    68  func SanitizeConfig(logger *zap.Logger, oldConfig Config) *Config {
    69  	// create a full copy of old config
    70  	newConfigPtr, err := deepcopy.Anything(oldConfig)
    71  	if err != nil {
    72  		logger.Fatal("failed to copy old config", zap.Error(err))
    73  	}
    74  	newConfig := newConfigPtr.(Config)
    75  
    76  	if len(newConfig.BucketsWidth) > 0 {
    77  		newConfig.Buckets = 0
    78  	}
    79  
    80  	if newConfig.MaxBatchSize == nil {
    81  		newConfig.MaxBatchSize = &newConfig.FallbackMaxBatchSize
    82  	}
    83  
    84  	newConfig.Timeouts = sanitizeTimeouts(newConfig.Timeouts, defaultTimeouts)
    85  
    86  	if newConfig.InternalRoutingCache.Seconds() < 30 {
    87  		logger.Warn("internalRoutingCache is too low",
    88  			zap.String("reason", "this variable is used for internal routing cache, minimum allowed is 30s"),
    89  			zap.String("recommendation", "it's usually good idea to set it to something like 600s"),
    90  		)
    91  		newConfig.InternalRoutingCache = 30 * time.Second
    92  	}
    93  
    94  	// Convert old config format to new one
    95  	defaultIdleConnTimeout := 3600 * time.Second
    96  	if newConfig.Backends != nil && len(newConfig.Backends) != 0 {
    97  		newConfig.BackendsV2 = types.BackendsV2{
    98  			Backends: []types.BackendV2{
    99  				{
   100  					GroupName:                 "backends",
   101  					Protocol:                  "carbonapi_v2_pb",
   102  					LBMethod:                  "broadcast",
   103  					Servers:                   newConfig.Backends,
   104  					Timeouts:                  &newConfig.Timeouts,
   105  					ConcurrencyLimit:          &newConfig.ConcurrencyLimitPerServer,
   106  					DoMultipleRequestsIfSplit: true,
   107  					KeepAliveInterval:         &newConfig.KeepAliveInterval,
   108  					MaxIdleConnsPerHost:       &newConfig.MaxIdleConnsPerHost,
   109  					MaxTries:                  &newConfig.MaxTries,
   110  					MaxBatchSize:              newConfig.MaxBatchSize,
   111  					IdleConnectionTimeout:     &defaultIdleConnTimeout,
   112  				},
   113  			},
   114  			MaxIdleConnsPerHost:       newConfig.MaxIdleConnsPerHost,
   115  			ConcurrencyLimitPerServer: newConfig.ConcurrencyLimitPerServer,
   116  			Timeouts:                  newConfig.Timeouts,
   117  			KeepAliveInterval:         newConfig.KeepAliveInterval,
   118  			MaxTries:                  newConfig.MaxTries,
   119  			MaxBatchSize:              newConfig.MaxBatchSize,
   120  		}
   121  
   122  		newConfig.DoMultipleRequestsIfSplit = true
   123  	}
   124  
   125  	newConfig.BackendsV2.Timeouts = sanitizeTimeouts(newConfig.BackendsV2.Timeouts, newConfig.Timeouts)
   126  	for i := range newConfig.BackendsV2.Backends {
   127  		if newConfig.BackendsV2.Backends[i].Timeouts == nil {
   128  			timeouts := newConfig.BackendsV2.Timeouts
   129  			newConfig.BackendsV2.Backends[i].Timeouts = &timeouts
   130  		}
   131  		timeouts := sanitizeTimeouts(*(newConfig.BackendsV2.Backends[i].Timeouts), newConfig.BackendsV2.Timeouts)
   132  		newConfig.BackendsV2.Backends[i].Timeouts = &timeouts
   133  		if newConfig.BackendsV2.Backends[i].IdleConnectionTimeout == nil {
   134  			newConfig.BackendsV2.Backends[i].IdleConnectionTimeout = &defaultIdleConnTimeout
   135  		}
   136  	}
   137  
   138  	if newConfig.BackendsV2.MaxBatchSize == nil {
   139  		newConfig.BackendsV2.MaxBatchSize = newConfig.MaxBatchSize
   140  	}
   141  
   142  	newConfig.isSanitized = true
   143  	return &newConfig
   144  }