Skip to content

Commit d6827e3

Browse files
authored
Support default configs for storage backends (jaegertracing#5691)
## Which problem is this PR solving? - Many OTEL Collector components provide default configs such that users do not need to provide most settings. - However, due to our organization of the storage extension config, there was no way to provide defaults ## Description of the changes - 🛑 **breaking** Change the main config inside out: instead of static separation by storage types followed by a map of custom names, move the map to the top level followed by static separation by storage type. E.g. ```yaml # before memory: some_storage: max_traces: 100000 # after backends: some_storage: memory: max_traces: 100000 ``` - This required an introduction of an extra nesting via `backends`, which is a bit unfortunate, but the OTEL framework requires config to be a struct, it did not work with a map at the top level. Having a struct might actually be beneficial in the future if we need some top-level settings - Add custom marshaling code where if a specific storage type is detected as set-by-user, then a default is created first (similar mechanism to how extension default configs is created by OTEL Collector, but unfortunately that mechanism is rigid, non-recursive) - Change sample config files to the new format - Use names `some_store` and `another_store` in configs to emphasize that those are custom names, not part of the config struct - Add more unit tests for config ## How was this change tested? - Unit tests and CI ## Checklist - [ ] I have read https://github.com/jaegertracing/jaeger/blob/master/CONTRIBUTING_GUIDELINES.md - [ ] I have signed all commits - [ ] I have added unit tests for the new functionality - [ ] I have run lint and test steps successfully - for `jaeger`: `make lint test` - for `jaeger-ui`: `yarn lint` and `yarn test` --------- Signed-off-by: Yuri Shkuro <[email protected]>
1 parent 9ba3238 commit d6827e3

20 files changed

+439
-310
lines changed

cmd/jaeger/config-badger.yaml

+14-18
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,22 @@ service:
88

99
extensions:
1010
jaeger_query:
11-
trace_storage: badger_main
12-
trace_storage_archive: badger_archive
11+
trace_storage: some_store
12+
trace_storage_archive: another_store
1313
ui_config: ./cmd/jaeger/config-ui.json
1414

1515
jaeger_storage:
16-
badger:
17-
badger_main:
18-
directory_key: "/tmp/jaeger/"
19-
directory_value: "/tmp/jaeger/"
20-
ephemeral: false
21-
maintenance_interval: 5
22-
metrics_update_interval: 10
23-
span_store_ttl: 72h
24-
badger_archive:
25-
directory_key: "/tmp/jaeger_archive/"
26-
directory_value: "/tmp/jaeger_archive/"
27-
ephemeral: false
28-
maintenance_interval: 5
29-
metrics_update_interval: 10
30-
span_store_ttl: 720h
16+
backends:
17+
some_store:
18+
badger:
19+
directory_key: "/tmp/jaeger/"
20+
directory_value: "/tmp/jaeger/"
21+
ephemeral: false
22+
another_store:
23+
badger:
24+
directory_key: "/tmp/jaeger_archive/"
25+
directory_value: "/tmp/jaeger_archive/"
26+
ephemeral: false
3127

3228
receivers:
3329
otlp:
@@ -40,4 +36,4 @@ processors:
4036

4137
exporters:
4238
jaeger_storage_exporter:
43-
trace_storage: badger_main
39+
trace_storage: some_store

cmd/jaeger/config-cassandra.yaml

+10-22
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,18 @@ service:
88

99
extensions:
1010
jaeger_query:
11-
trace_storage: cassandra_main
12-
trace_storage_archive: cassandra_archive
11+
trace_storage: some_storage
12+
trace_storage_archive: another_storage
1313
ui_config: ./cmd/jaeger/config-ui.json
1414

1515
jaeger_storage:
16-
cassandra:
17-
cassandra_main:
18-
servers: 127.0.0.1
19-
port: 9042
20-
keyspace: "jaeger_v1_dc1"
21-
connections_per_host: 2
22-
index:
23-
tags: true
24-
logs: true
25-
process_tags: true
26-
cassandra_archive:
27-
servers: 127.0.0.1
28-
port: 9042
29-
keyspace: "jaeger_v1_dc1"
30-
connections_per_host: 2
31-
index:
32-
tags: true
33-
logs: true
34-
process_tags: true
16+
backends:
17+
some_storage:
18+
cassandra:
19+
keyspace: "jaeger_v1_dc1"
20+
another_storage:
21+
cassandra:
22+
keyspace: "jaeger_v1_dc1"
3523
receivers:
3624
otlp:
3725
protocols:
@@ -50,4 +38,4 @@ processors:
5038

5139
exporters:
5240
jaeger_storage_exporter:
53-
trace_storage: cassandra_main
41+
trace_storage: some_storage

cmd/jaeger/config-elasticsearch.yaml

+10-16
Original file line numberDiff line numberDiff line change
@@ -8,24 +8,18 @@ service:
88

99
extensions:
1010
jaeger_query:
11-
trace_storage: es_main
12-
trace_storage_archive: es_archive
11+
trace_storage: some_storage
12+
trace_storage_archive: another_storage
1313
ui_config: ./cmd/jaeger/config-ui.json
1414

1515
jaeger_storage:
16-
elasticsearch:
17-
es_main:
18-
server_urls: http://localhost:9200
19-
log_level: "error"
20-
index_prefix: "jaeger-main"
21-
use_aliases: false
22-
create_mappings: true
23-
es_archive:
24-
server_urls: http://localhost:9200
25-
log_level: "error"
26-
index_prefix: "jaeger-archive"
27-
use_aliases: false
28-
create_mappings: true
16+
backends:
17+
some_storage:
18+
elasticsearch:
19+
index_prefix: "jaeger-main"
20+
another_storage:
21+
elasticsearch:
22+
index_prefix: "jaeger-archive"
2923

3024
receivers:
3125
otlp:
@@ -38,4 +32,4 @@ processors:
3832

3933
exporters:
4034
jaeger_storage_exporter:
41-
trace_storage: es_main
35+
trace_storage: some_storage

cmd/jaeger/config-opensearch.yaml

+10-16
Original file line numberDiff line numberDiff line change
@@ -8,25 +8,19 @@ service:
88

99
extensions:
1010
jaeger_query:
11-
trace_storage: os_main
12-
trace_storage_archive: os_archive
11+
trace_storage: some_storage
12+
trace_storage_archive: another_storage
1313
ui_config: ./cmd/jaeger/config-ui.json
1414

1515
jaeger_storage:
16-
opensearch:
17-
os_main:
18-
server_urls: http://localhost:9200
19-
log_level: "error"
20-
index_prefix: "jaeger-main"
21-
use_aliases: false
22-
create_mappings: true
16+
backends:
17+
some_storage:
18+
opensearch:
19+
index_prefix: "jaeger-main"
2320

24-
os_archive:
25-
server_urls: http://localhost:9200
26-
log_level: "error"
27-
index_prefix: "jaeger-main"
28-
use_aliases: false
29-
create_mappings: true
21+
another_storage:
22+
opensearch:
23+
index_prefix: "jaeger-main"
3024

3125
receivers:
3226
otlp:
@@ -39,4 +33,4 @@ processors:
3933

4034
exporters:
4135
jaeger_storage_exporter:
42-
trace_storage: os_main
36+
trace_storage: some_storage

cmd/jaeger/config-remote-storage.yaml

+8-8
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,16 @@ service:
88

99
extensions:
1010
jaeger_query:
11-
trace_storage: external-storage
11+
trace_storage: some-storage
1212
ui_config: ./cmd/jaeger/config-ui.json
1313

1414
jaeger_storage:
15-
grpc:
16-
external-storage:
17-
endpoint: localhost:17271
18-
timeout: 5s
19-
tls:
20-
insecure: true
15+
backends:
16+
some-storage:
17+
grpc:
18+
endpoint: localhost:17271
19+
tls:
20+
insecure: true
2121

2222
receivers:
2323
otlp:
@@ -30,4 +30,4 @@ processors:
3030

3131
exporters:
3232
jaeger_storage_exporter:
33-
trace_storage: external-storage
33+
trace_storage: some-storage

cmd/jaeger/internal/all-in-one.yaml

+6-5
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ service:
88

99
extensions:
1010
jaeger_query:
11-
trace_storage: memstore
11+
trace_storage: some_storage
1212

1313
jaeger_storage:
14-
memory:
15-
memstore:
16-
max_traces: 100000
14+
backends:
15+
some_storage:
16+
memory:
17+
max_traces: 100000
1718

1819
receivers:
1920
otlp:
@@ -35,4 +36,4 @@ processors:
3536

3637
exporters:
3738
jaeger_storage_exporter:
38-
trace_storage: memstore
39+
trace_storage: some_storage

cmd/jaeger/internal/exporters/storageexporter/exporter_test.go

+12-9
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929
"go.opentelemetry.io/collector/pdata/ptrace"
3030
noopmetric "go.opentelemetry.io/otel/metric/noop"
3131
nooptrace "go.opentelemetry.io/otel/trace/noop"
32-
"go.uber.org/zap"
32+
"go.uber.org/zap/zaptest"
3333

3434
"github.com/jaegertracing/jaeger/cmd/jaeger/internal/extension/jaegerstorage"
3535
"github.com/jaegertracing/jaeger/model"
@@ -103,7 +103,7 @@ func TestExporter(t *testing.T) {
103103

104104
ctx := context.Background()
105105
telemetrySettings := component.TelemetrySettings{
106-
Logger: zap.L(),
106+
Logger: zaptest.NewLogger(t),
107107
TracerProvider: nooptrace.NewTracerProvider(),
108108
MeterProvider: noopmetric.NewMeterProvider(),
109109
}
@@ -157,18 +157,21 @@ func TestExporter(t *testing.T) {
157157
}
158158

159159
func makeStorageExtension(t *testing.T, memstoreName string) component.Host {
160+
telemetrySettings := component.TelemetrySettings{
161+
Logger: zaptest.NewLogger(t),
162+
TracerProvider: nooptrace.NewTracerProvider(),
163+
MeterProvider: noopmetric.NewMeterProvider(),
164+
}
160165
extensionFactory := jaegerstorage.NewFactory()
161166
storageExtension, err := extensionFactory.CreateExtension(
162167
context.Background(),
163168
extension.Settings{
164-
TelemetrySettings: component.TelemetrySettings{
165-
Logger: zap.L(),
166-
TracerProvider: nooptrace.NewTracerProvider(),
167-
},
169+
TelemetrySettings: telemetrySettings,
168170
},
169-
&jaegerstorage.Config{Memory: map[string]memory.Configuration{
170-
memstoreName: {MaxTraces: 10000},
171-
}})
171+
&jaegerstorage.Config{Backends: map[string]jaegerstorage.Backend{
172+
memstoreName: {Memory: &memory.Configuration{MaxTraces: 10000}},
173+
}},
174+
)
172175
require.NoError(t, err)
173176

174177
host := storagetest.NewStorageHost()

cmd/jaeger/internal/extension/jaegerstorage/config.go

+77-13
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,95 @@ package jaegerstorage
66
import (
77
"fmt"
88
"reflect"
9+
"time"
910

11+
"go.opentelemetry.io/collector/component"
12+
"go.opentelemetry.io/collector/confmap"
13+
14+
casCfg "github.com/jaegertracing/jaeger/pkg/cassandra/config"
1015
esCfg "github.com/jaegertracing/jaeger/pkg/es/config"
1116
"github.com/jaegertracing/jaeger/plugin/storage/badger"
1217
"github.com/jaegertracing/jaeger/plugin/storage/cassandra"
18+
"github.com/jaegertracing/jaeger/plugin/storage/es"
1319
"github.com/jaegertracing/jaeger/plugin/storage/grpc"
1420
"github.com/jaegertracing/jaeger/plugin/storage/memory"
1521
)
1622

17-
// Config has the configuration for jaeger-query,
23+
var (
24+
_ component.ConfigValidator = (*Config)(nil)
25+
_ confmap.Unmarshaler = (*Backend)(nil)
26+
)
27+
28+
// Config contains configuration(s) for jaeger trace storage.
29+
// Keys in the map are storage names that can be used to refer to them
30+
// from other components, e.g. from jaeger_storage_exporter or jaeger_query.
31+
// We tried to alias this type directly to a map, but conf did not populated it correctly.
32+
// Note also that the Backend struct has a custom unmarshaler.
1833
type Config struct {
19-
Memory map[string]memory.Configuration `mapstructure:"memory"`
20-
Badger map[string]badger.NamespaceConfig `mapstructure:"badger"`
21-
GRPC map[string]grpc.ConfigV2 `mapstructure:"grpc"`
22-
Opensearch map[string]esCfg.Configuration `mapstructure:"opensearch"`
23-
Elasticsearch map[string]esCfg.Configuration `mapstructure:"elasticsearch"`
24-
Cassandra map[string]cassandra.Options `mapstructure:"cassandra"`
25-
// TODO add other storage types here
26-
// TODO how will this work with 3rd party storage implementations?
27-
// Option: instead of looking for specific name, check interface.
34+
Backends map[string]Backend `mapstructure:"backends"`
35+
}
36+
37+
type Backend struct {
38+
Memory *memory.Configuration `mapstructure:"memory"`
39+
Badger *badger.NamespaceConfig `mapstructure:"badger"`
40+
GRPC *grpc.ConfigV2 `mapstructure:"grpc"`
41+
Cassandra *cassandra.Options `mapstructure:"cassandra"`
42+
Elasticsearch *esCfg.Configuration `mapstructure:"elasticsearch"`
43+
Opensearch *esCfg.Configuration `mapstructure:"opensearch"`
44+
}
45+
46+
// Unmarshal implements confmap.Unmarshaler. This allows us to provide
47+
// defaults for different configs. It cannot be done in createDefaultConfig()
48+
// because at that time we don't know which backends the user wants to use.
49+
func (cfg *Backend) Unmarshal(conf *confmap.Conf) error {
50+
// apply defaults
51+
if conf.IsSet("memory") {
52+
cfg.Memory = &memory.Configuration{
53+
MaxTraces: 1_000_000,
54+
}
55+
}
56+
if conf.IsSet("badger") {
57+
v := badger.DefaultNamespaceConfig()
58+
cfg.Badger = &v
59+
}
60+
if conf.IsSet("grpc") {
61+
v := grpc.DefaultConfigV2()
62+
cfg.GRPC = &v
63+
}
64+
if conf.IsSet("cassandra") {
65+
cfg.Cassandra = &cassandra.Options{
66+
Primary: cassandra.NamespaceConfig{
67+
Configuration: casCfg.DefaultConfiguration(),
68+
Enabled: true,
69+
},
70+
SpanStoreWriteCacheTTL: 12 * time.Hour,
71+
Index: cassandra.IndexConfig{
72+
Tags: true,
73+
ProcessTags: true,
74+
Logs: true,
75+
},
76+
}
77+
}
78+
if conf.IsSet("elasticsearch") {
79+
v := es.DefaultConfig()
80+
cfg.Elasticsearch = &v
81+
}
82+
if conf.IsSet("opensearch") {
83+
v := es.DefaultConfig()
84+
cfg.Opensearch = &v
85+
}
86+
return conf.Unmarshal(cfg)
2887
}
2988

3089
func (cfg *Config) Validate() error {
31-
emptyCfg := createDefaultConfig().(*Config)
32-
if reflect.DeepEqual(*cfg, *emptyCfg) {
33-
return fmt.Errorf("%s: no storage type present in config", ID)
90+
if len(cfg.Backends) == 0 {
91+
return fmt.Errorf("at least one storage is required")
92+
}
93+
for name, b := range cfg.Backends {
94+
empty := Backend{}
95+
if reflect.DeepEqual(b, empty) {
96+
return fmt.Errorf("no backend defined for storage '%s'", name)
97+
}
3498
}
3599
return nil
36100
}

0 commit comments

Comments
 (0)