Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: add Baidu Cloud BOS as storage backends for Loki #4788 #5848

Merged
merged 15 commits into from
May 5, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
## Main
* [5848](https://github.com/grafana/loki/pull/5848) **arcosx** add Baidu AI Cloud as storage backends for Loki
* [5799](https://github.com/grafana/loki/pull/5799) **cyriltovena** Fix deduping issues when multiple entries with the same timestamp exist.
* [5799](https://github.com/grafana/loki/pull/5799) **cyriltovena** Fixes deduping issues when multiple entries exists with the same timestamp.
* [5780](https://github.com/grafana/loki/pull/5780) **simonswine**: Update alpine image to 3.15.4.
Expand Down
27 changes: 26 additions & 1 deletion docs/sources/configuration/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,9 @@ storage:
# Configures backend rule storage for a local file system directory.
[local: <local_storage_config>]

# Configures backend rule storage for Baidu BCE BOS.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should add an option to the comment above on type as well to include bos

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

# Method to use for backend rule storage (azure, gcs, s3, swift, local).
# CLI flag: -ruler.storage.type
[type: <string> ]

This comment. I agree.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I was careless, this has been fixed.

arcosx marked this conversation as resolved.
Show resolved Hide resolved
[ bos: <bos_storage_config> ]

# The `hedging` block configures how to hedge storage requests.
[hedging: <hedging>]

Expand Down Expand Up @@ -720,6 +723,25 @@ ring:
[num_tokens: <int> | default = 128]
```

## bos_storage_config

The `bos_storage_config` configures Baidu BCE BOS a general storage for different data generated by Loki.

```yaml
# Name of Bos bucket.
cstyan marked this conversation as resolved.
Show resolved Hide resolved
# CLI flag: <prefix>.baidubce.bucket-name
[ bucket_name: <string> | default = "" ]
# Bos endpoint to connect to.
# CLI flag: <prefix>.baidubce.endpoint
[ endpoint: <string> | default = "bj.bcebos.com" ]
# Baidu BCE Access Key ID
# CLI flag: <prefix>.baidubce.access-key-id
[ access_key_id: <string> | default = "" ]
# Baidu BCE Secret Access Key
# CLI flag: <prefix>.baidubce.secret-access-key
arcosx marked this conversation as resolved.
Show resolved Hide resolved
[ secret_access_key: <string> | default = "" ]
```

## azure_storage_config

The `azure_storage_config` configures Azure as a general storage for different data generated by Loki.
Expand Down Expand Up @@ -1999,7 +2021,7 @@ compacts index shards to more performant forms.
[working_directory: <string>]

# The shared store used for storing boltdb files.
# Supported types: gcs, s3, azure, swift, filesystem.
# Supported types: gcs, s3, azure, swift, filesystem, bos.
# CLI flag: -boltdb.shipper.compactor.shared-store
[shared_store: <string>]

Expand Down Expand Up @@ -2555,6 +2577,9 @@ If any specific configuration for an object storage client have been provided el

# The `hedging_config` configures how to hedge requests for the storage.
[hedging: <hedging_config>]

# Configures Baidu BCE BOS as the common storage.
[ bos: <bos_storage_config> ]
cstyan marked this conversation as resolved.
Show resolved Hide resolved
```

### filesystem
Expand Down
31 changes: 31 additions & 0 deletions docs/sources/configuration/examples.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,37 @@ storage_config:
```


## bos-config.yaml

```yaml
schema_config:
configs:
- from: 2020-05-15
store: boltdb-shipper
object_store: bos
schema: v11
index:
prefix: index_
period: 24h

storage_config:
boltdb_shipper:
active_index_directory: /loki/index
cache_location: /loki/index_cache
shared_store: bos

bos:
bucket_name: bucket_name_1
endpoint: bj.bcebos.com
access_key_id: access_key_id
secret_access_key: secret_access_key

compactor:
working_directory: /tmp/loki/compactor
shared_store: bos
```


## cassandra-index.yaml

```yaml
Expand Down
25 changes: 25 additions & 0 deletions docs/sources/configuration/examples/bos-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
schema_config:
configs:
- from: 2020-05-15
store: boltdb-shipper
object_store: bos
schema: v11
index:
prefix: index_
period: 24h

storage_config:
boltdb_shipper:
active_index_directory: /loki/index
cache_location: /loki/index_cache
shared_store: bos

bos:
bucket_name: bucket_name_1
endpoint: bj.bcebos.com
access_key_id: access_key_id
secret_access_key: secret_access_key

compactor:
working_directory: /tmp/loki/compactor
shared_store: bos
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ require (
k8s.io/klog v1.0.0
)

require github.com/baidubce/bce-sdk-go v0.9.81
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not an expert around why we have this file organized the way we do, but I imagine we want this in one of the other require sections rather than sitting on it's own?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes! I move it.


require (
cloud.google.com/go v0.100.2 // indirect
cloud.google.com/go/compute v1.3.0 // indirect
Expand Down
15 changes: 9 additions & 6 deletions pkg/loki/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/grafana/loki/pkg/storage/chunk/client/aws"
"github.com/grafana/loki/pkg/storage/chunk/client/azure"
"github.com/grafana/loki/pkg/storage/chunk/client/baidubce"
"github.com/grafana/loki/pkg/storage/chunk/client/gcp"
"github.com/grafana/loki/pkg/storage/chunk/client/hedging"
"github.com/grafana/loki/pkg/storage/chunk/client/openstack"
Expand Down Expand Up @@ -54,19 +55,21 @@ func (c *Config) RegisterFlags(_ *flag.FlagSet) {
}

type Storage struct {
S3 aws.S3Config `yaml:"s3"`
GCS gcp.GCSConfig `yaml:"gcs"`
Azure azure.BlobStorageConfig `yaml:"azure"`
Swift openstack.SwiftConfig `yaml:"swift"`
FSConfig FilesystemConfig `yaml:"filesystem"`
Hedging hedging.Config `yaml:"hedging"`
S3 aws.S3Config `yaml:"s3"`
GCS gcp.GCSConfig `yaml:"gcs"`
Azure azure.BlobStorageConfig `yaml:"azure"`
Bos baidubce.BosStorageConfig `yaml:"bos"`
Swift openstack.SwiftConfig `yaml:"swift"`
FSConfig FilesystemConfig `yaml:"filesystem"`
Hedging hedging.Config `yaml:"hedging"`
}

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.Bos.RegisterFlagsWithPrefix(prefix+".bos", f)
s.FSConfig.RegisterFlagsWithPrefix(prefix+".filesystem", f)
s.Hedging.RegisterFlagsWithPrefix(prefix, f)
}
Expand Down
10 changes: 10 additions & 0 deletions pkg/loki/config_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,16 @@ func applyStorageConfig(cfg, defaults *ConfigWrapper) error {
}
}

if !reflect.DeepEqual(cfg.Common.Storage.Bos, defaults.StorageConfig.BosStorageConfig) {
configsFound++
applyConfig = func(r *ConfigWrapper) {
r.Ruler.StoreConfig.Type = "bos"
r.Ruler.StoreConfig.BOS = r.Common.Storage.Bos
r.StorageConfig.BosStorageConfig = r.Common.Storage.Bos
r.CompactorConfig.SharedStoreType = config.StorageTypeBos
}
}

if !reflect.DeepEqual(cfg.Common.Storage.Swift, defaults.StorageConfig.Swift) {
configsFound++

Expand Down
56 changes: 52 additions & 4 deletions pkg/loki/config_wrapper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/grafana/loki/pkg/storage/bucket/swift"
"github.com/grafana/loki/pkg/storage/chunk/client/aws"
"github.com/grafana/loki/pkg/storage/chunk/client/azure"
"github.com/grafana/loki/pkg/storage/chunk/client/baidubce"
"github.com/grafana/loki/pkg/storage/chunk/client/gcp"
"github.com/grafana/loki/pkg/storage/config"
"github.com/grafana/loki/pkg/util"
Expand Down Expand Up @@ -200,6 +201,7 @@ memberlist:
// s3: aws.S3Config
// swift: openstack.SwiftConfig
// filesystem: Filesystem
// bos: baidubce.BosStorageConfig
cstyan marked this conversation as resolved.
Show resolved Hide resolved

t.Run("does not automatically configure cloud object storage", func(t *testing.T) {
config, defaults := testContext(emptyConfigString, nil)
Expand All @@ -210,12 +212,13 @@ memberlist:
assert.EqualValues(t, defaults.Ruler.StoreConfig.S3, config.Ruler.StoreConfig.S3)
assert.EqualValues(t, defaults.Ruler.StoreConfig.Swift, config.Ruler.StoreConfig.Swift)
assert.EqualValues(t, defaults.Ruler.StoreConfig.Local, config.Ruler.StoreConfig.Local)

assert.EqualValues(t, defaults.Ruler.StoreConfig.BOS, config.Ruler.StoreConfig.BOS)
assert.EqualValues(t, defaults.StorageConfig.AWSStorageConfig, config.StorageConfig.AWSStorageConfig)
assert.EqualValues(t, defaults.StorageConfig.AzureStorageConfig, config.StorageConfig.AzureStorageConfig)
assert.EqualValues(t, defaults.StorageConfig.GCSConfig, config.StorageConfig.GCSConfig)
assert.EqualValues(t, defaults.StorageConfig.Swift, config.StorageConfig.Swift)
assert.EqualValues(t, defaults.StorageConfig.FSConfig, config.StorageConfig.FSConfig)
assert.EqualValues(t, defaults.StorageConfig.BosStorageConfig, config.StorageConfig.BosStorageConfig)
})

t.Run("when multiple configs are provided, an error is returned", func(t *testing.T) {
Expand Down Expand Up @@ -284,12 +287,13 @@ memberlist:
assert.EqualValues(t, defaults.Ruler.StoreConfig.GCS, config.Ruler.StoreConfig.GCS)
assert.EqualValues(t, defaults.Ruler.StoreConfig.Swift, config.Ruler.StoreConfig.Swift)
assert.EqualValues(t, defaults.Ruler.StoreConfig.Local, config.Ruler.StoreConfig.Local)

assert.EqualValues(t, defaults.Ruler.StoreConfig.BOS, config.Ruler.StoreConfig.BOS)
// should remain empty
assert.EqualValues(t, defaults.StorageConfig.AzureStorageConfig, config.StorageConfig.AzureStorageConfig)
assert.EqualValues(t, defaults.StorageConfig.GCSConfig, config.StorageConfig.GCSConfig)
assert.EqualValues(t, defaults.StorageConfig.Swift, config.StorageConfig.Swift)
assert.EqualValues(t, defaults.StorageConfig.FSConfig, config.StorageConfig.FSConfig)
assert.EqualValues(t, defaults.StorageConfig.BosStorageConfig, config.StorageConfig.BosStorageConfig)
})

t.Run("when common gcs storage config is provided, ruler and storage config are defaulted to use it", func(t *testing.T) {
Expand Down Expand Up @@ -319,11 +323,13 @@ memberlist:
assert.EqualValues(t, defaults.Ruler.StoreConfig.S3, config.Ruler.StoreConfig.S3)
assert.EqualValues(t, defaults.Ruler.StoreConfig.Swift, config.Ruler.StoreConfig.Swift)
assert.EqualValues(t, defaults.Ruler.StoreConfig.Local, config.Ruler.StoreConfig.Local)
assert.EqualValues(t, defaults.Ruler.StoreConfig.BOS, config.Ruler.StoreConfig.BOS)
// should remain empty
assert.EqualValues(t, defaults.StorageConfig.AzureStorageConfig, config.StorageConfig.AzureStorageConfig)
assert.EqualValues(t, defaults.StorageConfig.AWSStorageConfig.S3Config, config.StorageConfig.AWSStorageConfig.S3Config)
assert.EqualValues(t, defaults.StorageConfig.Swift, config.StorageConfig.Swift)
assert.EqualValues(t, defaults.StorageConfig.FSConfig, config.StorageConfig.FSConfig)
assert.EqualValues(t, defaults.StorageConfig.BosStorageConfig, config.StorageConfig.BosStorageConfig)
})

t.Run("when common azure storage config is provided, ruler and storage config are defaulted to use it", func(t *testing.T) {
Expand Down Expand Up @@ -369,8 +375,48 @@ memberlist:
assert.EqualValues(t, defaults.Ruler.StoreConfig.S3, config.Ruler.StoreConfig.S3)
assert.EqualValues(t, defaults.Ruler.StoreConfig.Swift, config.Ruler.StoreConfig.Swift)
assert.EqualValues(t, defaults.Ruler.StoreConfig.Local, config.Ruler.StoreConfig.Local)
assert.EqualValues(t, defaults.Ruler.StoreConfig.BOS, config.Ruler.StoreConfig.BOS)

// should remain empty
assert.EqualValues(t, defaults.StorageConfig.GCSConfig, config.StorageConfig.GCSConfig)
assert.EqualValues(t, defaults.StorageConfig.AWSStorageConfig.S3Config, config.StorageConfig.AWSStorageConfig.S3Config)
assert.EqualValues(t, defaults.StorageConfig.Swift, config.StorageConfig.Swift)
assert.EqualValues(t, defaults.StorageConfig.FSConfig, config.StorageConfig.FSConfig)
assert.EqualValues(t, defaults.StorageConfig.BosStorageConfig, config.StorageConfig.BosStorageConfig)
})

t.Run("when common bos storage config is provided, ruler and storage config are defaulted to use it", func(t *testing.T) {
bosConfig := `common:
storage:
bos:
bucket_name: arcosx
endpoint: bj.bcebos.com
access_key_id: baidu
secret_access_key: bce`

config, defaults := testContext(bosConfig, nil)

assert.Equal(t, "bos", config.Ruler.StoreConfig.Type)

for _, actual := range []baidubce.BosStorageConfig{
config.Ruler.StoreConfig.BOS,
config.StorageConfig.BosStorageConfig,
} {
assert.Equal(t, "arcosx", actual.BucketName)
assert.Equal(t, "bj.bcebos.com", actual.Endpoint)
assert.Equal(t, "baidu", actual.AccessKeyID)
assert.Equal(t, "bce", actual.SecretAccessKey)
}

// should remain empty
assert.EqualValues(t, defaults.Ruler.StoreConfig.Azure, config.Ruler.StoreConfig.Azure)
assert.EqualValues(t, defaults.Ruler.StoreConfig.GCS, config.Ruler.StoreConfig.GCS)
assert.EqualValues(t, defaults.Ruler.StoreConfig.S3, config.Ruler.StoreConfig.S3)
assert.EqualValues(t, defaults.Ruler.StoreConfig.Swift, config.Ruler.StoreConfig.Swift)
assert.EqualValues(t, defaults.Ruler.StoreConfig.Local, config.Ruler.StoreConfig.Local)

// should remain empty
assert.EqualValues(t, defaults.StorageConfig.AzureStorageConfig, config.StorageConfig.AzureStorageConfig)
assert.EqualValues(t, defaults.StorageConfig.GCSConfig, config.StorageConfig.GCSConfig)
assert.EqualValues(t, defaults.StorageConfig.AWSStorageConfig.S3Config, config.StorageConfig.AWSStorageConfig.S3Config)
assert.EqualValues(t, defaults.StorageConfig.Swift, config.StorageConfig.Swift)
Expand Down Expand Up @@ -434,12 +480,13 @@ memberlist:
assert.EqualValues(t, defaults.Ruler.StoreConfig.S3, config.Ruler.StoreConfig.S3)
assert.EqualValues(t, defaults.Ruler.StoreConfig.Azure, config.Ruler.StoreConfig.Azure)
assert.EqualValues(t, defaults.Ruler.StoreConfig.Local, config.Ruler.StoreConfig.Local)

assert.EqualValues(t, defaults.Ruler.StoreConfig.BOS, config.Ruler.StoreConfig.BOS)
// should remain empty
assert.EqualValues(t, defaults.StorageConfig.GCSConfig, config.StorageConfig.GCSConfig)
assert.EqualValues(t, defaults.StorageConfig.AWSStorageConfig.S3Config, config.StorageConfig.AWSStorageConfig.S3Config)
assert.EqualValues(t, defaults.StorageConfig.AzureStorageConfig, config.StorageConfig.AzureStorageConfig)
assert.EqualValues(t, defaults.StorageConfig.FSConfig, config.StorageConfig.FSConfig)
assert.EqualValues(t, defaults.StorageConfig.BosStorageConfig, config.StorageConfig.BosStorageConfig)
})

t.Run("when common filesystem/local config is provided, ruler and storage config are defaulted to use it", func(t *testing.T) {
Expand All @@ -461,12 +508,13 @@ memberlist:
assert.EqualValues(t, defaults.Ruler.StoreConfig.S3, config.Ruler.StoreConfig.S3)
assert.EqualValues(t, defaults.Ruler.StoreConfig.Azure, config.Ruler.StoreConfig.Azure)
assert.EqualValues(t, defaults.Ruler.StoreConfig.Swift, config.Ruler.StoreConfig.Swift)

assert.EqualValues(t, defaults.Ruler.StoreConfig.BOS, config.Ruler.StoreConfig.BOS)
// should remain empty
assert.EqualValues(t, defaults.StorageConfig.GCSConfig, config.StorageConfig.GCSConfig)
assert.EqualValues(t, defaults.StorageConfig.AWSStorageConfig.S3Config, config.StorageConfig.AWSStorageConfig.S3Config)
assert.EqualValues(t, defaults.StorageConfig.AzureStorageConfig, config.StorageConfig.AzureStorageConfig)
assert.EqualValues(t, defaults.StorageConfig.Swift, config.StorageConfig.Swift)
assert.EqualValues(t, defaults.StorageConfig.BosStorageConfig, config.StorageConfig.BosStorageConfig)
})

t.Run("explicit ruler storage object storage configuration provided via config file is preserved", func(t *testing.T) {
Expand Down
19 changes: 13 additions & 6 deletions pkg/ruler/base/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"github.com/grafana/loki/pkg/storage/chunk/client"
"github.com/grafana/loki/pkg/storage/chunk/client/aws"
"github.com/grafana/loki/pkg/storage/chunk/client/azure"
"github.com/grafana/loki/pkg/storage/chunk/client/baidubce"
"github.com/grafana/loki/pkg/storage/chunk/client/gcp"
"github.com/grafana/loki/pkg/storage/chunk/client/hedging"
"github.com/grafana/loki/pkg/storage/chunk/client/openstack"
Expand All @@ -33,11 +34,12 @@ type RuleStoreConfig struct {
ConfigDB configClient.Config `yaml:"configdb"`

// Object Storage Configs
Azure azure.BlobStorageConfig `yaml:"azure"`
GCS gcp.GCSConfig `yaml:"gcs"`
S3 aws.S3Config `yaml:"s3"`
Swift openstack.SwiftConfig `yaml:"swift"`
Local local.Config `yaml:"local"`
Azure azure.BlobStorageConfig `yaml:"azure"`
GCS gcp.GCSConfig `yaml:"gcs"`
S3 aws.S3Config `yaml:"s3"`
BOS baidubce.BosStorageConfig `yaml:"bos"`
Swift openstack.SwiftConfig `yaml:"swift"`
Local local.Config `yaml:"local"`

mock rulestore.RuleStore `yaml:"-"`
}
Expand All @@ -50,7 +52,7 @@ func (cfg *RuleStoreConfig) RegisterFlags(f *flag.FlagSet) {
cfg.S3.RegisterFlagsWithPrefix("ruler.storage.", f)
cfg.Swift.RegisterFlagsWithPrefix("ruler.storage.", f)
cfg.Local.RegisterFlagsWithPrefix("ruler.storage.", f)

cfg.BOS.RegisterFlagsWithPrefix("ruler.storage.", f)
f.StringVar(&cfg.Type, "ruler.storage.type", "configdb", "Method to use for backend rule storage (configdb, azure, gcs, s3, swift, local)")
}

Expand All @@ -65,6 +67,9 @@ func (cfg *RuleStoreConfig) Validate() error {
if err := cfg.S3.Validate(); err != nil {
return errors.Wrap(err, "invalid S3 Storage config")
}
if err := cfg.BOS.Validate(); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this function always returns nil, why bother calling it here and implenting it as a no-op. We could follow a similar patter with the GCSConfig where we don't call Validate here and therefore don't need to implement it as a no-op. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I delete the function Validate() .You are right.It no need used now.

return errors.Wrap(err, "invalid BOS Storage config")
}
return nil
}

Expand Down Expand Up @@ -101,6 +106,8 @@ func NewLegacyRuleStore(cfg RuleStoreConfig, hedgeCfg hedging.Config, clientMetr
client, err = gcp.NewGCSObjectClient(context.Background(), cfg.GCS, hedgeCfg)
case "s3":
client, err = aws.NewS3ObjectClient(cfg.S3, hedgeCfg)
case "bos":
client, err = baidubce.NewBosObjectStorage(&cfg.BOS)
case "swift":
client, err = openstack.NewSwiftObjectClient(cfg.Swift, hedgeCfg)
case "local":
Expand Down
Loading