diff --git a/cmd/mdatagen/main_test.go b/cmd/mdatagen/main_test.go index f13693dab32..26f6648babf 100644 --- a/cmd/mdatagen/main_test.go +++ b/cmd/mdatagen/main_test.go @@ -15,6 +15,7 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/pdata/pmetric" ) func TestRunContents(t *testing.T) { @@ -610,6 +611,127 @@ func Meter(settings component.TelemetrySettings) metric.Meter { func Tracer(settings component.TelemetrySettings) trace.Tracer { return settings.TracerProvider.Tracer("") } +`, + }, + { + name: "foo component with internal telemetry", + md: metadata{ + Type: "foo", + Status: &Status{ + Stability: map[component.StabilityLevel][]string{ + component.StabilityLevelAlpha: {"metrics"}, + }, + Distributions: []string{"contrib"}, + Class: "receiver", + }, + Telemetry: telemetry{ + Metrics: map[metricName]metric{ + "metric1": { + Enabled: true, + Sum: &sum{ + Async: false, + Mono: Mono{true}, + MetricValueType: MetricValueType{ValueType: pmetric.NumberDataPointValueTypeInt}, + }, + }, + "metric2": { + Enabled: true, + Sum: &sum{ + Async: true, + Mono: Mono{false}, + MetricValueType: MetricValueType{ValueType: pmetric.NumberDataPointValueTypeDouble}, + }, + }, + }, + }, + }, + expected: `// Code generated by mdatagen. DO NOT EDIT. + +package metadata + +import ( + "context" + "errors" + + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/metric/noop" + "go.opentelemetry.io/otel/trace" + + "go.opentelemetry.io/collector/component" + "go.opentelemetry.io/collector/config/configtelemetry" +) + +func Meter(settings component.TelemetrySettings) metric.Meter { + return settings.MeterProvider.Meter("") +} + +func Tracer(settings component.TelemetrySettings) trace.Tracer { + return settings.TracerProvider.Tracer("") +} + +// TelemetryBuilder provides an interface for components to report telemetry +// as defined in metadata and user config. +type TelemetryBuilder struct { + meter metric.Meter + Metric1 metric.Int64Counter + Metric2 metric.Float64ObservableUpDownCounter + observeMetric2 func(context.Context, metric.Observer) error + level configtelemetry.Level +} + +// 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 + } +} + +// WithMetric2Callback sets callback for observable Metric2 metric. +func WithMetric2Callback(cb func() float64, opts ...metric.ObserveOption) telemetryBuilderOption { + return func(builder *TelemetryBuilder) { + builder.observeMetric2 = func(_ context.Context, o metric.Observer) error { + o.ObserveFloat64(builder.Metric2, cb(), opts...) + return nil + } + } +} + +// 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} + for _, op := range options { + op(&builder) + } + var err, errs error + if builder.level >= configtelemetry.LevelBasic { + builder.meter = Meter(settings) + } else { + builder.meter = noop.Meter{} + } + builder.Metric1, err = builder.meter.Int64Counter( + "otelcol_metric1", + metric.WithDescription(""), + metric.WithUnit(""), + ) + errs = errors.Join(errs, err) + builder.Metric2, err = builder.meter.Float64ObservableUpDownCounter( + "otelcol_metric2", + metric.WithDescription(""), + metric.WithUnit(""), + ) + errs = errors.Join(errs, err) + _, err = builder.meter.RegisterCallback(builder.observeMetric2, builder.Metric2) + errs = errors.Join(errs, err) + return &builder, errs +} + +func (b *TelemetryBuilder) RecordMetric1(ctx context.Context, val int64, opts ...metric.AddOption) { + b.Metric1.Add(ctx, val, opts...) +} `, }, }