diff --git a/cmd/jaeger/internal/all-in-one.yaml b/cmd/jaeger/internal/all-in-one.yaml index d8a8bb88b8e5..9a9713041fa0 100644 --- a/cmd/jaeger/internal/all-in-one.yaml +++ b/cmd/jaeger/internal/all-in-one.yaml @@ -31,6 +31,7 @@ extensions: # We can either use file or adaptive sampling strategy in remote_sampling file: path: + reload_interval: 1s # adaptive: # sampling_store: some_store # initial_sampling_probability: 0.1 diff --git a/cmd/jaeger/internal/extension/remotesampling/config.go b/cmd/jaeger/internal/extension/remotesampling/config.go index 7df4d0ff81b4..041f52655647 100644 --- a/cmd/jaeger/internal/extension/remotesampling/config.go +++ b/cmd/jaeger/internal/extension/remotesampling/config.go @@ -5,6 +5,7 @@ package remotesampling import ( "errors" + "time" "github.com/asaskevich/govalidator" "go.opentelemetry.io/collector/component" @@ -18,6 +19,7 @@ import ( var ( errNoProvider = errors.New("no sampling strategy provider specified, expecting 'adaptive' or 'file'") errMultipleProviders = errors.New("only one sampling strategy provider can be specified, 'adaptive' or 'file'") + errNegativeInterval = errors.New("reload interval must be a positive value, or zero to disable automatic reloading") ) var ( @@ -36,6 +38,8 @@ type Config struct { type FileConfig struct { // File specifies a local file as the source of sampling strategies. Path string `mapstructure:"path"` + // ReloadInterval is the time interval to check and reload sampling strategies file + ReloadInterval time.Duration `mapstructure:"reload_interval"` } type AdaptiveConfig struct { @@ -86,6 +90,10 @@ func (cfg *Config) Validate() error { return errMultipleProviders } + if cfg.File != nil && cfg.File.ReloadInterval < 0 { + return errNegativeInterval + } + _, err := govalidator.ValidateStruct(cfg) return err } diff --git a/cmd/jaeger/internal/extension/remotesampling/config_test.go b/cmd/jaeger/internal/extension/remotesampling/config_test.go index 319b9b204639..4993f6410a09 100644 --- a/cmd/jaeger/internal/extension/remotesampling/config_test.go +++ b/cmd/jaeger/internal/extension/remotesampling/config_test.go @@ -51,6 +51,13 @@ func Test_Validate(t *testing.T) { }, expectedErr: "", }, + { + name: "File provider has negative reload interval", + config: &Config{ + File: &FileConfig{Path: "", ReloadInterval: -1}, + }, + expectedErr: "must be a positive value", + }, { name: "Invalid Adaptive provider", config: &Config{ @@ -66,7 +73,7 @@ func Test_Validate(t *testing.T) { if tt.expectedErr == "" { require.NoError(t, err) } else { - assert.Equal(t, tt.expectedErr, err.Error()) + assert.ErrorContains(t, err, tt.expectedErr) } }) } diff --git a/cmd/jaeger/internal/extension/remotesampling/extension.go b/cmd/jaeger/internal/extension/remotesampling/extension.go index 43a8661f07a7..1020dccda910 100644 --- a/cmd/jaeger/internal/extension/remotesampling/extension.go +++ b/cmd/jaeger/internal/extension/remotesampling/extension.go @@ -166,6 +166,7 @@ func (ext *rsExtension) Shutdown(ctx context.Context) error { func (ext *rsExtension) startFileBasedStrategyProvider(_ context.Context) error { opts := static.Options{ StrategiesFile: ext.cfg.File.Path, + ReloadInterval: ext.cfg.File.ReloadInterval, } // contextcheck linter complains about next line that context is not passed. diff --git a/plugin/sampling/strategyprovider/static/provider.go b/plugin/sampling/strategyprovider/static/provider.go index 8c801de8f797..f05ea4528c84 100644 --- a/plugin/sampling/strategyprovider/static/provider.go +++ b/plugin/sampling/strategyprovider/static/provider.go @@ -146,7 +146,6 @@ func (h *samplingProvider) samplingStrategyLoader(strategiesFile string) strateg } return func() ([]byte, error) { - h.logger.Info("Loading sampling strategies", zap.String("filename", strategiesFile)) currBytes, err := os.ReadFile(filepath.Clean(strategiesFile)) if err != nil { return nil, fmt.Errorf("failed to read strategies file %s: %w", strategiesFile, err)