Skip to content

Commit 8a79193

Browse files
[service] Add service::telemetry::metrics::views config key (#12433)
#### Description This PR adds a `service::telemetry::metrics::views` config key, which explicitly sets the list of metric views used for internal telemetry, mirroring `meter_provider::views` in the SDK config. This can be used to disable specific internal metrics, among other uses. This key will cause an error if used alongside other features which would normally implicitly create views, such as: - not setting `service::telemetry::metrics::level` to `detailed`; - enabling the `telemetry.disableHighCardinalityMetrics` feature gate. #### Further discussion needed - A comment notes that the `telemetry.disableHighCardinalityMetrics` alpha gate *"will be removed when the collector allows for view configuration"*. I think setting the gate as deprecated first would be the correct thing to do, but it means that users relying on it will see their Collectors crash on update. Is that okay? - In the context of being able to enable/disable specific metrics, this key is only useful to disable metrics from an "all enabled" baseline. It cannot easily be used to customize the set of metrics emitted at `level: normal`, `level: basic`. Discussion is ongoing in #10769 on how to handle that, but the solution will probably involve a new key, which should hopefully be backward-compatible with the user-visible changes in this PR. #### Link to tracking issue Updates #10769 #### Testing None yet #### Documentation None yet, except the changelog --------- Co-authored-by: Pablo Baeyens <[email protected]>
1 parent 18390ba commit 8a79193

File tree

10 files changed

+133
-77
lines changed

10 files changed

+133
-77
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
7+
component: service
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Add config key to set metric views used for internal telemetry
11+
12+
# One or more tracking issues or pull requests related to the change
13+
issues: [10769]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext: |
19+
The `service::telemetry::metrics::views` config key can now be used to explicitly set the list of
20+
metric views used for internal telemetry, mirroring `meter_provider::views` in the SDK config.
21+
This can be used to disable specific internal metrics, among other uses.
22+
23+
This key will cause an error if used alongside other features which would normally implicitly create views, such as:
24+
- not setting `service::telemetry::metrics::level` to `detailed`;
25+
- enabling the `telemetry.disableHighCardinalityMetrics` feature flag.
26+
27+
# Optional: The change log or logs in which this entry should be included.
28+
# e.g. '[user]' or '[user, api]'
29+
# Include 'user' if the change is relevant to end users.
30+
# Include 'api' if there is a change to a library API.
31+
# Default: '[user]'
32+
change_logs: [user]

otelcol/config_test.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -301,14 +301,16 @@ func generateConfig() *Config {
301301
},
302302
Metrics: telemetry.MetricsConfig{
303303
Level: configtelemetry.LevelNormal,
304-
Readers: []config.MetricReader{
305-
{
306-
Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{
307-
Prometheus: &config.Prometheus{
308-
Host: newPtr("localhost"),
309-
Port: newPtr(8080),
310-
},
311-
}},
304+
MeterProvider: config.MeterProvider{
305+
Readers: []config.MetricReader{
306+
{
307+
Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{
308+
Prometheus: &config.Prometheus{
309+
Host: newPtr("localhost"),
310+
Port: newPtr(8080),
311+
},
312+
}},
313+
},
312314
},
313315
},
314316
},

service/config_test.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,12 +154,14 @@ func generateConfig() *Config {
154154
},
155155
Metrics: telemetry.MetricsConfig{
156156
Level: configtelemetry.LevelNormal,
157-
Readers: []config.MetricReader{
158-
{
159-
Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{
160-
Host: newPtr("localhost"),
161-
Port: newPtr(8080),
162-
}}},
157+
MeterProvider: config.MeterProvider{
158+
Readers: []config.MetricReader{
159+
{
160+
Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{
161+
Host: newPtr("localhost"),
162+
Port: newPtr(8080),
163+
}}},
164+
},
163165
},
164166
},
165167
},

service/service.go

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,18 @@ func New(ctx context.Context, set Settings, cfg Config) (*Service, error) {
137137

138138
sch := semconv.SchemaURL
139139

140-
views := configureViews(cfg.Telemetry.Metrics.Level)
140+
mpConfig := &cfg.Telemetry.Metrics.MeterProvider
141+
142+
if mpConfig.Views != nil {
143+
if disableHighCardinalityMetricsFeatureGate.IsEnabled() {
144+
return nil, errors.New("telemetry.disableHighCardinalityMetrics gate is incompatible with service::telemetry::metrics::views")
145+
}
146+
} else {
147+
mpConfig.Views = configureViews(cfg.Telemetry.Metrics.Level)
148+
}
141149

142-
readers := cfg.Telemetry.Metrics.Readers
143150
if cfg.Telemetry.Metrics.Level == configtelemetry.LevelNone {
144-
readers = []config.MetricReader{}
151+
mpConfig.Readers = []config.MetricReader{}
145152
}
146153

147154
sdk, err := config.NewSDK(
@@ -151,10 +158,7 @@ func New(ctx context.Context, set Settings, cfg Config) (*Service, error) {
151158
LoggerProvider: &config.LoggerProvider{
152159
Processors: cfg.Telemetry.Logs.Processors,
153160
},
154-
MeterProvider: &config.MeterProvider{
155-
Readers: readers,
156-
Views: views,
157-
},
161+
MeterProvider: mpConfig,
158162
TracerProvider: &config.TracerProvider{
159163
Processors: cfg.Telemetry.Traces.Processors,
160164
},
@@ -222,7 +226,7 @@ func New(ctx context.Context, set Settings, cfg Config) (*Service, error) {
222226
return nil, err
223227
}
224228

225-
if cfg.Telemetry.Metrics.Level != configtelemetry.LevelNone && (len(readers) != 0 || cfg.Telemetry.Metrics.Address != "") {
229+
if cfg.Telemetry.Metrics.Level != configtelemetry.LevelNone && (len(mpConfig.Readers) != 0 || cfg.Telemetry.Metrics.Address != "") {
226230
if err = proctelemetry.RegisterProcessMetrics(srv.telemetrySettings); err != nil {
227231
return nil, fmt.Errorf("failed to register process metrics: %w", err)
228232
}
@@ -406,6 +410,21 @@ func dropViewOption(selector *config.ViewSelector) config.View {
406410
func configureViews(level configtelemetry.Level) []config.View {
407411
views := []config.View{}
408412

413+
if level < configtelemetry.LevelDetailed {
414+
// Drop all otelhttp and otelgrpc metrics if the level is not detailed.
415+
views = append(views,
416+
dropViewOption(&config.ViewSelector{
417+
MeterName: ptr("go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"),
418+
}),
419+
dropViewOption(&config.ViewSelector{
420+
MeterName: ptr("go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"),
421+
}),
422+
)
423+
}
424+
425+
// Make sure to add the AttributeKeys view after the AggregationDrop view:
426+
// Only the first view outputting a given metric identity is actually used, so placing the
427+
// AttributeKeys view first would never drop the metrics regadless of level.
409428
if disableHighCardinalityMetricsFeatureGate.IsEnabled() {
410429
views = append(views, []config.View{
411430
{
@@ -438,18 +457,6 @@ func configureViews(level configtelemetry.Level) []config.View {
438457
}...)
439458
}
440459

441-
if level < configtelemetry.LevelDetailed {
442-
// Drop all otelhttp and otelgrpc metrics if the level is not detailed.
443-
views = append(views,
444-
dropViewOption(&config.ViewSelector{
445-
MeterName: ptr("go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc"),
446-
}),
447-
dropViewOption(&config.ViewSelector{
448-
MeterName: ptr("go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"),
449-
}),
450-
)
451-
}
452-
453460
// otel-arrow library metrics
454461
// See https://github.com/open-telemetry/otel-arrow/blob/c39257/pkg/otel/arrow_record/consumer.go#L174-L176
455462
if level < configtelemetry.LevelNormal {

service/telemetry/config.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,5 +111,9 @@ func (c *Config) Validate() error {
111111
return errors.New("collector telemetry metrics reader should exist when metric level is not none")
112112
}
113113

114+
if c.Metrics.Views != nil && c.Metrics.Level != configtelemetry.LevelDetailed {
115+
return errors.New("service::telemetry::metrics::views can only be set when service::telemetry::metrics::level is detailed")
116+
}
117+
114118
return nil
115119
}

service/telemetry/config_test.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,14 @@ func TestConfigValidate(t *testing.T) {
117117
cfg: &Config{
118118
Metrics: MetricsConfig{
119119
Level: configtelemetry.LevelBasic,
120-
Readers: []config.MetricReader{
121-
{
122-
Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{
123-
Host: newPtr("127.0.0.1"),
124-
Port: newPtr(3333),
125-
}}},
120+
MeterProvider: config.MeterProvider{
121+
Readers: []config.MetricReader{
122+
{
123+
Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{
124+
Host: newPtr("127.0.0.1"),
125+
Port: newPtr(3333),
126+
}}},
127+
},
126128
},
127129
},
128130
},
@@ -133,8 +135,7 @@ func TestConfigValidate(t *testing.T) {
133135
name: "invalid metric telemetry",
134136
cfg: &Config{
135137
Metrics: MetricsConfig{
136-
Level: configtelemetry.LevelBasic,
137-
Readers: nil,
138+
Level: configtelemetry.LevelBasic,
138139
},
139140
},
140141
success: false,

service/telemetry/factory.go

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -98,18 +98,20 @@ func createDefaultConfig() component.Config {
9898
},
9999
Metrics: MetricsConfig{
100100
Level: configtelemetry.LevelNormal,
101-
Readers: []config.MetricReader{
102-
{
103-
Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{
104-
WithoutScopeInfo: newPtr(true),
105-
WithoutUnits: newPtr(true),
106-
WithoutTypeSuffix: newPtr(true),
107-
Host: &metricsHost,
108-
Port: newPtr(8888),
109-
WithResourceConstantLabels: &config.IncludeExclude{
110-
Included: []string{},
111-
},
112-
}}},
101+
MeterProvider: config.MeterProvider{
102+
Readers: []config.MetricReader{
103+
{
104+
Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{
105+
WithoutScopeInfo: newPtr(true),
106+
WithoutUnits: newPtr(true),
107+
WithoutTypeSuffix: newPtr(true),
108+
Host: &metricsHost,
109+
Port: newPtr(8888),
110+
WithResourceConstantLabels: &config.IncludeExclude{
111+
Included: []string{},
112+
},
113+
}}},
114+
},
113115
},
114116
},
115117
},

service/telemetry/factory_test.go

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,14 @@ func TestTelemetryConfiguration(t *testing.T) {
6565
},
6666
Metrics: MetricsConfig{
6767
Level: configtelemetry.LevelBasic,
68-
Readers: []config.MetricReader{
69-
{
70-
Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{
71-
Host: newPtr("127.0.0.1"),
72-
Port: newPtr(3333),
73-
}}},
68+
MeterProvider: config.MeterProvider{
69+
Readers: []config.MetricReader{
70+
{
71+
Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{
72+
Host: newPtr("127.0.0.1"),
73+
Port: newPtr(3333),
74+
}}},
75+
},
7476
},
7577
},
7678
},
@@ -85,12 +87,14 @@ func TestTelemetryConfiguration(t *testing.T) {
8587
},
8688
Metrics: MetricsConfig{
8789
Level: configtelemetry.LevelBasic,
88-
Readers: []config.MetricReader{
89-
{
90-
Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{
91-
Host: newPtr("127.0.0.1"),
92-
Port: newPtr(3333),
93-
}}},
90+
MeterProvider: config.MeterProvider{
91+
Readers: []config.MetricReader{
92+
{
93+
Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: &config.Prometheus{
94+
Host: newPtr("127.0.0.1"),
95+
Port: newPtr(3333),
96+
}}},
97+
},
9498
},
9599
},
96100
},

service/telemetry/internal/migration/v0.3.0.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,7 @@ type MetricsConfigV030 struct {
7070
// Deprecated: [v0.111.0] use readers configuration.
7171
Address string `mapstructure:"address,omitempty"`
7272

73-
// Readers allow configuration of metric readers to emit metrics to
74-
// any number of supported backends.
75-
Readers []config.MetricReader `mapstructure:"readers"`
73+
config.MeterProvider `mapstructure:",squash"`
7674
}
7775

7876
func (c *MetricsConfigV030) Unmarshal(conf *confmap.Conf) error {

service/telemetry/metrics_test.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,13 @@ func TestTelemetryInit(t *testing.T) {
9797
cfg := Config{
9898
Metrics: MetricsConfig{
9999
Level: configtelemetry.LevelDetailed,
100-
Readers: []config.MetricReader{{
101-
Pull: &config.PullMetricReader{
102-
Exporter: config.PullMetricExporter{Prometheus: prom},
103-
},
104-
}},
100+
MeterProvider: config.MeterProvider{
101+
Readers: []config.MetricReader{{
102+
Pull: &config.PullMetricReader{
103+
Exporter: config.PullMetricExporter{Prometheus: prom},
104+
},
105+
}},
106+
},
105107
},
106108
}
107109
t.Run(tt.name, func(t *testing.T) {
@@ -217,9 +219,11 @@ func TestInstrumentEnabled(t *testing.T) {
217219
cfg := Config{
218220
Metrics: MetricsConfig{
219221
Level: configtelemetry.LevelDetailed,
220-
Readers: []config.MetricReader{{
221-
Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: prom}},
222-
}},
222+
MeterProvider: config.MeterProvider{
223+
Readers: []config.MetricReader{{
224+
Pull: &config.PullMetricReader{Exporter: config.PullMetricExporter{Prometheus: prom}},
225+
}},
226+
},
223227
},
224228
}
225229
sdk, err := config.NewSDK(

0 commit comments

Comments
 (0)