From d2c91702fed4e5896709d63dd18fb91402a8cabb Mon Sep 17 00:00:00 2001 From: Alex Boten <223565+codeboten@users.noreply.github.com> Date: Thu, 9 May 2024 10:18:14 -0700 Subject: [PATCH] [chore] use mdatagen for receiverhelper metrics (#10123) Signed-off-by: Alex Boten <223565+codeboten@users.noreply.github.com> --- ...kage_test.go => generated_package_test.go} | 3 +- .../internal/metadata/generated_telemetry.go | 79 +++++++++++++++ .../metadata/generated_telemetry_test.go | 63 ++++++++++++ receiver/receiverhelper/metadata.yaml | 57 +++++++++++ receiver/receiverhelper/obsreport.go | 95 ++++--------------- 5 files changed, 218 insertions(+), 79 deletions(-) rename receiver/receiverhelper/{package_test.go => generated_package_test.go} (62%) create mode 100644 receiver/receiverhelper/internal/metadata/generated_telemetry.go create mode 100644 receiver/receiverhelper/internal/metadata/generated_telemetry_test.go create mode 100644 receiver/receiverhelper/metadata.yaml diff --git a/receiver/receiverhelper/package_test.go b/receiver/receiverhelper/generated_package_test.go similarity index 62% rename from receiver/receiverhelper/package_test.go rename to receiver/receiverhelper/generated_package_test.go index 7b9bf829fc9..3e71ceab063 100644 --- a/receiver/receiverhelper/package_test.go +++ b/receiver/receiverhelper/generated_package_test.go @@ -1,5 +1,4 @@ -// Copyright The OpenTelemetry Authors -// SPDX-License-Identifier: Apache-2.0 +// Code generated by mdatagen. DO NOT EDIT. package receiverhelper diff --git a/receiver/receiverhelper/internal/metadata/generated_telemetry.go b/receiver/receiverhelper/internal/metadata/generated_telemetry.go new file mode 100644 index 00000000000..5226a3d64b4 --- /dev/null +++ b/receiver/receiverhelper/internal/metadata/generated_telemetry.go @@ -0,0 +1,79 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "errors" + + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/trace" + + "go.opentelemetry.io/collector/component" +) + +func Meter(settings component.TelemetrySettings) metric.Meter { + return settings.MeterProvider.Meter("go.opentelemetry.io/collector/receiver/receiverhelper") +} + +func Tracer(settings component.TelemetrySettings) trace.Tracer { + return settings.TracerProvider.Tracer("go.opentelemetry.io/collector/receiver/receiverhelper") +} + +// TelemetryBuilder provides an interface for components to report telemetry +// as defined in metadata and user config. +type TelemetryBuilder struct { + ReceiverAcceptedLogRecords metric.Int64Counter + ReceiverAcceptedMetricPoints metric.Int64Counter + ReceiverAcceptedSpans metric.Int64Counter + ReceiverRefusedLogRecords metric.Int64Counter + ReceiverRefusedMetricPoints metric.Int64Counter + ReceiverRefusedSpans metric.Int64Counter +} + +// telemetryBuilderOption applies changes to default builder. +type telemetryBuilderOption func(*TelemetryBuilder) + +// 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{} + var err, errs error + meter := Meter(settings) + builder.ReceiverAcceptedLogRecords, err = meter.Int64Counter( + "receiver_accepted_log_records", + metric.WithDescription("Number of log records successfully pushed into the pipeline."), + metric.WithUnit("1"), + ) + errs = errors.Join(errs, err) + builder.ReceiverAcceptedMetricPoints, err = meter.Int64Counter( + "receiver_accepted_metric_points", + metric.WithDescription("Number of metric points successfully pushed into the pipeline."), + metric.WithUnit("1"), + ) + errs = errors.Join(errs, err) + builder.ReceiverAcceptedSpans, err = meter.Int64Counter( + "receiver_accepted_spans", + metric.WithDescription("Number of spans successfully pushed into the pipeline."), + metric.WithUnit("1"), + ) + errs = errors.Join(errs, err) + builder.ReceiverRefusedLogRecords, err = meter.Int64Counter( + "receiver_refused_log_records", + metric.WithDescription("Number of log records that could not be pushed into the pipeline."), + metric.WithUnit("1"), + ) + errs = errors.Join(errs, err) + builder.ReceiverRefusedMetricPoints, err = meter.Int64Counter( + "receiver_refused_metric_points", + metric.WithDescription("Number of metric points that could not be pushed into the pipeline."), + metric.WithUnit("1"), + ) + errs = errors.Join(errs, err) + builder.ReceiverRefusedSpans, err = meter.Int64Counter( + "receiver_refused_spans", + metric.WithDescription("Number of spans that could not be pushed into the pipeline."), + metric.WithUnit("1"), + ) + errs = errors.Join(errs, err) + return &builder, errs +} diff --git a/receiver/receiverhelper/internal/metadata/generated_telemetry_test.go b/receiver/receiverhelper/internal/metadata/generated_telemetry_test.go new file mode 100644 index 00000000000..842c86838aa --- /dev/null +++ b/receiver/receiverhelper/internal/metadata/generated_telemetry_test.go @@ -0,0 +1,63 @@ +// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "testing" + + "github.com/stretchr/testify/require" + "go.opentelemetry.io/otel/metric" + embeddedmetric "go.opentelemetry.io/otel/metric/embedded" + noopmetric "go.opentelemetry.io/otel/metric/noop" + "go.opentelemetry.io/otel/trace" + embeddedtrace "go.opentelemetry.io/otel/trace/embedded" + nooptrace "go.opentelemetry.io/otel/trace/noop" + + "go.opentelemetry.io/collector/component" +) + +type mockMeter struct { + noopmetric.Meter + name string +} +type mockMeterProvider struct { + embeddedmetric.MeterProvider +} + +func (m mockMeterProvider) Meter(name string, opts ...metric.MeterOption) metric.Meter { + return mockMeter{name: name} +} + +type mockTracer struct { + nooptrace.Tracer + name string +} + +type mockTracerProvider struct { + embeddedtrace.TracerProvider +} + +func (m mockTracerProvider) Tracer(name string, opts ...trace.TracerOption) trace.Tracer { + return mockTracer{name: name} +} + +func TestProviders(t *testing.T) { + set := component.TelemetrySettings{ + MeterProvider: mockMeterProvider{}, + TracerProvider: mockTracerProvider{}, + } + + meter := Meter(set) + if m, ok := meter.(mockMeter); ok { + require.Equal(t, "go.opentelemetry.io/collector/receiver/receiverhelper", m.name) + } else { + require.Fail(t, "returned Meter not mockMeter") + } + + tracer := Tracer(set) + if m, ok := tracer.(mockTracer); ok { + require.Equal(t, "go.opentelemetry.io/collector/receiver/receiverhelper", m.name) + } else { + require.Fail(t, "returned Meter not mockTracer") + } +} diff --git a/receiver/receiverhelper/metadata.yaml b/receiver/receiverhelper/metadata.yaml new file mode 100644 index 00000000000..9d1fe3c4436 --- /dev/null +++ b/receiver/receiverhelper/metadata.yaml @@ -0,0 +1,57 @@ +type: receiverhelper + +status: + class: pkg + stability: + beta: [traces, metrics, logs] + distributions: [core, contrib] + +telemetry: + metrics: + receiver_accepted_spans: + enabled: true + description: Number of spans successfully pushed into the pipeline. + unit: 1 + sum: + value_type: int + monotonic: true + + receiver_refused_spans: + enabled: true + description: Number of spans that could not be pushed into the pipeline. + unit: 1 + sum: + value_type: int + monotonic: true + + receiver_accepted_metric_points: + enabled: true + description: Number of metric points successfully pushed into the pipeline. + unit: 1 + sum: + value_type: int + monotonic: true + + receiver_refused_metric_points: + enabled: true + description: Number of metric points that could not be pushed into the pipeline. + unit: 1 + sum: + value_type: int + monotonic: true + + receiver_accepted_log_records: + enabled: true + description: Number of log records successfully pushed into the pipeline. + unit: 1 + sum: + value_type: int + monotonic: true + + receiver_refused_log_records: + enabled: true + description: Number of log records that could not be pushed into the pipeline. + unit: 1 + sum: + value_type: int + monotonic: true \ No newline at end of file diff --git a/receiver/receiverhelper/obsreport.go b/receiver/receiverhelper/obsreport.go index ae1422b68f1..18ff7556454 100644 --- a/receiver/receiverhelper/obsreport.go +++ b/receiver/receiverhelper/obsreport.go @@ -1,6 +1,8 @@ // Copyright The OpenTelemetry Authors // SPDX-License-Identifier: Apache-2.0 +//go:generate mdatagen metadata.yaml + package receiverhelper // import "go.opentelemetry.io/collector/receiver/receiverhelper" import ( @@ -10,17 +12,13 @@ import ( "go.opentelemetry.io/otel/codes" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/trace" - "go.uber.org/multierr" "go.uber.org/zap" "go.opentelemetry.io/collector/component" "go.opentelemetry.io/collector/config/configtelemetry" "go.opentelemetry.io/collector/internal/obsreportconfig/obsmetrics" "go.opentelemetry.io/collector/receiver" -) - -const ( - receiverScope = obsmetrics.Scope + obsmetrics.SpanNameSep + obsmetrics.ReceiverKey + "go.opentelemetry.io/collector/receiver/receiverhelper/internal/metadata" ) // ObsReport is a helper to add observability to a receiver. @@ -30,17 +28,10 @@ type ObsReport struct { transport string longLivedCtx bool tracer trace.Tracer - meter metric.Meter logger *zap.Logger - otelAttrs []attribute.KeyValue - - acceptedSpansCounter metric.Int64Counter - refusedSpansCounter metric.Int64Counter - acceptedMetricPointsCounter metric.Int64Counter - refusedMetricPointsCounter metric.Int64Counter - acceptedLogRecordsCounter metric.Int64Counter - refusedLogRecordsCounter metric.Int64Counter + otelAttrs []attribute.KeyValue + telemetryBuilder *metadata.TelemetryBuilder } // ObsReportSettings are settings for creating an ObsReport. @@ -62,74 +53,24 @@ func NewObsReport(cfg ObsReportSettings) (*ObsReport, error) { } func newReceiver(cfg ObsReportSettings) (*ObsReport, error) { - rec := &ObsReport{ + telemetryBuilder, err := metadata.NewTelemetryBuilder(cfg.ReceiverCreateSettings.TelemetrySettings) + if err != nil { + return nil, err + } + return &ObsReport{ level: cfg.ReceiverCreateSettings.TelemetrySettings.MetricsLevel, spanNamePrefix: obsmetrics.ReceiverPrefix + cfg.ReceiverID.String(), transport: cfg.Transport, longLivedCtx: cfg.LongLivedCtx, tracer: cfg.ReceiverCreateSettings.TracerProvider.Tracer(cfg.ReceiverID.String()), - meter: cfg.ReceiverCreateSettings.MeterProvider.Meter(receiverScope), logger: cfg.ReceiverCreateSettings.Logger, otelAttrs: []attribute.KeyValue{ attribute.String(obsmetrics.ReceiverKey, cfg.ReceiverID.String()), attribute.String(obsmetrics.TransportKey, cfg.Transport), }, - } - - if err := rec.createOtelMetrics(); err != nil { - return nil, err - } - - return rec, nil -} - -func (rec *ObsReport) createOtelMetrics() error { - var errors, err error - - rec.acceptedSpansCounter, err = rec.meter.Int64Counter( - obsmetrics.ReceiverMetricPrefix+obsmetrics.AcceptedSpansKey, - metric.WithDescription("Number of spans successfully pushed into the pipeline."), - metric.WithUnit("1"), - ) - errors = multierr.Append(errors, err) - - rec.refusedSpansCounter, err = rec.meter.Int64Counter( - obsmetrics.ReceiverMetricPrefix+obsmetrics.RefusedSpansKey, - metric.WithDescription("Number of spans that could not be pushed into the pipeline."), - metric.WithUnit("1"), - ) - errors = multierr.Append(errors, err) - - rec.acceptedMetricPointsCounter, err = rec.meter.Int64Counter( - obsmetrics.ReceiverMetricPrefix+obsmetrics.AcceptedMetricPointsKey, - metric.WithDescription("Number of metric points successfully pushed into the pipeline."), - metric.WithUnit("1"), - ) - errors = multierr.Append(errors, err) - - rec.refusedMetricPointsCounter, err = rec.meter.Int64Counter( - obsmetrics.ReceiverMetricPrefix+obsmetrics.RefusedMetricPointsKey, - metric.WithDescription("Number of metric points that could not be pushed into the pipeline."), - metric.WithUnit("1"), - ) - errors = multierr.Append(errors, err) - - rec.acceptedLogRecordsCounter, err = rec.meter.Int64Counter( - obsmetrics.ReceiverMetricPrefix+obsmetrics.AcceptedLogRecordsKey, - metric.WithDescription("Number of log records successfully pushed into the pipeline."), - metric.WithUnit("1"), - ) - errors = multierr.Append(errors, err) - - rec.refusedLogRecordsCounter, err = rec.meter.Int64Counter( - obsmetrics.ReceiverMetricPrefix+obsmetrics.RefusedLogRecordsKey, - metric.WithDescription("Number of log records that could not be pushed into the pipeline."), - metric.WithUnit("1"), - ) - errors = multierr.Append(errors, err) - - return errors + telemetryBuilder: telemetryBuilder, + }, nil } // StartTracesOp is called when a request is received from a client. @@ -263,14 +204,14 @@ func (rec *ObsReport) recordMetrics(receiverCtx context.Context, dataType compon var acceptedMeasure, refusedMeasure metric.Int64Counter switch dataType { case component.DataTypeTraces: - acceptedMeasure = rec.acceptedSpansCounter - refusedMeasure = rec.refusedSpansCounter + acceptedMeasure = rec.telemetryBuilder.ReceiverAcceptedSpans + refusedMeasure = rec.telemetryBuilder.ReceiverRefusedSpans case component.DataTypeMetrics: - acceptedMeasure = rec.acceptedMetricPointsCounter - refusedMeasure = rec.refusedMetricPointsCounter + acceptedMeasure = rec.telemetryBuilder.ReceiverAcceptedMetricPoints + refusedMeasure = rec.telemetryBuilder.ReceiverRefusedMetricPoints case component.DataTypeLogs: - acceptedMeasure = rec.acceptedLogRecordsCounter - refusedMeasure = rec.refusedLogRecordsCounter + acceptedMeasure = rec.telemetryBuilder.ReceiverAcceptedLogRecords + refusedMeasure = rec.telemetryBuilder.ReceiverRefusedLogRecords } acceptedMeasure.Add(receiverCtx, int64(numAccepted), metric.WithAttributes(rec.otelAttrs...))