diff --git a/CHANGELOG.md b/CHANGELOG.md index 77aec5cb7aacb..a39d60568a4c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * [4453](https://github.com/grafana/loki/pull/4453) **liguozhong**: Loki: Implement retry to s3 chunk storage * [4542](https://github.com/grafana/loki/pull/4542) **owen-d**: Introduce the `loki_overrides_defaults` metric and only export diffs for tenant limits. * [4498](https://github.com/grafana/loki/pull/4498) **trevorwhitney**: Feature: add virtual read and write targets +* [4543](https://github.com/grafana/loki/pull/4543) **trevorwhitney**: Change more default values and improve application of common storage config # 2.3.0 (2021/08/06) diff --git a/docs/sources/upgrading/_index.md b/docs/sources/upgrading/_index.md index 5242ecbfc69a6..c590b3ec57b80 100644 --- a/docs/sources/upgrading/_index.md +++ b/docs/sources/upgrading/_index.md @@ -19,6 +19,29 @@ If possible try to stay current and do sequential updates. If you want to skip v ### Loki +#### Ingester WAL now defaults to on, and chunk transfers are disabled by default + +* [4543](https://github.com/grafana/loki/pull/4543) **trevorwhitney**: Change more default values and improve application of common storage config + +This changes a few default values, resulting in the ingester WAL now being on by default, +and chunk transfer retries are disabled by default. Note, this now means Loki will depend on local disk by default for it's WAL (write ahead log) directory. This defaults to `wal` but can be overridden via the `--ingester.wal-dir` or via `path_prefix` in the common configuration section. Below are config snippets with the previous defaults, and another with the new values. + +Previous defaults: +```yaml +ingester: + max_transfer_retries: 10 + wal: + enabled: false +``` + +New defaults: +```yaml +ingester: + max_transfer_retries: 0 + wal: + enabled: true +``` + #### Distributor now stores ring in memory by default instead of Consul PR [4440](https://github.com/grafana/loki/pull/4440) **DylanGuedes**: Config: Override distributor's default ring KV store diff --git a/pkg/ingester/flush_test.go b/pkg/ingester/flush_test.go index 5d40933665648..ae865fc2c9acb 100644 --- a/pkg/ingester/flush_test.go +++ b/pkg/ingester/flush_test.go @@ -290,6 +290,7 @@ func defaultIngesterTestConfig(t testing.TB) Config { cfg.LifecyclerConfig.MinReadyDuration = 0 cfg.BlockSize = 256 * 1024 cfg.TargetChunkSize = 1500 * 1024 + cfg.WAL.Enabled = false return cfg } diff --git a/pkg/ingester/ingester.go b/pkg/ingester/ingester.go index e110990936c51..828f175ccfb38 100644 --- a/pkg/ingester/ingester.go +++ b/pkg/ingester/ingester.go @@ -90,7 +90,7 @@ func (cfg *Config) RegisterFlags(f *flag.FlagSet) { cfg.LifecyclerConfig.RegisterFlags(f) cfg.WAL.RegisterFlags(f) - f.IntVar(&cfg.MaxTransferRetries, "ingester.max-transfer-retries", 10, "Number of times to try and transfer chunks before falling back to flushing. If set to 0 or negative value, transfers are disabled.") + f.IntVar(&cfg.MaxTransferRetries, "ingester.max-transfer-retries", 0, "Number of times to try and transfer chunks before falling back to flushing. If set to 0 or negative value, transfers are disabled.") f.IntVar(&cfg.ConcurrentFlushes, "ingester.concurrent-flushes", 16, "") f.DurationVar(&cfg.FlushCheckPeriod, "ingester.flush-check-period", 30*time.Second, "") f.DurationVar(&cfg.FlushOpTimeout, "ingester.flush-op-timeout", 10*time.Second, "") diff --git a/pkg/ingester/wal.go b/pkg/ingester/wal.go index badb69502981c..00efc054fe846 100644 --- a/pkg/ingester/wal.go +++ b/pkg/ingester/wal.go @@ -41,7 +41,7 @@ func (cfg *WALConfig) Validate() error { // RegisterFlags adds the flags required to config this to the given FlagSet func (cfg *WALConfig) RegisterFlags(f *flag.FlagSet) { f.StringVar(&cfg.Dir, "ingester.wal-dir", "wal", "Directory to store the WAL and/or recover from WAL.") - f.BoolVar(&cfg.Enabled, "ingester.wal-enabled", false, "Enable writing of ingested data into WAL.") + f.BoolVar(&cfg.Enabled, "ingester.wal-enabled", true, "Enable writing of ingested data into WAL.") f.DurationVar(&cfg.CheckpointDuration, "ingester.checkpoint-duration", 5*time.Minute, "Interval at which checkpoints should be created.") f.BoolVar(&cfg.FlushOnShutdown, "ingester.flush-on-shutdown", false, "When WAL is enabled, should chunks be flushed to long-term storage on shutdown.") diff --git a/pkg/loki/common/common.go b/pkg/loki/common/common.go index c0e11bf2f2abe..d85d01d0cbda0 100644 --- a/pkg/loki/common/common.go +++ b/pkg/loki/common/common.go @@ -1,6 +1,8 @@ package common import ( + "flag" + "github.com/grafana/loki/pkg/storage/chunk/aws" "github.com/grafana/loki/pkg/storage/chunk/azure" "github.com/grafana/loki/pkg/storage/chunk/gcp" @@ -14,10 +16,22 @@ type Config struct { Storage Storage `yaml:"storage"` } +func (c *Config) RegisterFlags(f *flag.FlagSet) { + c.Storage.RegisterFlagsWithPrefix("common.storage", f) +} + type Storage struct { - S3 *aws.S3Config `yaml:"s3"` - GCS *gcp.GCSConfig `yaml:"gcs"` - Azure *azure.BlobStorageConfig `yaml:"azure"` - Swift *openstack.SwiftConfig `yaml:"swift"` - FSConfig *local.FSConfig `yaml:"filesystem"` + S3 aws.S3Config `yaml:"s3"` + GCS gcp.GCSConfig `yaml:"gcs"` + Azure azure.BlobStorageConfig `yaml:"azure"` + Swift openstack.SwiftConfig `yaml:"swift"` + FSConfig local.FSConfig `yaml:"filesystem"` +} + +func (s *Storage) RegisterFlagsWithPrefix(prefix string, f *flag.FlagSet) { + s.S3.RegisterFlagsWithPrefix(prefix+".s3", f) + s.GCS.RegisterFlagsWithPrefix(prefix+".gcs", f) + s.Azure.RegisterFlagsWithPrefix(prefix+".azure", f) + s.Swift.RegisterFlagsWithPrefix(prefix+".swift", f) + s.FSConfig.RegisterFlagsWithPrefix(prefix+".filesystem", f) } diff --git a/pkg/loki/config_wrapper.go b/pkg/loki/config_wrapper.go index 8ec740203858f..ba392712b00d5 100644 --- a/pkg/loki/config_wrapper.go +++ b/pkg/loki/config_wrapper.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "reflect" + "strings" cortexcache "github.com/cortexproject/cortex/pkg/chunk/cache" "github.com/grafana/dskit/flagext" @@ -66,17 +67,6 @@ func (c *ConfigWrapper) ApplyDynamicConfig() cfg.Source { return errors.New("dst is not a Loki ConfigWrapper") } - // Apply all our custom logic here to set values in the Loki config from values in the common config - if r.Common.PathPrefix != "" { - if r.Ruler.RulePath == defaults.Ruler.RulePath { - r.Ruler.RulePath = fmt.Sprintf("%s/rules", r.Common.PathPrefix) - } - - if r.Ingester.WAL.Dir == defaults.Ingester.WAL.Dir { - r.Ingester.WAL.Dir = fmt.Sprintf("%s/wal", r.Common.PathPrefix) - } - } - // If nobody has defined any frontend address or scheduler address // we can default to using the query scheduler ring for scheduler discovery. if r.Worker.FrontendAddress == "" && @@ -86,6 +76,7 @@ func (c *ConfigWrapper) ApplyDynamicConfig() cfg.Source { } applyIngesterRingConfig(r) + applyPathPrefixDefaults(r, defaults) applyMemberlistConfig(r) if err := applyStorageConfig(r, &defaults); err != nil { @@ -149,6 +140,24 @@ func applyIngesterRingConfig(r *ConfigWrapper) { r.QueryScheduler.SchedulerRing.KVStore.StoreConfig = sc } +func applyPathPrefixDefaults(r *ConfigWrapper, defaults ConfigWrapper) { + if r.Common.PathPrefix != "" { + prefix := strings.TrimSuffix(r.Common.PathPrefix, "/") + + if r.Ruler.RulePath == defaults.Ruler.RulePath { + r.Ruler.RulePath = fmt.Sprintf("%s/rules", prefix) + } + + if r.Ingester.WAL.Dir == defaults.Ingester.WAL.Dir { + r.Ingester.WAL.Dir = fmt.Sprintf("%s/wal", prefix) + } + + if r.CompactorConfig.WorkingDirectory == defaults.CompactorConfig.WorkingDirectory { + r.CompactorConfig.WorkingDirectory = fmt.Sprintf("%s/compactor", prefix) + } + } +} + // applyMemberlistConfig will change the default ingester, distributor, ruler, and query scheduler ring configurations to use memberlist // if the -memberlist.join_members config is provided. The idea here is that if a user explicitly configured the // memberlist configuration section, they probably want to be using memberlist for all their ring configurations. @@ -171,78 +180,62 @@ var ErrTooManyStorageConfigs = errors.New("too many storage configs provided in // configuration file, applyStorageConfig will not override them. // If multiple storage configurations are provided, applyStorageConfig will return an error func applyStorageConfig(cfg, defaults *ConfigWrapper) error { - var applyRulerStoreConfig func(*ConfigWrapper) - var applyChunkStorageConfig func(*ConfigWrapper) + var applyConfig func(*ConfigWrapper) //only one config is allowed configsFound := 0 - if cfg.Common.Storage.Azure != nil { + if !reflect.DeepEqual(cfg.Common.Storage.Azure, defaults.StorageConfig.AzureStorageConfig) { configsFound++ - applyRulerStoreConfig = func(r *ConfigWrapper) { + applyConfig = func(r *ConfigWrapper) { r.Ruler.StoreConfig.Type = "azure" r.Ruler.StoreConfig.Azure = r.Common.Storage.Azure.ToCortexAzureConfig() - } - - applyChunkStorageConfig = func(r *ConfigWrapper) { - r.StorageConfig.AzureStorageConfig = *r.Common.Storage.Azure + r.StorageConfig.AzureStorageConfig = r.Common.Storage.Azure r.CompactorConfig.SharedStoreType = chunk_storage.StorageTypeAzure } } - if cfg.Common.Storage.FSConfig != nil { + if !reflect.DeepEqual(cfg.Common.Storage.FSConfig, defaults.StorageConfig.FSConfig) { configsFound++ - applyRulerStoreConfig = func(r *ConfigWrapper) { + applyConfig = func(r *ConfigWrapper) { r.Ruler.StoreConfig.Type = "local" r.Ruler.StoreConfig.Local = r.Common.Storage.FSConfig.ToCortexLocalConfig() - } - - applyChunkStorageConfig = func(r *ConfigWrapper) { - r.StorageConfig.FSConfig = *r.Common.Storage.FSConfig + r.StorageConfig.FSConfig = r.Common.Storage.FSConfig r.CompactorConfig.SharedStoreType = chunk_storage.StorageTypeFileSystem } } - if cfg.Common.Storage.GCS != nil { + if !reflect.DeepEqual(cfg.Common.Storage.GCS, defaults.StorageConfig.GCSConfig) { configsFound++ - applyRulerStoreConfig = func(r *ConfigWrapper) { + applyConfig = func(r *ConfigWrapper) { r.Ruler.StoreConfig.Type = "gcs" r.Ruler.StoreConfig.GCS = r.Common.Storage.GCS.ToCortexGCSConfig() - } - - applyChunkStorageConfig = func(r *ConfigWrapper) { - r.StorageConfig.GCSConfig = *r.Common.Storage.GCS + r.StorageConfig.GCSConfig = r.Common.Storage.GCS r.CompactorConfig.SharedStoreType = chunk_storage.StorageTypeGCS } } - if cfg.Common.Storage.S3 != nil { + if !reflect.DeepEqual(cfg.Common.Storage.S3, defaults.StorageConfig.AWSStorageConfig.S3Config) { configsFound++ - applyRulerStoreConfig = func(r *ConfigWrapper) { + applyConfig = func(r *ConfigWrapper) { r.Ruler.StoreConfig.Type = "s3" r.Ruler.StoreConfig.S3 = r.Common.Storage.S3.ToCortexS3Config() - } - - applyChunkStorageConfig = func(r *ConfigWrapper) { - r.StorageConfig.AWSStorageConfig.S3Config = *r.Common.Storage.S3 + r.StorageConfig.AWSStorageConfig.S3Config = r.Common.Storage.S3 r.CompactorConfig.SharedStoreType = chunk_storage.StorageTypeS3 } } - if cfg.Common.Storage.Swift != nil { + if !reflect.DeepEqual(cfg.Common.Storage.Swift, defaults.StorageConfig.Swift) { configsFound++ - applyRulerStoreConfig = func(r *ConfigWrapper) { + applyConfig = func(r *ConfigWrapper) { r.Ruler.StoreConfig.Type = "swift" r.Ruler.StoreConfig.Swift = r.Common.Storage.Swift.ToCortexSwiftConfig() - } - - applyChunkStorageConfig = func(r *ConfigWrapper) { - r.StorageConfig.Swift = *r.Common.Storage.Swift + r.StorageConfig.Swift = r.Common.Storage.Swift r.CompactorConfig.SharedStoreType = chunk_storage.StorageTypeSwift } } @@ -251,22 +244,11 @@ func applyStorageConfig(cfg, defaults *ConfigWrapper) error { return ErrTooManyStorageConfigs } - applyRulerStoreConfigs(cfg, defaults, applyRulerStoreConfig) - applyChunkStorageConfigs(cfg, defaults, applyChunkStorageConfig) - - return nil -} - -func applyRulerStoreConfigs(cfg, defaults *ConfigWrapper, apply func(*ConfigWrapper)) { - if apply != nil && reflect.DeepEqual(cfg.Ruler.StoreConfig, defaults.Ruler.StoreConfig) { - apply(cfg) + if applyConfig != nil { + applyConfig(cfg) } -} -func applyChunkStorageConfigs(cfg, defaults *ConfigWrapper, apply func(*ConfigWrapper)) { - if apply != nil && reflect.DeepEqual(cfg.StorageConfig, defaults.StorageConfig) { - apply(cfg) - } + return nil } func betterBoltdbShipperDefaults(cfg, defaults *ConfigWrapper) { @@ -280,6 +262,18 @@ func betterBoltdbShipperDefaults(cfg, defaults *ConfigWrapper) { if cfg.CompactorConfig.SharedStoreType == defaults.CompactorConfig.SharedStoreType { cfg.CompactorConfig.SharedStoreType = currentSchema.ObjectType } + + if cfg.Common.PathPrefix != "" { + prefix := strings.TrimSuffix(cfg.Common.PathPrefix, "/") + + if cfg.StorageConfig.BoltDBShipperConfig.ActiveIndexDirectory == "" { + cfg.StorageConfig.BoltDBShipperConfig.ActiveIndexDirectory = fmt.Sprintf("%s/boltdb-shipper-active", prefix) + } + + if cfg.StorageConfig.BoltDBShipperConfig.CacheLocation == "" { + cfg.StorageConfig.BoltDBShipperConfig.CacheLocation = fmt.Sprintf("%s/boltdb-shipper-cache", prefix) + } + } } // applyFIFOCacheConfig turns on FIFO cache for the chunk store and for the query range results, diff --git a/pkg/loki/config_wrapper_test.go b/pkg/loki/config_wrapper_test.go index c982a65f9b030..9376bd34e8361 100644 --- a/pkg/loki/config_wrapper_test.go +++ b/pkg/loki/config_wrapper_test.go @@ -86,6 +86,18 @@ common: assert.EqualValues(t, "/opt/loki/rules", config.Ruler.RulePath) assert.EqualValues(t, "/opt/loki/wal", config.Ingester.WAL.Dir) + assert.EqualValues(t, "/opt/loki/compactor", config.CompactorConfig.WorkingDirectory) + }) + + t.Run("accepts paths both with and without trailing slash", func(t *testing.T) { + configFileString := `--- +common: + path_prefix: /opt/loki/` + config, _ := testContext(configFileString, nil) + + assert.EqualValues(t, "/opt/loki/rules", config.Ruler.RulePath) + assert.EqualValues(t, "/opt/loki/wal", config.Ingester.WAL.Dir) + assert.EqualValues(t, "/opt/loki/compactor", config.CompactorConfig.WorkingDirectory) }) t.Run("does not rewrite custom (non-default) paths passed via config file", func(t *testing.T) { @@ -177,6 +189,7 @@ memberlist: // gcs: gcp.GCSConfig // s3: aws.S3Config // swift: openstack.SwiftConfig + // filesystem: local.FSConfig t.Run("does not automatically configure cloud object storage", func(t *testing.T) { config, defaults := testContext(emptyConfigString, nil) @@ -223,9 +236,7 @@ memberlist: access_key_id: abc123 secret_access_key: def789 insecure: true - signature_version: v4 http_config: - idle_conn_timeout: 5m response_header_timeout: 5m` config, defaults := testContext(s3Config, nil) @@ -249,10 +260,13 @@ memberlist: assert.Equal(t, "def789", actual.SecretAccessKey) assert.Equal(t, true, actual.Insecure) assert.Equal(t, false, actual.SSEEncryption) - assert.Equal(t, 5*time.Minute, actual.HTTPConfig.IdleConnTimeout) assert.Equal(t, 5*time.Minute, actual.HTTPConfig.ResponseHeaderTimeout) assert.Equal(t, false, actual.HTTPConfig.InsecureSkipVerify) - assert.Equal(t, "v4", actual.SignatureVersion) + + assert.Equal(t, cortex_aws.SignatureVersionV4, actual.SignatureVersion, + "signature version should equal default value") + assert.Equal(t, 90*time.Second, actual.HTTPConfig.IdleConnTimeout, + "idle connection timeout should equal default value") } //should remain empty @@ -274,8 +288,7 @@ memberlist: gcs: bucket_name: foobar chunk_buffer_size: 27 - request_timeout: 5m - enable_opencensus: true` + request_timeout: 5m` config, defaults := testContext(gcsConfig, nil) @@ -288,7 +301,7 @@ memberlist: assert.Equal(t, "foobar", actual.BucketName) assert.Equal(t, 27, actual.ChunkBufferSize) assert.Equal(t, 5*time.Minute, actual.RequestTimeout) - assert.Equal(t, true, actual.EnableOpenCensus) + assert.Equal(t, true, actual.EnableOpenCensus, "should get default value for unspecified oc config") } //should remain empty @@ -307,7 +320,6 @@ memberlist: azureConfig := `common: storage: azure: - environment: earth container_name: milkyway account_name: 3rd_planet account_key: water @@ -327,7 +339,9 @@ memberlist: config.Ruler.StoreConfig.Azure, config.StorageConfig.AzureStorageConfig.ToCortexAzureConfig(), } { - assert.Equal(t, "earth", actual.Environment) + assert.Equal(t, "AzureGlobal", actual.Environment, + "should equal default environment since unspecified in config") + assert.Equal(t, "milkyway", actual.ContainerName) assert.Equal(t, "3rd_planet", actual.AccountName) assert.Equal(t, "water", actual.AccountKey.Value) @@ -372,9 +386,7 @@ memberlist: project_domain_name: tower.com region_name: us-east1 container_name: tupperware - max_retries: 6 - connect_timeout: 5m - request_timeout: 5s` + connect_timeout: 5m` config, defaults := testContext(swiftConfig, nil) @@ -399,9 +411,12 @@ memberlist: assert.Equal(t, "tower.com", actual.ProjectDomainName) assert.Equal(t, "us-east1", actual.RegionName) assert.Equal(t, "tupperware", actual.ContainerName) - assert.Equal(t, 6, actual.MaxRetries) assert.Equal(t, 5*time.Minute, actual.ConnectTimeout) - assert.Equal(t, 5*time.Second, actual.RequestTimeout) + + assert.Equal(t, 3, actual.MaxRetries, + "unspecified max retries should get default value") + assert.Equal(t, 5*time.Second, actual.RequestTimeout, + "unspecified connection timeout should get default value") } //should remain empty @@ -470,9 +485,6 @@ ruler: assert.Equal(t, "abc123", config.Ruler.StoreConfig.S3.AccessKeyID) assert.Equal(t, "def789", config.Ruler.StoreConfig.S3.SecretAccessKey) - //should remain empty - assert.EqualValues(t, defaults.Ruler.StoreConfig.GCS, config.Ruler.StoreConfig.GCS) - //should be set by common config assert.EqualValues(t, "foobar", config.StorageConfig.GCSConfig.BucketName) assert.EqualValues(t, 27, config.StorageConfig.GCSConfig.ChunkBufferSize) @@ -503,9 +515,6 @@ storage_config: assert.Equal(t, "abc123", config.StorageConfig.AWSStorageConfig.S3Config.AccessKeyID) assert.Equal(t, "def789", config.StorageConfig.AWSStorageConfig.S3Config.SecretAccessKey) - //should remain empty - assert.EqualValues(t, defaults.StorageConfig.GCSConfig, config.StorageConfig.GCSConfig) - //should be set by common config assert.EqualValues(t, "foobar", config.Ruler.StoreConfig.GCS.BucketName) assert.EqualValues(t, 27, config.Ruler.StoreConfig.GCS.ChunkBufferSize) @@ -515,6 +524,47 @@ storage_config: assert.EqualValues(t, defaults.Ruler.StoreConfig.S3, config.Ruler.StoreConfig.S3) }) + t.Run("partial ruler config from file is honored for overriding things like bucket names", func(t *testing.T) { + specificRulerConfig := `common: + storage: + gcs: + bucket_name: foobar + chunk_buffer_size: 27 + request_timeout: 5m +ruler: + storage: + gcs: + bucket_name: rules` + + config, _ := testContext(specificRulerConfig, nil) + + assert.EqualValues(t, "rules", config.Ruler.StoreConfig.GCS.BucketName) + + //from common config + assert.EqualValues(t, 27, config.Ruler.StoreConfig.GCS.ChunkBufferSize) + assert.EqualValues(t, 5*time.Minute, config.Ruler.StoreConfig.GCS.RequestTimeout) + }) + + t.Run("partial chunk store config from file is honored for overriding things like bucket names", func(t *testing.T) { + specificRulerConfig := `common: + storage: + gcs: + bucket_name: foobar + chunk_buffer_size: 27 + request_timeout: 5m +storage_config: + gcs: + bucket_name: chunks` + + config, _ := testContext(specificRulerConfig, nil) + + assert.EqualValues(t, "chunks", config.StorageConfig.GCSConfig.BucketName) + + //from common config + assert.EqualValues(t, 27, config.StorageConfig.GCSConfig.ChunkBufferSize) + assert.EqualValues(t, 5*time.Minute, config.StorageConfig.GCSConfig.RequestTimeout) + }) + t.Run("when common object store config is provided, compactor shared store is defaulted to use it", func(t *testing.T) { for _, tt := range []struct { configString string @@ -654,6 +704,43 @@ schema_config: assert.Equal(t, storage.StorageTypeS3, config.StorageConfig.BoltDBShipperConfig.SharedStoreType) assert.Equal(t, storage.StorageTypeS3, config.CompactorConfig.SharedStoreType) }) + + t.Run("if path prefix provided in common config, default active_index_directory and cache_location", func(t *testing.T) {}) + const boltdbSchemaConfig = `--- +common: + path_prefix: /opt/loki +schema_config: + configs: + - from: 2021-08-01 + store: boltdb-shipper + object_store: gcs + schema: v11 + index: + prefix: index_ + period: 24h` + config, _ := testContext(boltdbSchemaConfig, []string{"-boltdb.shipper.compactor.shared-store", "s3", "-boltdb.shipper.shared-store", "s3"}) + + assert.Equal(t, "/opt/loki/boltdb-shipper-active", config.StorageConfig.BoltDBShipperConfig.ActiveIndexDirectory) + assert.Equal(t, "/opt/loki/boltdb-shipper-cache", config.StorageConfig.BoltDBShipperConfig.CacheLocation) + }) + + t.Run("boltdb shipper directories correctly handle trailing slash in path prefix", func(t *testing.T) { + const boltdbSchemaConfig = `--- +common: + path_prefix: /opt/loki/ +schema_config: + configs: + - from: 2021-08-01 + store: boltdb-shipper + object_store: gcs + schema: v11 + index: + prefix: index_ + period: 24h` + config, _ := testContext(boltdbSchemaConfig, []string{"-boltdb.shipper.compactor.shared-store", "s3", "-boltdb.shipper.shared-store", "s3"}) + + assert.Equal(t, "/opt/loki/boltdb-shipper-active", config.StorageConfig.BoltDBShipperConfig.ActiveIndexDirectory) + assert.Equal(t, "/opt/loki/boltdb-shipper-cache", config.StorageConfig.BoltDBShipperConfig.CacheLocation) }) } diff --git a/pkg/loki/loki.go b/pkg/loki/loki.go index 2cbdaa261094f..00e542dc49174 100644 --- a/pkg/loki/loki.go +++ b/pkg/loki/loki.go @@ -89,6 +89,7 @@ func (c *Config) RegisterFlags(f *flag.FlagSet) { f.BoolVar(&c.AuthEnabled, "auth.enabled", true, "Set to false to disable auth.") c.registerServerFlagsWithChangedDefaultValues(f) + c.Common.RegisterFlags(f) c.Distributor.RegisterFlags(f) c.Querier.RegisterFlags(f) c.IngesterClient.RegisterFlags(f) @@ -465,6 +466,18 @@ func (t *Loki) setupModuleManager() error { deps[All] = append(deps[All], Compactor) } + // If the query scheduler and querier are running together, make sure the scheduler goes + // first to initialize the ring that will also be used by the querier + if (t.Cfg.isModuleEnabled(Querier) && t.Cfg.isModuleEnabled(QueryScheduler)) || t.Cfg.isModuleEnabled(Read) || t.Cfg.isModuleEnabled(All) { + deps[Querier] = append(deps[Querier], QueryScheduler) + } + + // If the query scheduler and query frontend are running together, make sure the scheduler goes + // first to initialize the ring that will also be used by the query frontend + if (t.Cfg.isModuleEnabled(QueryFrontend) && t.Cfg.isModuleEnabled(QueryScheduler)) || t.Cfg.isModuleEnabled(Read) || t.Cfg.isModuleEnabled(All) { + deps[QueryFrontend] = append(deps[QueryFrontend], QueryScheduler) + } + for mod, targets := range deps { if err := mm.AddDependency(mod, targets...); err != nil { return err diff --git a/pkg/ruler/config.go b/pkg/ruler/config.go index ea60ecb06b576..52fa0efec5a99 100644 --- a/pkg/ruler/config.go +++ b/pkg/ruler/config.go @@ -31,7 +31,7 @@ func (c *Config) RegisterFlags(f *flag.FlagSet) { c.WALCleaner.RegisterFlags(f) // TODO(owen-d, 3.0.0): remove deprecated experimental prefix in Cortex if they'll accept it. - f.BoolVar(&c.Config.EnableAPI, "ruler.enable-api", false, "Enable the ruler api") + f.BoolVar(&c.Config.EnableAPI, "ruler.enable-api", true, "Enable the ruler api") } // Validate overrides the embedded cortex variant which expects a cortex limits struct. Instead copy the relevant bits over. diff --git a/pkg/storage/chunk/aws/s3_storage_client.go b/pkg/storage/chunk/aws/s3_storage_client.go index 5f153c8e6fba3..736ec44815587 100644 --- a/pkg/storage/chunk/aws/s3_storage_client.go +++ b/pkg/storage/chunk/aws/s3_storage_client.go @@ -118,9 +118,10 @@ func (cfg *S3Config) RegisterFlagsWithPrefix(prefix string, f *flag.FlagSet) { f.BoolVar(&cfg.HTTPConfig.InsecureSkipVerify, prefix+"s3.http.insecure-skip-verify", false, "Set to true to skip verifying the certificate chain and hostname.") f.StringVar(&cfg.HTTPConfig.CAFile, prefix+"s3.http.ca-file", "", "Path to the trusted CA file that signed the SSL certificate of the S3 endpoint.") f.StringVar(&cfg.SignatureVersion, prefix+"s3.signature-version", SignatureVersionV4, fmt.Sprintf("The signature version to use for authenticating against S3. Supported values are: %s.", strings.Join(supportedSignatureVersions, ", "))) - f.DurationVar(&cfg.BackoffConfig.MinBackoff, "s3.min-backoff", 100*time.Millisecond, "Minimum backoff time when s3 get Object") - f.DurationVar(&cfg.BackoffConfig.MaxBackoff, "s3.max-backoff", 3*time.Second, "Maximum backoff time when s3 get Object") - f.IntVar(&cfg.BackoffConfig.MaxRetries, "s3.max-retries", 5, "Maximum number of times to retry when s3 get Object") + + f.DurationVar(&cfg.BackoffConfig.MinBackoff, prefix+"s3.min-backoff", 100*time.Millisecond, "Minimum backoff time when s3 get Object") + f.DurationVar(&cfg.BackoffConfig.MaxBackoff, prefix+"s3.max-backoff", 3*time.Second, "Maximum backoff time when s3 get Object") + f.IntVar(&cfg.BackoffConfig.MaxRetries, prefix+"s3.max-retries", 5, "Maximum number of times to retry when s3 get Object") } // Validate config and returns error on failure