Skip to content

Add OpenTelemetry metrics#4230

Open
mmatczuk wants to merge 3 commits intomainfrom
mmt/otel_metrics
Open

Add OpenTelemetry metrics#4230
mmatczuk wants to merge 3 commits intomainfrom
mmt/otel_metrics

Conversation

@mmatczuk
Copy link
Copy Markdown
Contributor

@mmatczuk mmatczuk commented Apr 9, 2026

No description provided.

Comment on lines +12 to +33
"context"
"fmt"
"net/http"
"sync/atomic"
"time"

"go.opentelemetry.io/otel/attribute"
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc"
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
"go.opentelemetry.io/otel/metric"
metricsdk "go.opentelemetry.io/otel/sdk/metric"

"github.com/redpanda-data/benthos/v4/public/service"
)

func otlpMetricsSpec() *service.ConfigSpec {
return service.NewConfigSpec().
Summary("Send metrics to an https://opentelemetry.io/docs/collector/[Open Telemetry collector^].").
Fields(
service.NewStringField("service").
Default("benthos").
Description("The name of the service in metrics."),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Field names should be defined as constants with a component-prefix convention (e.g., omFieldService, omFieldHTTP, etc.) rather than used as string literals. This applies to "service" here and in newOtlpMetrics ("service", "http", "grpc", "tags").

See project Go patterns:

Field names are always defined as constants with a component-prefix convention <componentAbbrev>Field<Name>
Don't put field names as string literals. Do use constants


func newOtlpMetrics(conf *service.ParsedConfig, _ *service.Logger) (*otlpMetrics, error) {
serviceName, err := conf.FieldString("service")
if err != nil {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 30*time.Second timeout is a magic number and a hardcoded duration. Per project patterns, it should be a named constant at minimum, and ideally exposed as a YAML-configurable field.

See project Go patterns:

Name all numeric constants. Every literal number in logic must have a clear meaning through a named constant or variable.

Every time-related value (timeouts, backoffs, intervals, retry delays) must be exposed as a YAML-configurable field. Do not hardcode durations.


func TestMetricsCounter(t *testing.T) {
m := newTestMetrics(t)
t.Cleanup(func() { require.NoError(t, m.Close(t.Context())) })
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

t.Context() returns a canceled context during t.Cleanup() execution, which will cause m.Close() to fail if the OTel provider's Shutdown respects the context. Use context.Background() instead. This applies to all 7 t.Cleanup calls in this file.

See project test patterns:

Use t.Context() for test contexts. Exception: in t.Cleanup() functions, use context.Background() because t.Context() is already canceled during cleanup.

@claude
Copy link
Copy Markdown

claude bot commented Apr 9, 2026

Commits
LGTM

Review
The refactoring to extract shared collector parsing logic and the new metrics exporter are well-structured. Three issues found in the new metrics code:

  1. Field name string literals (metrics_otlp.go#L12-L33): Field names like "service", "http", "grpc", "tags" should be defined as constants with the component-prefix convention per project patterns.
  2. Hardcoded timeout (metrics_otlp.go#L54): 30*time.Second is a magic number and a non-configurable duration, violating two project patterns (named constants + configurable time parameters).
  3. t.Context() in t.Cleanup() (metrics_otlp_test.go#L56): All 7 cleanup functions use t.Context() which is already canceled during cleanup; should use context.Background() per project test patterns.

mmatczuk added 3 commits April 9, 2026 15:15
- Extracted common collector parsing logic to `collectorListFields` and
  `parseCollectors`.
- Simplified resource creation with `newResource` helper.
- Renamed `oltp` to `otlpTracer` for clarity.
- Updated tests to use new spec and config parsing functions.
Implement new metrics exporter for OpenTelemetry collectors,
supporting both gRPC and HTTP protocols.
@claude
Copy link
Copy Markdown

claude bot commented Apr 9, 2026

Commits
LGTM

Review
Clean refactoring that extracts shared OTLP collector config/parsing into otlp.go, adds a new metrics exporter following the same patterns as the existing tracer, and separates docs into their own commit. Unit tests cover config parsing, all instrument types (counter, timer, gauge) with and without labels, and edge cases in the zipAttrs helper.

LGTM

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants