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 }