From 7da6b618a7eef2f97aa6666ac7edef50aa6b3cae Mon Sep 17 00:00:00 2001 From: Alex Boten <223565+codeboten@users.noreply.github.com> Date: Thu, 29 Aug 2024 12:05:54 -0700 Subject: [PATCH] [service] deprecate TelemetrySettings.MeterProvider (#10912) This is replaced by a LeveledMeterProvider method on the struct instead. This reduces the complexity from the view of component authors, in that there's no need to check the level before invoking the meter to record a metric. Closes https://github.com/open-telemetry/opentelemetry-collector/issues/9510 --------- Signed-off-by: Alex Boten <223565+codeboten@users.noreply.github.com> Co-authored-by: Tyler Helmuth <12352919+TylerHelmuth@users.noreply.github.com> --- .../codeboten_level-internal-telemetry.yaml | 25 +++++++++++ .../internal/metadata/generated_telemetry.go | 30 ++++--------- cmd/mdatagen/loader.go | 13 ++++++ cmd/mdatagen/templates/telemetry.go.tmpl | 29 +++++------- component/componenttest/nop_telemetry.go | 6 ++- component/componenttest/obsreporttest.go | 6 ++- component/telemetry.go | 7 ++- config/configgrpc/configgrpc.go | 8 +--- config/confighttp/confighttp.go | 9 +--- config/confighttp/confighttp_test.go | 3 +- config/confighttp/go.mod | 2 +- .../internal/metadata/generated_telemetry.go | 44 +++++++------------ .../internal/metadata/generated_telemetry.go | 31 +++++-------- processor/batchprocessor/metadata.yaml | 1 + processor/batchprocessor/metrics.go | 5 +-- .../internal/metadata/generated_telemetry.go | 42 +++++++----------- processor/processorhelper/obsreport.go | 2 +- processor/processorhelper/obsreport_test.go | 3 -- .../internal/metadata/generated_telemetry.go | 30 ++++--------- .../internal/metadata/generated_telemetry.go | 22 +++------- .../internal/metadata/generated_telemetry.go | 42 +++++++----------- .../proctelemetry/process_telemetry_test.go | 15 ++++--- 22 files changed, 159 insertions(+), 216 deletions(-) create mode 100644 .chloggen/codeboten_level-internal-telemetry.yaml diff --git a/.chloggen/codeboten_level-internal-telemetry.yaml b/.chloggen/codeboten_level-internal-telemetry.yaml new file mode 100644 index 00000000000..0d8561d9af3 --- /dev/null +++ b/.chloggen/codeboten_level-internal-telemetry.yaml @@ -0,0 +1,25 @@ +# Use this changelog template to create an entry for release notes. + +# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix' +change_type: deprecation + +# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver) +component: configtelemetry + +# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`). +note: "Deprecating `TelemetrySettings.MeterProvider` in favour of `TelemetrySettings.LeveledMeterProvider`" + +# One or more tracking issues or pull requests related to the change +issues: [10912] + +# (Optional) One or more lines of additional information to render under the primary note. +# These lines will be padded with 2 spaces and then inserted directly into the document. +# Use pipe (|) for multiline entries. +subtext: + +# Optional: The change log or logs in which this entry should be included. +# e.g. '[user]' or '[user, api]' +# Include 'user' if the change is relevant to end users. +# Include 'api' if there is a change to a library API. +# Default: '[user]' +change_logs: [api] diff --git a/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_telemetry.go b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_telemetry.go index ea6bfee53e9..43104bedead 100644 --- a/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_telemetry.go +++ b/cmd/mdatagen/internal/samplereceiver/internal/metadata/generated_telemetry.go @@ -7,7 +7,6 @@ import ( "errors" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/noop" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/collector/component" @@ -36,19 +35,12 @@ type TelemetryBuilder struct { observeProcessRuntimeTotalAllocBytes func(context.Context, metric.Observer) error QueueLength metric.Int64ObservableGauge RequestDuration metric.Float64Histogram - level configtelemetry.Level + meters map[configtelemetry.Level]metric.Meter } // telemetryBuilderOption applies changes to default builder. type telemetryBuilderOption func(*TelemetryBuilder) -// WithLevel sets the current telemetry level for the component. -func WithLevel(lvl configtelemetry.Level) telemetryBuilderOption { - return func(builder *TelemetryBuilder) { - builder.level = lvl - } -} - // WithProcessRuntimeTotalAllocBytesCallback sets callback for observable ProcessRuntimeTotalAllocBytes metric. func WithProcessRuntimeTotalAllocBytesCallback(cb func() int64, opts ...metric.ObserveOption) telemetryBuilderOption { return func(builder *TelemetryBuilder) { @@ -62,7 +54,7 @@ func WithProcessRuntimeTotalAllocBytesCallback(cb func() int64, opts ...metric.O // InitQueueLength configures the QueueLength metric. func (builder *TelemetryBuilder) InitQueueLength(cb func() int64, opts ...metric.ObserveOption) error { var err error - builder.QueueLength, err = builder.meter.Int64ObservableGauge( + builder.QueueLength, err = builder.meters[configtelemetry.LevelBasic].Int64ObservableGauge( "otelcol_queue_length", metric.WithDescription("This metric is optional and therefore not initialized in NewTelemetryBuilder."), metric.WithUnit("{items}"), @@ -70,7 +62,7 @@ func (builder *TelemetryBuilder) InitQueueLength(cb func() int64, opts ...metric if err != nil { return err } - _, err = builder.meter.RegisterCallback(func(_ context.Context, o metric.Observer) error { + _, err = builder.meters[configtelemetry.LevelBasic].RegisterCallback(func(_ context.Context, o metric.Observer) error { o.ObserveInt64(builder.QueueLength, cb(), opts...) return nil }, builder.QueueLength) @@ -80,31 +72,27 @@ func (builder *TelemetryBuilder) InitQueueLength(cb func() int64, opts ...metric // NewTelemetryBuilder provides a struct with methods to update all internal telemetry // for a component func NewTelemetryBuilder(settings component.TelemetrySettings, options ...telemetryBuilderOption) (*TelemetryBuilder, error) { - builder := TelemetryBuilder{level: configtelemetry.LevelBasic} + builder := TelemetryBuilder{meters: map[configtelemetry.Level]metric.Meter{}} for _, op := range options { op(&builder) } + builder.meters[configtelemetry.LevelBasic] = LeveledMeter(settings, configtelemetry.LevelBasic) var err, errs error - if builder.level >= configtelemetry.LevelBasic { - builder.meter = Meter(settings) - } else { - builder.meter = noop.Meter{} - } - builder.BatchSizeTriggerSend, err = builder.meter.Int64Counter( + builder.BatchSizeTriggerSend, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_batch_size_trigger_send", metric.WithDescription("Number of times the batch was sent due to a size trigger"), metric.WithUnit("{times}"), ) errs = errors.Join(errs, err) - builder.ProcessRuntimeTotalAllocBytes, err = builder.meter.Int64ObservableCounter( + builder.ProcessRuntimeTotalAllocBytes, err = builder.meters[configtelemetry.LevelBasic].Int64ObservableCounter( "otelcol_process_runtime_total_alloc_bytes", metric.WithDescription("Cumulative bytes allocated for heap objects (see 'go doc runtime.MemStats.TotalAlloc')"), metric.WithUnit("By"), ) errs = errors.Join(errs, err) - _, err = builder.meter.RegisterCallback(builder.observeProcessRuntimeTotalAllocBytes, builder.ProcessRuntimeTotalAllocBytes) + _, err = builder.meters[configtelemetry.LevelBasic].RegisterCallback(builder.observeProcessRuntimeTotalAllocBytes, builder.ProcessRuntimeTotalAllocBytes) errs = errors.Join(errs, err) - builder.RequestDuration, err = builder.meter.Float64Histogram( + builder.RequestDuration, err = builder.meters[configtelemetry.LevelBasic].Float64Histogram( "otelcol_request_duration", metric.WithDescription("Duration of request"), metric.WithUnit("s"), metric.WithExplicitBucketBoundaries([]float64{1, 10, 100}...), diff --git a/cmd/mdatagen/loader.go b/cmd/mdatagen/loader.go index c091d39052c..9353aae405b 100644 --- a/cmd/mdatagen/loader.go +++ b/cmd/mdatagen/loader.go @@ -127,6 +127,11 @@ type metric struct { // Attributes is the list of attributes that the metric emits. Attributes []attributeName `mapstructure:"attributes"` + + // Level specifies the minimum `configtelemetry.Level` for which + // the metric will be emitted. This only applies to internal telemetry + // configuration. + Level configtelemetry.Level `mapstructure:"level"` } func (m *metric) Unmarshal(parser *confmap.Conf) error { @@ -237,6 +242,14 @@ type telemetry struct { Metrics map[metricName]metric `mapstructure:"metrics"` } +func (t telemetry) Levels() map[string]interface{} { + levels := map[string]interface{}{} + for _, m := range t.Metrics { + levels[m.Level.String()] = nil + } + return levels +} + type metadata struct { // Type of the component. Type string `mapstructure:"type"` diff --git a/cmd/mdatagen/templates/telemetry.go.tmpl b/cmd/mdatagen/templates/telemetry.go.tmpl index 1727e823e61..a4b98c3359b 100644 --- a/cmd/mdatagen/templates/telemetry.go.tmpl +++ b/cmd/mdatagen/templates/telemetry.go.tmpl @@ -45,25 +45,18 @@ type TelemetryBuilder struct { observe{{ $name.Render }} func(context.Context, metric.Observer) error {{- end }} {{- end }} - level configtelemetry.Level + meters map[configtelemetry.Level]metric.Meter } // telemetryBuilderOption applies changes to default builder. type telemetryBuilderOption func(*TelemetryBuilder) -// WithLevel sets the current telemetry level for the component. -func WithLevel(lvl configtelemetry.Level) telemetryBuilderOption { - return func(builder *TelemetryBuilder) { - builder.level = lvl - } -} - {{- range $name, $metric := .Telemetry.Metrics }} {{- if $metric.Optional }} // Init{{ $name.Render }} configures the {{ $name.Render }} metric. func (builder *TelemetryBuilder) Init{{ $name.Render }}({{ if $metric.Data.Async -}}cb func() {{ $metric.Data.BasicType }}{{- end }}, opts ...metric.ObserveOption) error { var err error - builder.{{ $name.Render }}, err = builder.meter.{{ $metric.Data.Instrument }}( + builder.{{ $name.Render }}, err = builder.meters[configtelemetry.Level{{ casesTitle $metric.Level.String }}].{{ $metric.Data.Instrument }}( "otelcol_{{ $name }}", metric.WithDescription("{{ $metric.Description }}"), metric.WithUnit("{{ $metric.Unit }}"), @@ -75,7 +68,7 @@ func (builder *TelemetryBuilder) Init{{ $name.Render }}({{ if $metric.Data.Async if err != nil { return err } - _, err = builder.meter.RegisterCallback(func(_ context.Context, o metric.Observer) error { + _, err = builder.meters[configtelemetry.Level{{ casesTitle $metric.Level.String }}].RegisterCallback(func(_ context.Context, o metric.Observer) error { o.Observe{{ casesTitle $metric.Data.BasicType }}(builder.{{ $name.Render }}, cb(), opts...) return nil }, builder.{{ $name.Render }}) @@ -102,20 +95,18 @@ func With{{ $name.Render }}Callback(cb func() {{ $metric.Data.BasicType }}, opts // NewTelemetryBuilder provides a struct with methods to update all internal telemetry // for a component func NewTelemetryBuilder(settings component.TelemetrySettings, options ...telemetryBuilderOption) (*TelemetryBuilder, error) { - builder := TelemetryBuilder{level: configtelemetry.LevelBasic} + builder := TelemetryBuilder{meters: map[configtelemetry.Level]metric.Meter{}} for _, op := range options { op(&builder) } + {{- range $level, $val := .Telemetry.Levels }} + builder.meters[configtelemetry.Level{{ casesTitle $level }}] = LeveledMeter(settings, configtelemetry.Level{{ casesTitle $level }}) + {{- end }} var err, errs error - if builder.level >= configtelemetry.Level{{ casesTitle .Telemetry.Level.String }} { - builder.meter = Meter(settings) - } else { - builder.meter = noop.Meter{} - } - + {{- range $name, $metric := .Telemetry.Metrics }} {{- if not $metric.Optional }} - builder.{{ $name.Render }}, err = builder.meter.{{ $metric.Data.Instrument }}( + builder.{{ $name.Render }}, err = builder.meters[configtelemetry.Level{{ casesTitle $metric.Level.String }}].{{ $metric.Data.Instrument }}( "otelcol_{{ $name }}", metric.WithDescription("{{ $metric.Description }}"), metric.WithUnit("{{ $metric.Unit }}"), @@ -125,7 +116,7 @@ func NewTelemetryBuilder(settings component.TelemetrySettings, options ...teleme ) errs = errors.Join(errs, err) {{- if $metric.Data.Async }} - _, err = builder.meter.RegisterCallback(builder.observe{{ $name.Render }}, builder.{{ $name.Render }}) + _, err = builder.meters[configtelemetry.Level{{ casesTitle $metric.Level.String }}].RegisterCallback(builder.observe{{ $name.Render }}, builder.{{ $name.Render }}) errs = errors.Join(errs, err) {{- end }} {{- end }} diff --git a/component/componenttest/nop_telemetry.go b/component/componenttest/nop_telemetry.go index 0324f65c980..15ac6f51b28 100644 --- a/component/componenttest/nop_telemetry.go +++ b/component/componenttest/nop_telemetry.go @@ -4,6 +4,7 @@ package componenttest // import "go.opentelemetry.io/collector/component/componenttest" import ( + "go.opentelemetry.io/otel/metric" noopmetric "go.opentelemetry.io/otel/metric/noop" nooptrace "go.opentelemetry.io/otel/trace/noop" "go.uber.org/zap" @@ -16,7 +17,10 @@ import ( // NewNopTelemetrySettings returns a new nop telemetry settings for Create* functions. func NewNopTelemetrySettings() component.TelemetrySettings { return component.TelemetrySettings{ - Logger: zap.NewNop(), + Logger: zap.NewNop(), + LeveledMeterProvider: func(_ configtelemetry.Level) metric.MeterProvider { + return noopmetric.NewMeterProvider() + }, TracerProvider: nooptrace.NewTracerProvider(), MeterProvider: noopmetric.NewMeterProvider(), MetricsLevel: configtelemetry.LevelNone, diff --git a/component/componenttest/obsreporttest.go b/component/componenttest/obsreporttest.go index 652db62529f..d4f35aee3b6 100644 --- a/component/componenttest/obsreporttest.go +++ b/component/componenttest/obsreporttest.go @@ -10,6 +10,7 @@ import ( "github.com/prometheus/client_golang/prometheus/promhttp" "go.opentelemetry.io/otel/attribute" otelprom "go.opentelemetry.io/otel/exporters/prometheus" + "go.opentelemetry.io/otel/metric" sdkmetric "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/resource" sdktrace "go.opentelemetry.io/otel/sdk/trace" @@ -149,7 +150,6 @@ func SetupTelemetry(id component.ID) (TestTelemetry, error) { SpanRecorder: sr, } settings.ts.TracerProvider = tp - settings.ts.MetricsLevel = configtelemetry.LevelNormal promRegOtel := prometheus.NewRegistry() @@ -162,7 +162,9 @@ func SetupTelemetry(id component.ID) (TestTelemetry, error) { sdkmetric.WithResource(resource.Empty()), sdkmetric.WithReader(exp), ) - settings.ts.MeterProvider = settings.meterProvider + settings.ts.LeveledMeterProvider = func(_ configtelemetry.Level) metric.MeterProvider { + return settings.meterProvider + } settings.prometheusChecker = &prometheusChecker{ otelHandler: promhttp.HandlerFor(promRegOtel, promhttp.HandlerOpts{}), diff --git a/component/telemetry.go b/component/telemetry.go index 3d33efbdab0..ffb3ac25411 100644 --- a/component/telemetry.go +++ b/component/telemetry.go @@ -22,14 +22,17 @@ type TelemetrySettings struct { TracerProvider trace.TracerProvider // MeterProvider that the factory can pass to other instrumented third-party libraries. + // + // Deprecated [v0.109.0]: use LeveledMeterProvider instead. MeterProvider metric.MeterProvider // LeveledMeterProvider returns a MeterProvider for a Level that the factory can // pass to other instrumented third-party libraries. LeveledMeterProvider func(level configtelemetry.Level) metric.MeterProvider - // MetricsLevel controls the level of detail for metrics emitted by the collector. - // Experimental: *NOTE* this field is experimental and may be changed or removed. + // MetricsLevel represents the configuration value set when the collector + // is configured. Components may use this level to decide whether it is + // appropriate to avoid computationally expensive calculations. MetricsLevel configtelemetry.Level // Resource contains the resource attributes for the collector's telemetry. diff --git a/config/configgrpc/configgrpc.go b/config/configgrpc/configgrpc.go index 046017cbaac..9caa916b81c 100644 --- a/config/configgrpc/configgrpc.go +++ b/config/configgrpc/configgrpc.go @@ -306,9 +306,7 @@ func (gcs *ClientConfig) toDialOptions(ctx context.Context, host component.Host, otelOpts := []otelgrpc.Option{ otelgrpc.WithTracerProvider(settings.TracerProvider), otelgrpc.WithPropagators(otel.GetTextMapPropagator()), - } - if settings.MetricsLevel >= configtelemetry.LevelDetailed { - otelOpts = append(otelOpts, otelgrpc.WithMeterProvider(settings.MeterProvider)) + otelgrpc.WithMeterProvider(settings.LeveledMeterProvider(configtelemetry.LevelDetailed)), } // Enable OpenTelemetry observability plugin. @@ -427,9 +425,7 @@ func (gss *ServerConfig) toServerOption(host component.Host, settings component. otelOpts := []otelgrpc.Option{ otelgrpc.WithTracerProvider(settings.TracerProvider), otelgrpc.WithPropagators(otel.GetTextMapPropagator()), - } - if settings.MetricsLevel >= configtelemetry.LevelDetailed { - otelOpts = append(otelOpts, otelgrpc.WithMeterProvider(settings.MeterProvider)) + otelgrpc.WithMeterProvider(settings.LeveledMeterProvider(configtelemetry.LevelDetailed)), } // Enable OpenTelemetry observability plugin. diff --git a/config/confighttp/confighttp.go b/config/confighttp/confighttp.go index e7ac390a93c..ec7c3197de9 100644 --- a/config/confighttp/confighttp.go +++ b/config/confighttp/confighttp.go @@ -226,11 +226,8 @@ func (hcs *ClientConfig) ToClient(ctx context.Context, host component.Host, sett otelOpts := []otelhttp.Option{ otelhttp.WithTracerProvider(settings.TracerProvider), otelhttp.WithPropagators(otel.GetTextMapPropagator()), + otelhttp.WithMeterProvider(settings.LeveledMeterProvider(configtelemetry.LevelDetailed)), } - if settings.MetricsLevel >= configtelemetry.LevelDetailed { - otelOpts = append(otelOpts, otelhttp.WithMeterProvider(settings.MeterProvider)) - } - // wrapping http transport with otelhttp transport to enable otel instrumentation if settings.TracerProvider != nil && settings.MeterProvider != nil { clientTransport = otelhttp.NewTransport(clientTransport, otelOpts...) @@ -460,9 +457,7 @@ func (hss *ServerConfig) ToServer(_ context.Context, host component.Host, settin otelhttp.WithSpanNameFormatter(func(_ string, r *http.Request) string { return r.URL.Path }), - } - if settings.MetricsLevel >= configtelemetry.LevelDetailed { - otelOpts = append(otelOpts, otelhttp.WithMeterProvider(settings.MeterProvider)) + otelhttp.WithMeterProvider(settings.LeveledMeterProvider(configtelemetry.LevelDetailed)), } // Enable OpenTelemetry observability plugin. diff --git a/config/confighttp/confighttp_test.go b/config/confighttp/confighttp_test.go index 8107b6a77f8..2ef1517da73 100644 --- a/config/confighttp/confighttp_test.go +++ b/config/confighttp/confighttp_test.go @@ -20,6 +20,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/metric" "go.uber.org/zap" "go.uber.org/zap/zaptest/observer" @@ -52,7 +53,7 @@ var ( dummyID = component.MustNewID("dummy") nonExistingID = component.MustNewID("nonexisting") // Omit TracerProvider and MeterProvider in TelemetrySettings as otelhttp.Transport cannot be introspected - nilProvidersSettings = component.TelemetrySettings{Logger: zap.NewNop(), MetricsLevel: configtelemetry.LevelNone} + nilProvidersSettings = component.TelemetrySettings{Logger: zap.NewNop(), MetricsLevel: configtelemetry.LevelNone, LeveledMeterProvider: func(_ configtelemetry.Level) metric.MeterProvider { return nil }} ) func TestAllHTTPClientSettings(t *testing.T) { diff --git a/config/confighttp/go.mod b/config/confighttp/go.mod index c3400348fcf..86168be5788 100644 --- a/config/confighttp/go.mod +++ b/config/confighttp/go.mod @@ -20,6 +20,7 @@ require ( go.opentelemetry.io/collector/featuregate v1.14.1 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.54.0 go.opentelemetry.io/otel v1.29.0 + go.opentelemetry.io/otel/metric v1.29.0 go.uber.org/goleak v1.3.0 go.uber.org/zap v1.27.0 golang.org/x/net v0.28.0 @@ -52,7 +53,6 @@ require ( go.opentelemetry.io/collector/extension v0.108.1 // indirect go.opentelemetry.io/collector/pdata v1.14.1 // indirect go.opentelemetry.io/otel/exporters/prometheus v0.51.0 // indirect - go.opentelemetry.io/otel/metric v1.29.0 // indirect go.opentelemetry.io/otel/sdk v1.29.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.29.0 // indirect go.opentelemetry.io/otel/trace v1.29.0 // indirect diff --git a/exporter/exporterhelper/internal/metadata/generated_telemetry.go b/exporter/exporterhelper/internal/metadata/generated_telemetry.go index 7155f256b58..a35625ac0a5 100644 --- a/exporter/exporterhelper/internal/metadata/generated_telemetry.go +++ b/exporter/exporterhelper/internal/metadata/generated_telemetry.go @@ -7,7 +7,6 @@ import ( "errors" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/noop" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/collector/component" @@ -42,23 +41,16 @@ type TelemetryBuilder struct { ExporterSentLogRecords metric.Int64Counter ExporterSentMetricPoints metric.Int64Counter ExporterSentSpans metric.Int64Counter - level configtelemetry.Level + meters map[configtelemetry.Level]metric.Meter } // telemetryBuilderOption applies changes to default builder. type telemetryBuilderOption func(*TelemetryBuilder) -// WithLevel sets the current telemetry level for the component. -func WithLevel(lvl configtelemetry.Level) telemetryBuilderOption { - return func(builder *TelemetryBuilder) { - builder.level = lvl - } -} - // InitExporterQueueCapacity configures the ExporterQueueCapacity metric. func (builder *TelemetryBuilder) InitExporterQueueCapacity(cb func() int64, opts ...metric.ObserveOption) error { var err error - builder.ExporterQueueCapacity, err = builder.meter.Int64ObservableGauge( + builder.ExporterQueueCapacity, err = builder.meters[configtelemetry.LevelBasic].Int64ObservableGauge( "otelcol_exporter_queue_capacity", metric.WithDescription("Fixed capacity of the retry queue (in batches)"), metric.WithUnit("{batches}"), @@ -66,7 +58,7 @@ func (builder *TelemetryBuilder) InitExporterQueueCapacity(cb func() int64, opts if err != nil { return err } - _, err = builder.meter.RegisterCallback(func(_ context.Context, o metric.Observer) error { + _, err = builder.meters[configtelemetry.LevelBasic].RegisterCallback(func(_ context.Context, o metric.Observer) error { o.ObserveInt64(builder.ExporterQueueCapacity, cb(), opts...) return nil }, builder.ExporterQueueCapacity) @@ -76,7 +68,7 @@ func (builder *TelemetryBuilder) InitExporterQueueCapacity(cb func() int64, opts // InitExporterQueueSize configures the ExporterQueueSize metric. func (builder *TelemetryBuilder) InitExporterQueueSize(cb func() int64, opts ...metric.ObserveOption) error { var err error - builder.ExporterQueueSize, err = builder.meter.Int64ObservableGauge( + builder.ExporterQueueSize, err = builder.meters[configtelemetry.LevelBasic].Int64ObservableGauge( "otelcol_exporter_queue_size", metric.WithDescription("Current size of the retry queue (in batches)"), metric.WithUnit("{batches}"), @@ -84,7 +76,7 @@ func (builder *TelemetryBuilder) InitExporterQueueSize(cb func() int64, opts ... if err != nil { return err } - _, err = builder.meter.RegisterCallback(func(_ context.Context, o metric.Observer) error { + _, err = builder.meters[configtelemetry.LevelBasic].RegisterCallback(func(_ context.Context, o metric.Observer) error { o.ObserveInt64(builder.ExporterQueueSize, cb(), opts...) return nil }, builder.ExporterQueueSize) @@ -94,65 +86,61 @@ func (builder *TelemetryBuilder) InitExporterQueueSize(cb func() int64, opts ... // NewTelemetryBuilder provides a struct with methods to update all internal telemetry // for a component func NewTelemetryBuilder(settings component.TelemetrySettings, options ...telemetryBuilderOption) (*TelemetryBuilder, error) { - builder := TelemetryBuilder{level: configtelemetry.LevelBasic} + builder := TelemetryBuilder{meters: map[configtelemetry.Level]metric.Meter{}} for _, op := range options { op(&builder) } + builder.meters[configtelemetry.LevelBasic] = LeveledMeter(settings, configtelemetry.LevelBasic) var err, errs error - if builder.level >= configtelemetry.LevelBasic { - builder.meter = Meter(settings) - } else { - builder.meter = noop.Meter{} - } - builder.ExporterEnqueueFailedLogRecords, err = builder.meter.Int64Counter( + builder.ExporterEnqueueFailedLogRecords, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_exporter_enqueue_failed_log_records", metric.WithDescription("Number of log records failed to be added to the sending queue."), metric.WithUnit("{records}"), ) errs = errors.Join(errs, err) - builder.ExporterEnqueueFailedMetricPoints, err = builder.meter.Int64Counter( + builder.ExporterEnqueueFailedMetricPoints, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_exporter_enqueue_failed_metric_points", metric.WithDescription("Number of metric points failed to be added to the sending queue."), metric.WithUnit("{datapoints}"), ) errs = errors.Join(errs, err) - builder.ExporterEnqueueFailedSpans, err = builder.meter.Int64Counter( + builder.ExporterEnqueueFailedSpans, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_exporter_enqueue_failed_spans", metric.WithDescription("Number of spans failed to be added to the sending queue."), metric.WithUnit("{spans}"), ) errs = errors.Join(errs, err) - builder.ExporterSendFailedLogRecords, err = builder.meter.Int64Counter( + builder.ExporterSendFailedLogRecords, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_exporter_send_failed_log_records", metric.WithDescription("Number of log records in failed attempts to send to destination."), metric.WithUnit("{records}"), ) errs = errors.Join(errs, err) - builder.ExporterSendFailedMetricPoints, err = builder.meter.Int64Counter( + builder.ExporterSendFailedMetricPoints, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_exporter_send_failed_metric_points", metric.WithDescription("Number of metric points in failed attempts to send to destination."), metric.WithUnit("{datapoints}"), ) errs = errors.Join(errs, err) - builder.ExporterSendFailedSpans, err = builder.meter.Int64Counter( + builder.ExporterSendFailedSpans, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_exporter_send_failed_spans", metric.WithDescription("Number of spans in failed attempts to send to destination."), metric.WithUnit("{spans}"), ) errs = errors.Join(errs, err) - builder.ExporterSentLogRecords, err = builder.meter.Int64Counter( + builder.ExporterSentLogRecords, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_exporter_sent_log_records", metric.WithDescription("Number of log record successfully sent to destination."), metric.WithUnit("{records}"), ) errs = errors.Join(errs, err) - builder.ExporterSentMetricPoints, err = builder.meter.Int64Counter( + builder.ExporterSentMetricPoints, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_exporter_sent_metric_points", metric.WithDescription("Number of metric points successfully sent to destination."), metric.WithUnit("{datapoints}"), ) errs = errors.Join(errs, err) - builder.ExporterSentSpans, err = builder.meter.Int64Counter( + builder.ExporterSentSpans, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_exporter_sent_spans", metric.WithDescription("Number of spans successfully sent to destination."), metric.WithUnit("{spans}"), diff --git a/processor/batchprocessor/internal/metadata/generated_telemetry.go b/processor/batchprocessor/internal/metadata/generated_telemetry.go index 87bfa10e369..38a97468402 100644 --- a/processor/batchprocessor/internal/metadata/generated_telemetry.go +++ b/processor/batchprocessor/internal/metadata/generated_telemetry.go @@ -7,7 +7,6 @@ import ( "errors" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/noop" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/collector/component" @@ -37,19 +36,12 @@ type TelemetryBuilder struct { ProcessorBatchMetadataCardinality metric.Int64ObservableUpDownCounter observeProcessorBatchMetadataCardinality func(context.Context, metric.Observer) error ProcessorBatchTimeoutTriggerSend metric.Int64Counter - level configtelemetry.Level + meters map[configtelemetry.Level]metric.Meter } // telemetryBuilderOption applies changes to default builder. type telemetryBuilderOption func(*TelemetryBuilder) -// WithLevel sets the current telemetry level for the component. -func WithLevel(lvl configtelemetry.Level) telemetryBuilderOption { - return func(builder *TelemetryBuilder) { - builder.level = lvl - } -} - // WithProcessorBatchMetadataCardinalityCallback sets callback for observable ProcessorBatchMetadataCardinality metric. func WithProcessorBatchMetadataCardinalityCallback(cb func() int64, opts ...metric.ObserveOption) telemetryBuilderOption { return func(builder *TelemetryBuilder) { @@ -63,43 +55,40 @@ func WithProcessorBatchMetadataCardinalityCallback(cb func() int64, opts ...metr // NewTelemetryBuilder provides a struct with methods to update all internal telemetry // for a component func NewTelemetryBuilder(settings component.TelemetrySettings, options ...telemetryBuilderOption) (*TelemetryBuilder, error) { - builder := TelemetryBuilder{level: configtelemetry.LevelBasic} + builder := TelemetryBuilder{meters: map[configtelemetry.Level]metric.Meter{}} for _, op := range options { op(&builder) } + builder.meters[configtelemetry.LevelBasic] = LeveledMeter(settings, configtelemetry.LevelBasic) + builder.meters[configtelemetry.LevelDetailed] = LeveledMeter(settings, configtelemetry.LevelDetailed) var err, errs error - if builder.level >= configtelemetry.LevelNormal { - builder.meter = Meter(settings) - } else { - builder.meter = noop.Meter{} - } - builder.ProcessorBatchBatchSendSize, err = builder.meter.Int64Histogram( + builder.ProcessorBatchBatchSendSize, err = builder.meters[configtelemetry.LevelBasic].Int64Histogram( "otelcol_processor_batch_batch_send_size", metric.WithDescription("Number of units in the batch"), metric.WithUnit("{units}"), metric.WithExplicitBucketBoundaries([]float64{10, 25, 50, 75, 100, 250, 500, 750, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 20000, 30000, 50000, 100000}...), ) errs = errors.Join(errs, err) - builder.ProcessorBatchBatchSendSizeBytes, err = builder.meter.Int64Histogram( + builder.ProcessorBatchBatchSendSizeBytes, err = builder.meters[configtelemetry.LevelDetailed].Int64Histogram( "otelcol_processor_batch_batch_send_size_bytes", metric.WithDescription("Number of bytes in batch that was sent"), metric.WithUnit("By"), metric.WithExplicitBucketBoundaries([]float64{10, 25, 50, 75, 100, 250, 500, 750, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 20000, 30000, 50000, 100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1e+06, 2e+06, 3e+06, 4e+06, 5e+06, 6e+06, 7e+06, 8e+06, 9e+06}...), ) errs = errors.Join(errs, err) - builder.ProcessorBatchBatchSizeTriggerSend, err = builder.meter.Int64Counter( + builder.ProcessorBatchBatchSizeTriggerSend, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_processor_batch_batch_size_trigger_send", metric.WithDescription("Number of times the batch was sent due to a size trigger"), metric.WithUnit("{times}"), ) errs = errors.Join(errs, err) - builder.ProcessorBatchMetadataCardinality, err = builder.meter.Int64ObservableUpDownCounter( + builder.ProcessorBatchMetadataCardinality, err = builder.meters[configtelemetry.LevelBasic].Int64ObservableUpDownCounter( "otelcol_processor_batch_metadata_cardinality", metric.WithDescription("Number of distinct metadata value combinations being processed"), metric.WithUnit("{combinations}"), ) errs = errors.Join(errs, err) - _, err = builder.meter.RegisterCallback(builder.observeProcessorBatchMetadataCardinality, builder.ProcessorBatchMetadataCardinality) + _, err = builder.meters[configtelemetry.LevelBasic].RegisterCallback(builder.observeProcessorBatchMetadataCardinality, builder.ProcessorBatchMetadataCardinality) errs = errors.Join(errs, err) - builder.ProcessorBatchTimeoutTriggerSend, err = builder.meter.Int64Counter( + builder.ProcessorBatchTimeoutTriggerSend, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_processor_batch_timeout_trigger_send", metric.WithDescription("Number of times the batch was sent due to a timeout trigger"), metric.WithUnit("{times}"), diff --git a/processor/batchprocessor/metadata.yaml b/processor/batchprocessor/metadata.yaml index c9bd117706d..6f72f5d4d79 100644 --- a/processor/batchprocessor/metadata.yaml +++ b/processor/batchprocessor/metadata.yaml @@ -34,6 +34,7 @@ telemetry: value_type: int bucket_boundaries: [10, 25, 50, 75, 100, 250, 500, 750, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 20000, 30000, 50000, 100000] processor_batch_batch_send_size_bytes: + level: detailed enabled: true description: Number of bytes in batch that was sent unit: By diff --git a/processor/batchprocessor/metrics.go b/processor/batchprocessor/metrics.go index d9983022830..98302403707 100644 --- a/processor/batchprocessor/metrics.go +++ b/processor/batchprocessor/metrics.go @@ -36,7 +36,6 @@ func newBatchProcessorTelemetry(set processor.Settings, currentMetadataCardinali attrs := attribute.NewSet(attribute.String(obsmetrics.ProcessorKey, set.ID.String())) telemetryBuilder, err := metadata.NewTelemetryBuilder(set.TelemetrySettings, - metadata.WithLevel(set.MetricsLevel), metadata.WithProcessorBatchMetadataCardinalityCallback(func() int64 { return int64(currentMetadataCardinality()) }, metric.WithAttributeSet(attrs)), @@ -63,7 +62,5 @@ func (bpt *batchProcessorTelemetry) record(trigger trigger, sent, bytes int64) { } bpt.telemetryBuilder.ProcessorBatchBatchSendSize.Record(bpt.exportCtx, sent, metric.WithAttributeSet(bpt.processorAttr)) - if bpt.detailed { - bpt.telemetryBuilder.ProcessorBatchBatchSendSizeBytes.Record(bpt.exportCtx, bytes, metric.WithAttributeSet(bpt.processorAttr)) - } + bpt.telemetryBuilder.ProcessorBatchBatchSendSizeBytes.Record(bpt.exportCtx, bytes, metric.WithAttributeSet(bpt.processorAttr)) } diff --git a/processor/processorhelper/internal/metadata/generated_telemetry.go b/processor/processorhelper/internal/metadata/generated_telemetry.go index 432f3703f88..114ba9df7c0 100644 --- a/processor/processorhelper/internal/metadata/generated_telemetry.go +++ b/processor/processorhelper/internal/metadata/generated_telemetry.go @@ -6,7 +6,6 @@ import ( "errors" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/noop" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/collector/component" @@ -42,99 +41,88 @@ type TelemetryBuilder struct { ProcessorRefusedLogRecords metric.Int64Counter ProcessorRefusedMetricPoints metric.Int64Counter ProcessorRefusedSpans metric.Int64Counter - level configtelemetry.Level + meters map[configtelemetry.Level]metric.Meter } // telemetryBuilderOption applies changes to default builder. type telemetryBuilderOption func(*TelemetryBuilder) -// WithLevel sets the current telemetry level for the component. -func WithLevel(lvl configtelemetry.Level) telemetryBuilderOption { - return func(builder *TelemetryBuilder) { - builder.level = lvl - } -} - // NewTelemetryBuilder provides a struct with methods to update all internal telemetry // for a component func NewTelemetryBuilder(settings component.TelemetrySettings, options ...telemetryBuilderOption) (*TelemetryBuilder, error) { - builder := TelemetryBuilder{level: configtelemetry.LevelBasic} + builder := TelemetryBuilder{meters: map[configtelemetry.Level]metric.Meter{}} for _, op := range options { op(&builder) } + builder.meters[configtelemetry.LevelBasic] = LeveledMeter(settings, configtelemetry.LevelBasic) var err, errs error - if builder.level >= configtelemetry.LevelBasic { - builder.meter = Meter(settings) - } else { - builder.meter = noop.Meter{} - } - builder.ProcessorAcceptedLogRecords, err = builder.meter.Int64Counter( + builder.ProcessorAcceptedLogRecords, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_processor_accepted_log_records", metric.WithDescription("Number of log records successfully pushed into the next component in the pipeline."), metric.WithUnit("{records}"), ) errs = errors.Join(errs, err) - builder.ProcessorAcceptedMetricPoints, err = builder.meter.Int64Counter( + builder.ProcessorAcceptedMetricPoints, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_processor_accepted_metric_points", metric.WithDescription("Number of metric points successfully pushed into the next component in the pipeline."), metric.WithUnit("{datapoints}"), ) errs = errors.Join(errs, err) - builder.ProcessorAcceptedSpans, err = builder.meter.Int64Counter( + builder.ProcessorAcceptedSpans, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_processor_accepted_spans", metric.WithDescription("Number of spans successfully pushed into the next component in the pipeline."), metric.WithUnit("{spans}"), ) errs = errors.Join(errs, err) - builder.ProcessorDroppedLogRecords, err = builder.meter.Int64Counter( + builder.ProcessorDroppedLogRecords, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_processor_dropped_log_records", metric.WithDescription("Number of log records that were dropped."), metric.WithUnit("{records}"), ) errs = errors.Join(errs, err) - builder.ProcessorDroppedMetricPoints, err = builder.meter.Int64Counter( + builder.ProcessorDroppedMetricPoints, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_processor_dropped_metric_points", metric.WithDescription("Number of metric points that were dropped."), metric.WithUnit("{datapoints}"), ) errs = errors.Join(errs, err) - builder.ProcessorDroppedSpans, err = builder.meter.Int64Counter( + builder.ProcessorDroppedSpans, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_processor_dropped_spans", metric.WithDescription("Number of spans that were dropped."), metric.WithUnit("{spans}"), ) errs = errors.Join(errs, err) - builder.ProcessorInsertedLogRecords, err = builder.meter.Int64Counter( + builder.ProcessorInsertedLogRecords, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_processor_inserted_log_records", metric.WithDescription("Number of log records that were inserted."), metric.WithUnit("{records}"), ) errs = errors.Join(errs, err) - builder.ProcessorInsertedMetricPoints, err = builder.meter.Int64Counter( + builder.ProcessorInsertedMetricPoints, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_processor_inserted_metric_points", metric.WithDescription("Number of metric points that were inserted."), metric.WithUnit("{datapoints}"), ) errs = errors.Join(errs, err) - builder.ProcessorInsertedSpans, err = builder.meter.Int64Counter( + builder.ProcessorInsertedSpans, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_processor_inserted_spans", metric.WithDescription("Number of spans that were inserted."), metric.WithUnit("{spans}"), ) errs = errors.Join(errs, err) - builder.ProcessorRefusedLogRecords, err = builder.meter.Int64Counter( + builder.ProcessorRefusedLogRecords, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_processor_refused_log_records", metric.WithDescription("Number of log records that were rejected by the next component in the pipeline."), metric.WithUnit("{records}"), ) errs = errors.Join(errs, err) - builder.ProcessorRefusedMetricPoints, err = builder.meter.Int64Counter( + builder.ProcessorRefusedMetricPoints, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_processor_refused_metric_points", metric.WithDescription("Number of metric points that were rejected by the next component in the pipeline."), metric.WithUnit("{datapoints}"), ) errs = errors.Join(errs, err) - builder.ProcessorRefusedSpans, err = builder.meter.Int64Counter( + builder.ProcessorRefusedSpans, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_processor_refused_spans", metric.WithDescription("Number of spans that were rejected by the next component in the pipeline."), metric.WithUnit("{spans}"), diff --git a/processor/processorhelper/obsreport.go b/processor/processorhelper/obsreport.go index 2a3bd0dc754..6fef0fd45ec 100644 --- a/processor/processorhelper/obsreport.go +++ b/processor/processorhelper/obsreport.go @@ -48,7 +48,7 @@ func NewObsReport(cfg ObsReportSettings) (*ObsReport, error) { } func newObsReport(cfg ObsReportSettings) (*ObsReport, error) { - telemetryBuilder, err := metadata.NewTelemetryBuilder(cfg.ProcessorCreateSettings.TelemetrySettings, metadata.WithLevel(cfg.ProcessorCreateSettings.MetricsLevel)) + telemetryBuilder, err := metadata.NewTelemetryBuilder(cfg.ProcessorCreateSettings.TelemetrySettings) if err != nil { return nil, err } diff --git a/processor/processorhelper/obsreport_test.go b/processor/processorhelper/obsreport_test.go index 63e88bb5ced..f48b6739ef0 100644 --- a/processor/processorhelper/obsreport_test.go +++ b/processor/processorhelper/obsreport_test.go @@ -218,7 +218,6 @@ func TestNoMetrics(t *testing.T) { const inserted = 5 set := tt.TelemetrySettings() - set.MetricsLevel = configtelemetry.LevelNone set.LeveledMeterProvider = func(_ configtelemetry.Level) metric.MeterProvider { return noop.MeterProvider{} } @@ -243,7 +242,6 @@ func TestNoMetrics(t *testing.T) { const inserted = 4 set := tt.TelemetrySettings() - set.MetricsLevel = configtelemetry.LevelNone set.LeveledMeterProvider = func(_ configtelemetry.Level) metric.MeterProvider { return noop.MeterProvider{} } @@ -268,7 +266,6 @@ func TestNoMetrics(t *testing.T) { const inserted = 3 set := tt.TelemetrySettings() - set.MetricsLevel = configtelemetry.LevelNone set.LeveledMeterProvider = func(_ configtelemetry.Level) metric.MeterProvider { return noop.MeterProvider{} } diff --git a/receiver/receiverhelper/internal/metadata/generated_telemetry.go b/receiver/receiverhelper/internal/metadata/generated_telemetry.go index b0e676d1961..766735f943c 100644 --- a/receiver/receiverhelper/internal/metadata/generated_telemetry.go +++ b/receiver/receiverhelper/internal/metadata/generated_telemetry.go @@ -6,7 +6,6 @@ import ( "errors" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/noop" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/collector/component" @@ -36,63 +35,52 @@ type TelemetryBuilder struct { ReceiverRefusedLogRecords metric.Int64Counter ReceiverRefusedMetricPoints metric.Int64Counter ReceiverRefusedSpans metric.Int64Counter - level configtelemetry.Level + meters map[configtelemetry.Level]metric.Meter } // telemetryBuilderOption applies changes to default builder. type telemetryBuilderOption func(*TelemetryBuilder) -// WithLevel sets the current telemetry level for the component. -func WithLevel(lvl configtelemetry.Level) telemetryBuilderOption { - return func(builder *TelemetryBuilder) { - builder.level = lvl - } -} - // NewTelemetryBuilder provides a struct with methods to update all internal telemetry // for a component func NewTelemetryBuilder(settings component.TelemetrySettings, options ...telemetryBuilderOption) (*TelemetryBuilder, error) { - builder := TelemetryBuilder{level: configtelemetry.LevelBasic} + builder := TelemetryBuilder{meters: map[configtelemetry.Level]metric.Meter{}} for _, op := range options { op(&builder) } + builder.meters[configtelemetry.LevelBasic] = LeveledMeter(settings, configtelemetry.LevelBasic) var err, errs error - if builder.level >= configtelemetry.LevelBasic { - builder.meter = Meter(settings) - } else { - builder.meter = noop.Meter{} - } - builder.ReceiverAcceptedLogRecords, err = builder.meter.Int64Counter( + builder.ReceiverAcceptedLogRecords, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_receiver_accepted_log_records", metric.WithDescription("Number of log records successfully pushed into the pipeline."), metric.WithUnit("{records}"), ) errs = errors.Join(errs, err) - builder.ReceiverAcceptedMetricPoints, err = builder.meter.Int64Counter( + builder.ReceiverAcceptedMetricPoints, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_receiver_accepted_metric_points", metric.WithDescription("Number of metric points successfully pushed into the pipeline."), metric.WithUnit("{datapoints}"), ) errs = errors.Join(errs, err) - builder.ReceiverAcceptedSpans, err = builder.meter.Int64Counter( + builder.ReceiverAcceptedSpans, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_receiver_accepted_spans", metric.WithDescription("Number of spans successfully pushed into the pipeline."), metric.WithUnit("{spans}"), ) errs = errors.Join(errs, err) - builder.ReceiverRefusedLogRecords, err = builder.meter.Int64Counter( + builder.ReceiverRefusedLogRecords, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_receiver_refused_log_records", metric.WithDescription("Number of log records that could not be pushed into the pipeline."), metric.WithUnit("{records}"), ) errs = errors.Join(errs, err) - builder.ReceiverRefusedMetricPoints, err = builder.meter.Int64Counter( + builder.ReceiverRefusedMetricPoints, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_receiver_refused_metric_points", metric.WithDescription("Number of metric points that could not be pushed into the pipeline."), metric.WithUnit("{datapoints}"), ) errs = errors.Join(errs, err) - builder.ReceiverRefusedSpans, err = builder.meter.Int64Counter( + builder.ReceiverRefusedSpans, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_receiver_refused_spans", metric.WithDescription("Number of spans that could not be pushed into the pipeline."), metric.WithUnit("{spans}"), diff --git a/receiver/scraperhelper/internal/metadata/generated_telemetry.go b/receiver/scraperhelper/internal/metadata/generated_telemetry.go index 204dcb0ff55..498746b0e87 100644 --- a/receiver/scraperhelper/internal/metadata/generated_telemetry.go +++ b/receiver/scraperhelper/internal/metadata/generated_telemetry.go @@ -6,7 +6,6 @@ import ( "errors" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/noop" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/collector/component" @@ -32,39 +31,28 @@ type TelemetryBuilder struct { meter metric.Meter ScraperErroredMetricPoints metric.Int64Counter ScraperScrapedMetricPoints metric.Int64Counter - level configtelemetry.Level + meters map[configtelemetry.Level]metric.Meter } // telemetryBuilderOption applies changes to default builder. type telemetryBuilderOption func(*TelemetryBuilder) -// WithLevel sets the current telemetry level for the component. -func WithLevel(lvl configtelemetry.Level) telemetryBuilderOption { - return func(builder *TelemetryBuilder) { - builder.level = lvl - } -} - // NewTelemetryBuilder provides a struct with methods to update all internal telemetry // for a component func NewTelemetryBuilder(settings component.TelemetrySettings, options ...telemetryBuilderOption) (*TelemetryBuilder, error) { - builder := TelemetryBuilder{level: configtelemetry.LevelBasic} + builder := TelemetryBuilder{meters: map[configtelemetry.Level]metric.Meter{}} for _, op := range options { op(&builder) } + builder.meters[configtelemetry.LevelBasic] = LeveledMeter(settings, configtelemetry.LevelBasic) var err, errs error - if builder.level >= configtelemetry.LevelBasic { - builder.meter = Meter(settings) - } else { - builder.meter = noop.Meter{} - } - builder.ScraperErroredMetricPoints, err = builder.meter.Int64Counter( + builder.ScraperErroredMetricPoints, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_scraper_errored_metric_points", metric.WithDescription("Number of metric points that were unable to be scraped."), metric.WithUnit("{datapoints}"), ) errs = errors.Join(errs, err) - builder.ScraperScrapedMetricPoints, err = builder.meter.Int64Counter( + builder.ScraperScrapedMetricPoints, err = builder.meters[configtelemetry.LevelBasic].Int64Counter( "otelcol_scraper_scraped_metric_points", metric.WithDescription("Number of metric points successfully scraped."), metric.WithUnit("{datapoints}"), diff --git a/service/internal/metadata/generated_telemetry.go b/service/internal/metadata/generated_telemetry.go index d398ccf34ec..c08e6cd7cd3 100644 --- a/service/internal/metadata/generated_telemetry.go +++ b/service/internal/metadata/generated_telemetry.go @@ -7,7 +7,6 @@ import ( "errors" "go.opentelemetry.io/otel/metric" - "go.opentelemetry.io/otel/metric/noop" "go.opentelemetry.io/otel/trace" "go.opentelemetry.io/collector/component" @@ -43,19 +42,12 @@ type TelemetryBuilder struct { observeProcessRuntimeTotalSysMemoryBytes func(context.Context, metric.Observer) error ProcessUptime metric.Float64ObservableCounter observeProcessUptime func(context.Context, metric.Observer) error - level configtelemetry.Level + meters map[configtelemetry.Level]metric.Meter } // telemetryBuilderOption applies changes to default builder. type telemetryBuilderOption func(*TelemetryBuilder) -// WithLevel sets the current telemetry level for the component. -func WithLevel(lvl configtelemetry.Level) telemetryBuilderOption { - return func(builder *TelemetryBuilder) { - builder.level = lvl - } -} - // WithProcessCPUSecondsCallback sets callback for observable ProcessCPUSeconds metric. func WithProcessCPUSecondsCallback(cb func() float64, opts ...metric.ObserveOption) telemetryBuilderOption { return func(builder *TelemetryBuilder) { @@ -119,63 +111,59 @@ func WithProcessUptimeCallback(cb func() float64, opts ...metric.ObserveOption) // NewTelemetryBuilder provides a struct with methods to update all internal telemetry // for a component func NewTelemetryBuilder(settings component.TelemetrySettings, options ...telemetryBuilderOption) (*TelemetryBuilder, error) { - builder := TelemetryBuilder{level: configtelemetry.LevelBasic} + builder := TelemetryBuilder{meters: map[configtelemetry.Level]metric.Meter{}} for _, op := range options { op(&builder) } + builder.meters[configtelemetry.LevelBasic] = LeveledMeter(settings, configtelemetry.LevelBasic) var err, errs error - if builder.level >= configtelemetry.LevelBasic { - builder.meter = Meter(settings) - } else { - builder.meter = noop.Meter{} - } - builder.ProcessCPUSeconds, err = builder.meter.Float64ObservableCounter( + builder.ProcessCPUSeconds, err = builder.meters[configtelemetry.LevelBasic].Float64ObservableCounter( "otelcol_process_cpu_seconds", metric.WithDescription("Total CPU user and system time in seconds"), metric.WithUnit("s"), ) errs = errors.Join(errs, err) - _, err = builder.meter.RegisterCallback(builder.observeProcessCPUSeconds, builder.ProcessCPUSeconds) + _, err = builder.meters[configtelemetry.LevelBasic].RegisterCallback(builder.observeProcessCPUSeconds, builder.ProcessCPUSeconds) errs = errors.Join(errs, err) - builder.ProcessMemoryRss, err = builder.meter.Int64ObservableGauge( + builder.ProcessMemoryRss, err = builder.meters[configtelemetry.LevelBasic].Int64ObservableGauge( "otelcol_process_memory_rss", metric.WithDescription("Total physical memory (resident set size)"), metric.WithUnit("By"), ) errs = errors.Join(errs, err) - _, err = builder.meter.RegisterCallback(builder.observeProcessMemoryRss, builder.ProcessMemoryRss) + _, err = builder.meters[configtelemetry.LevelBasic].RegisterCallback(builder.observeProcessMemoryRss, builder.ProcessMemoryRss) errs = errors.Join(errs, err) - builder.ProcessRuntimeHeapAllocBytes, err = builder.meter.Int64ObservableGauge( + builder.ProcessRuntimeHeapAllocBytes, err = builder.meters[configtelemetry.LevelBasic].Int64ObservableGauge( "otelcol_process_runtime_heap_alloc_bytes", metric.WithDescription("Bytes of allocated heap objects (see 'go doc runtime.MemStats.HeapAlloc')"), metric.WithUnit("By"), ) errs = errors.Join(errs, err) - _, err = builder.meter.RegisterCallback(builder.observeProcessRuntimeHeapAllocBytes, builder.ProcessRuntimeHeapAllocBytes) + _, err = builder.meters[configtelemetry.LevelBasic].RegisterCallback(builder.observeProcessRuntimeHeapAllocBytes, builder.ProcessRuntimeHeapAllocBytes) errs = errors.Join(errs, err) - builder.ProcessRuntimeTotalAllocBytes, err = builder.meter.Int64ObservableCounter( + builder.ProcessRuntimeTotalAllocBytes, err = builder.meters[configtelemetry.LevelBasic].Int64ObservableCounter( "otelcol_process_runtime_total_alloc_bytes", metric.WithDescription("Cumulative bytes allocated for heap objects (see 'go doc runtime.MemStats.TotalAlloc')"), metric.WithUnit("By"), ) errs = errors.Join(errs, err) - _, err = builder.meter.RegisterCallback(builder.observeProcessRuntimeTotalAllocBytes, builder.ProcessRuntimeTotalAllocBytes) + _, err = builder.meters[configtelemetry.LevelBasic].RegisterCallback(builder.observeProcessRuntimeTotalAllocBytes, builder.ProcessRuntimeTotalAllocBytes) errs = errors.Join(errs, err) - builder.ProcessRuntimeTotalSysMemoryBytes, err = builder.meter.Int64ObservableGauge( + builder.ProcessRuntimeTotalSysMemoryBytes, err = builder.meters[configtelemetry.LevelBasic].Int64ObservableGauge( "otelcol_process_runtime_total_sys_memory_bytes", metric.WithDescription("Total bytes of memory obtained from the OS (see 'go doc runtime.MemStats.Sys')"), metric.WithUnit("By"), ) errs = errors.Join(errs, err) - _, err = builder.meter.RegisterCallback(builder.observeProcessRuntimeTotalSysMemoryBytes, builder.ProcessRuntimeTotalSysMemoryBytes) + _, err = builder.meters[configtelemetry.LevelBasic].RegisterCallback(builder.observeProcessRuntimeTotalSysMemoryBytes, builder.ProcessRuntimeTotalSysMemoryBytes) errs = errors.Join(errs, err) - builder.ProcessUptime, err = builder.meter.Float64ObservableCounter( + builder.ProcessUptime, err = builder.meters[configtelemetry.LevelBasic].Float64ObservableCounter( "otelcol_process_uptime", metric.WithDescription("Uptime of the process"), metric.WithUnit("s"), ) errs = errors.Join(errs, err) - _, err = builder.meter.RegisterCallback(builder.observeProcessUptime, builder.ProcessUptime) + _, err = builder.meters[configtelemetry.LevelBasic].RegisterCallback(builder.observeProcessUptime, builder.ProcessUptime) errs = errors.Join(errs, err) return &builder, errs } diff --git a/service/internal/proctelemetry/process_telemetry_test.go b/service/internal/proctelemetry/process_telemetry_test.go index 1367192db0f..466605ce8a4 100644 --- a/service/internal/proctelemetry/process_telemetry_test.go +++ b/service/internal/proctelemetry/process_telemetry_test.go @@ -28,8 +28,7 @@ import ( type testTelemetry struct { component.TelemetrySettings - promHandler http.Handler - meterProvider *sdkmetric.MeterProvider + promHandler http.Handler } var expectedMetrics = []string{ @@ -45,25 +44,27 @@ func setupTelemetry(t *testing.T) testTelemetry { settings := testTelemetry{ TelemetrySettings: componenttest.NewNopTelemetrySettings(), } - settings.TelemetrySettings.MetricsLevel = configtelemetry.LevelNormal promReg := prometheus.NewRegistry() exporter, err := otelprom.New(otelprom.WithRegisterer(promReg), otelprom.WithoutUnits(), otelprom.WithoutCounterSuffixes()) require.NoError(t, err) - settings.meterProvider = sdkmetric.NewMeterProvider( + meterProvider := sdkmetric.NewMeterProvider( sdkmetric.WithResource(resource.Empty()), sdkmetric.WithReader(exporter), ) - settings.TelemetrySettings.MeterProvider = settings.meterProvider + + settings.LeveledMeterProvider = func(_ configtelemetry.Level) metric.MeterProvider { + return meterProvider + } settings.TelemetrySettings.LeveledMeterProvider = func(_ configtelemetry.Level) metric.MeterProvider { - return settings.meterProvider + return meterProvider } settings.promHandler = promhttp.HandlerFor(promReg, promhttp.HandlerOpts{}) - t.Cleanup(func() { assert.NoError(t, settings.meterProvider.Shutdown(context.Background())) }) + t.Cleanup(func() { assert.NoError(t, meterProvider.Shutdown(context.Background())) }) return settings }