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

[jaeger-v2] Add Validation And Comments to Badger Storage Config #5927

Merged
merged 10 commits into from
Sep 5, 2024
10 changes: 6 additions & 4 deletions cmd/jaeger/config-badger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ extensions:
backends:
some_store:
badger:
directory_key: "/tmp/jaeger/"
directory_value: "/tmp/jaeger/"
directories:
keys: "/tmp/jaeger/"
values: "/tmp/jaeger/"
yurishkuro marked this conversation as resolved.
Show resolved Hide resolved
ephemeral: false
another_store:
badger:
directory_key: "/tmp/jaeger_archive/"
directory_value: "/tmp/jaeger_archive/"
directories:
keys: "/tmp/jaeger_archive/"
values: "/tmp/jaeger_archive/"
ephemeral: false

receivers:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ backends:
`)
cfg := createDefaultConfig().(*Config)
require.NoError(t, conf.Unmarshal(cfg))
assert.NotEmpty(t, cfg.Backends["some_storage"].Badger.SpanStoreTTL)
assert.NotEmpty(t, cfg.Backends["some_storage"].Badger.TTL.SpanStore)
}

func TestConfigDefaultGRPC(t *testing.T) {
Expand Down
16 changes: 8 additions & 8 deletions plugin/storage/badger/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,16 +126,16 @@
opts.Dir = f.tmpDir
opts.ValueDir = f.tmpDir

f.Options.Primary.KeyDirectory = f.tmpDir
f.Options.Primary.ValueDirectory = f.tmpDir
f.Options.Primary.Directories.Keys = f.tmpDir
f.Options.Primary.Directories.Keys = f.tmpDir

Check warning on line 130 in plugin/storage/badger/factory.go

View check run for this annotation

Codecov / codecov/patch

plugin/storage/badger/factory.go#L129-L130

Added lines #L129 - L130 were not covered by tests
} else {
// Errors are ignored as they're caught in the Open call
initializeDir(f.Options.Primary.KeyDirectory)
initializeDir(f.Options.Primary.ValueDirectory)
initializeDir(f.Options.Primary.Directories.Keys)
initializeDir(f.Options.Primary.Directories.Values)

opts.SyncWrites = f.Options.Primary.SyncWrites
opts.Dir = f.Options.Primary.KeyDirectory
opts.ValueDir = f.Options.Primary.ValueDirectory
opts.Dir = f.Options.Primary.Directories.Keys
opts.ValueDir = f.Options.Primary.Directories.Values

// These options make no sense with ephemeral data
opts.ReadOnly = f.Options.Primary.ReadOnly
Expand All @@ -147,7 +147,7 @@
}
f.store = store

f.cache = badgerStore.NewCacheStore(f.store, f.Options.Primary.SpanStoreTTL, true)
f.cache = badgerStore.NewCacheStore(f.store, f.Options.Primary.TTL.SpanStore, true)

f.metrics.ValueLogSpaceAvailable = metricsFactory.Gauge(metrics.Options{Name: valueLogSpaceAvailableName})
f.metrics.KeyLogSpaceAvailable = metricsFactory.Gauge(metrics.Options{Name: keyLogSpaceAvailableName})
Expand Down Expand Up @@ -178,7 +178,7 @@

// CreateSpanWriter implements storage.Factory
func (f *Factory) CreateSpanWriter() (spanstore.Writer, error) {
return badgerStore.NewSpanWriter(f.store, f.cache, f.Options.Primary.SpanStoreTTL), nil
return badgerStore.NewSpanWriter(f.store, f.cache, f.Options.Primary.TTL.SpanStore), nil
}

// CreateDependencyReader implements storage.Factory
Expand Down
6 changes: 4 additions & 2 deletions plugin/storage/badger/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,8 +203,10 @@ func TestBadgerStorageFactoryWithConfig(t *testing.T) {
tmp := os.TempDir()
defer os.Remove(tmp)
cfg = NamespaceConfig{
ValueDirectory: tmp,
KeyDirectory: tmp,
Directories: Directories{
Keys: tmp,
Values: tmp,
},
Ephemeral: false,
MaintenanceInterval: 5,
MetricsUpdateInterval: 10,
Expand Down
77 changes: 56 additions & 21 deletions plugin/storage/badger/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"path/filepath"
"time"

"github.com/asaskevich/govalidator"
"github.com/spf13/viper"
"go.uber.org/zap"
)
Expand All @@ -19,18 +20,43 @@
// This storage plugin does not support additional namespaces
}

// NamespaceConfig is badger's internal configuration data
// NamespaceConfig is badger's internal configuration data.
yurishkuro marked this conversation as resolved.
Show resolved Hide resolved
type NamespaceConfig struct {
namespace string
SpanStoreTTL time.Duration `mapstructure:"span_store_ttl"`
ValueDirectory string `mapstructure:"directory_value"`
KeyDirectory string `mapstructure:"directory_key"`
// Setting this to true will ignore ValueDirectory and KeyDirectory
Ephemeral bool `mapstructure:"ephemeral"`
SyncWrites bool `mapstructure:"consistency"`
MaintenanceInterval time.Duration `mapstructure:"maintenance_interval"`
namespace string
Copy link
Contributor Author

Choose a reason for hiding this comment

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

do we want to make this field configurable?

Copy link
Member

Choose a reason for hiding this comment

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

it's not needed, see #5929

// TTL holds time-to-live configuration for the badger store.
TTL TTL `mapstructure:"ttl"`
// Directories contains the configuration for where items are stored. Ephemeral must be
// set to false for this configuration to take effect.
Directories Directories `mapstructure:"directories"`
// Ephemeral, if set to true, will store data in a temporary file system.
// If set to true, the configuration in Directories is ignored.
Ephemeral bool `mapstructure:"ephemeral"`
// SyncWrites, if set to true, will immediately sync all writes to disk. Note that
// setting this field to true will affect write performance.
SyncWrites bool `mapstructure:"consistency"`
// MaintenanceInterval is the regular interval after which a maintenance job is
// run on the values in the store.
MaintenanceInterval time.Duration `mapstructure:"maintenance_interval"`
// MetricsUpdateInterval is the regular interval after which metrics are collected
// by Jaeger.
MetricsUpdateInterval time.Duration `mapstructure:"metrics_update_interval"`
ReadOnly bool `mapstructure:"read_only"`
// ReadOnly opens the data store in read-only mode. Multiple instances can open the same
// store in read-only mode. Values still in the write-ahead-log must be replayed before opening.
ReadOnly bool `mapstructure:"read_only"`
}

type TTL struct {
// SpanStore holds the amount of time that the span store data is stored.
// Once this duration has passed for a given key, span store data will
// no longer be accessible.
SpanStore time.Duration `mapstructure:"span_store"`
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
SpanStore time.Duration `mapstructure:"span_store"`
Spans time.Duration `mapstructure:"spans"`

}

type Directories struct {
// Keys contains the directory in which the keys are stored.
Keys string `mapstructure:"keys"`
// Values contains the directory in which the values are stored.
Values string `mapstructure:"values"`
}

const (
Expand All @@ -56,11 +82,15 @@
func DefaultNamespaceConfig() NamespaceConfig {
defaultBadgerDataDir := getCurrentExecutableDir()
return NamespaceConfig{
SpanStoreTTL: defaultTTL,
SyncWrites: false, // Performance over durability
Ephemeral: true, // Default is ephemeral storage
ValueDirectory: defaultBadgerDataDir + defaultValueDir,
KeyDirectory: defaultBadgerDataDir + defaultKeysDir,
TTL: TTL{
SpanStore: defaultTTL,
},
SyncWrites: false, // Performance over durability
Ephemeral: true, // Default is ephemeral storage
Directories: Directories{
Keys: defaultBadgerDataDir + defaultKeysDir,
Values: defaultBadgerDataDir + defaultValueDir,
},
MaintenanceInterval: defaultMaintenanceInterval,
MetricsUpdateInterval: defaultMetricsUpdateInterval,
}
Expand Down Expand Up @@ -97,17 +127,17 @@
)
flagSet.Duration(
nsConfig.namespace+suffixSpanstoreTTL,
nsConfig.SpanStoreTTL,
nsConfig.TTL.SpanStore,

Check warning on line 130 in plugin/storage/badger/options.go

View check run for this annotation

Codecov / codecov/patch

plugin/storage/badger/options.go#L130

Added line #L130 was not covered by tests
"How long to store the data. Format is time.Duration (https://golang.org/pkg/time/#Duration)",
)
flagSet.String(
nsConfig.namespace+suffixKeyDirectory,
nsConfig.KeyDirectory,
nsConfig.Directories.Keys,

Check warning on line 135 in plugin/storage/badger/options.go

View check run for this annotation

Codecov / codecov/patch

plugin/storage/badger/options.go#L135

Added line #L135 was not covered by tests
"Path to store the keys (indexes), this directory should reside in SSD disk. Set ephemeral to false if you want to define this setting.",
)
flagSet.String(
nsConfig.namespace+suffixValueDirectory,
nsConfig.ValueDirectory,
nsConfig.Directories.Values,

Check warning on line 140 in plugin/storage/badger/options.go

View check run for this annotation

Codecov / codecov/patch

plugin/storage/badger/options.go#L140

Added line #L140 was not covered by tests
"Path to store the values (spans). Set ephemeral to false if you want to define this setting.",
)
flagSet.Bool(
Expand Down Expand Up @@ -139,10 +169,10 @@

func initFromViper(cfg *NamespaceConfig, v *viper.Viper, _ *zap.Logger) {
cfg.Ephemeral = v.GetBool(cfg.namespace + suffixEphemeral)
cfg.KeyDirectory = v.GetString(cfg.namespace + suffixKeyDirectory)
cfg.ValueDirectory = v.GetString(cfg.namespace + suffixValueDirectory)
cfg.Directories.Keys = v.GetString(cfg.namespace + suffixKeyDirectory)
cfg.Directories.Values = v.GetString(cfg.namespace + suffixValueDirectory)

Check warning on line 173 in plugin/storage/badger/options.go

View check run for this annotation

Codecov / codecov/patch

plugin/storage/badger/options.go#L172-L173

Added lines #L172 - L173 were not covered by tests
cfg.SyncWrites = v.GetBool(cfg.namespace + suffixSyncWrite)
cfg.SpanStoreTTL = v.GetDuration(cfg.namespace + suffixSpanstoreTTL)
cfg.TTL.SpanStore = v.GetDuration(cfg.namespace + suffixSpanstoreTTL)

Check warning on line 175 in plugin/storage/badger/options.go

View check run for this annotation

Codecov / codecov/patch

plugin/storage/badger/options.go#L175

Added line #L175 was not covered by tests
cfg.MaintenanceInterval = v.GetDuration(cfg.namespace + suffixMaintenanceInterval)
cfg.MetricsUpdateInterval = v.GetDuration(cfg.namespace + suffixMetricsInterval)
cfg.ReadOnly = v.GetBool(cfg.namespace + suffixReadOnly)
Expand All @@ -152,3 +182,8 @@
func (opt *Options) GetPrimary() NamespaceConfig {
return opt.Primary
}

func (c *NamespaceConfig) Validate() error {
_, err := govalidator.ValidateStruct(c)
return err

Check warning on line 188 in plugin/storage/badger/options.go

View check run for this annotation

Codecov / codecov/patch

plugin/storage/badger/options.go#L186-L188

Added lines #L186 - L188 were not covered by tests
}
45 changes: 41 additions & 4 deletions plugin/storage/badger/options_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap"

"github.com/jaegertracing/jaeger/pkg/config"
Expand All @@ -21,7 +22,7 @@ func TestDefaultOptionsParsing(t *testing.T) {

assert.True(t, opts.GetPrimary().Ephemeral)
assert.False(t, opts.GetPrimary().SyncWrites)
assert.Equal(t, time.Duration(72*time.Hour), opts.GetPrimary().SpanStoreTTL)
assert.Equal(t, time.Duration(72*time.Hour), opts.GetPrimary().TTL.SpanStore)
}

func TestParseOptions(t *testing.T) {
Expand All @@ -38,9 +39,9 @@ func TestParseOptions(t *testing.T) {

assert.False(t, opts.GetPrimary().Ephemeral)
assert.True(t, opts.GetPrimary().SyncWrites)
assert.Equal(t, time.Duration(168*time.Hour), opts.GetPrimary().SpanStoreTTL)
assert.Equal(t, "/var/lib/badger", opts.GetPrimary().KeyDirectory)
assert.Equal(t, "/mnt/slow/badger", opts.GetPrimary().ValueDirectory)
assert.Equal(t, time.Duration(168*time.Hour), opts.GetPrimary().TTL.SpanStore)
assert.Equal(t, "/var/lib/badger", opts.GetPrimary().Directories.Keys)
assert.Equal(t, "/mnt/slow/badger", opts.GetPrimary().Directories.Values)
assert.False(t, opts.GetPrimary().ReadOnly)
}

Expand All @@ -53,3 +54,39 @@ func TestReadOnlyOptions(t *testing.T) {
opts.InitFromViper(v, zap.NewNop())
assert.True(t, opts.GetPrimary().ReadOnly)
}

func TestValidate_DoesNotReturnErrorWhenValid(t *testing.T) {
tests := []struct {
name string
config *NamespaceConfig
}{
{
name: "non-required fields not set",
config: &NamespaceConfig{},
},
{
name: "all fields are set",
config: &NamespaceConfig{
TTL: TTL{
SpanStore: time.Second,
},
Directories: Directories{
Keys: "some-key-directory",
Values: "some-values-directory",
},
Ephemeral: false,
SyncWrites: false,
MaintenanceInterval: time.Second,
MetricsUpdateInterval: time.Second,
ReadOnly: false,
},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
err := test.config.Validate()
require.NoError(t, err)
})
}
}
4 changes: 2 additions & 2 deletions plugin/storage/badger/stats_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@
// In case of ephemeral these are the same, but we'll report them separately for consistency
var keyDirStatfs unix.Statfs_t
// Error ignored to satisfy Codecov
_ = unix.Statfs(f.Options.GetPrimary().KeyDirectory, &keyDirStatfs)
_ = unix.Statfs(f.Options.GetPrimary().Directories.Keys, &keyDirStatfs)

Check warning on line 15 in plugin/storage/badger/stats_linux.go

View check run for this annotation

Codecov / codecov/patch

plugin/storage/badger/stats_linux.go#L15

Added line #L15 was not covered by tests

var valDirStatfs unix.Statfs_t
// Error ignored to satisfy Codecov
_ = unix.Statfs(f.Options.GetPrimary().ValueDirectory, &valDirStatfs)
_ = unix.Statfs(f.Options.GetPrimary().Directories.Values, &valDirStatfs)

Check warning on line 19 in plugin/storage/badger/stats_linux.go

View check run for this annotation

Codecov / codecov/patch

plugin/storage/badger/stats_linux.go#L19

Added line #L19 was not covered by tests

// Using Bavail instead of Bfree to get non-priviledged user space available
//nolint: gosec // G115
Expand Down
Loading