feat(outputs.opentelemetry): Support dot-separated OpenTelemetry metric names#18680
Conversation
|
Download PR build artifacts for linux_amd64.tar.gz, darwin_arm64.tar.gz, and windows_amd64.zip. 📦 Click here to get additional PR build artifactsArtifact URLs |
|
@srebhan Could you take a look at this PR? |
| if o.MetricNameFormat == "" { | ||
| o.MetricNameFormat = defaultMetricNameFormat | ||
| } | ||
| switch o.MetricNameFormat { | ||
| case "prometheus", "otel": |
There was a problem hiding this comment.
| if o.MetricNameFormat == "" { | |
| o.MetricNameFormat = defaultMetricNameFormat | |
| } | |
| switch o.MetricNameFormat { | |
| case "prometheus", "otel": | |
| switch o.MetricNameFormat { | |
| case "": | |
| o.MetricNameFormat = "prometheus" | |
| case "prometheus", "otel": |
| defaultServiceAddress = "localhost:4317" | ||
| defaultTimeout = config.Duration(5 * time.Second) | ||
| defaultCompression = "gzip" | ||
| defaultMetricNameFormat = "prometheus" |
There was a problem hiding this comment.
Please do not add constants for this! There is no benefit really!
| ServiceAddress: defaultServiceAddress, | ||
| Timeout: defaultTimeout, | ||
| Compression: defaultCompression, | ||
| MetricNameFormat: defaultMetricNameFormat, |
| // Only check metadata if it exists (for tests that provide headers) | ||
| ctxMetadata, ok := metadata.FromIncomingContext(ctx) | ||
| require.Equal(m.t, []string{"header1"}, ctxMetadata.Get("test")) | ||
| require.True(m.t, ok) | ||
| if ok { | ||
| if testHeader := ctxMetadata.Get("test"); len(testHeader) > 0 { | ||
| require.Equal(m.t, []string{"header1"}, testHeader) | ||
| } | ||
| } |
| return pmetricotlp.NewExportResponse(), nil | ||
| } | ||
|
|
||
| func TestOpenTelemetryMetricNameFormatPrometheus(t *testing.T) { |
There was a problem hiding this comment.
How about
| func TestOpenTelemetryMetricNameFormatPrometheus(t *testing.T) { | |
| func TestNameFormatPrometheus(t *testing.T) { |
| got := m.GotMetrics() | ||
| require.Equal(t, 1, got.ResourceMetrics().Len()) | ||
| require.Equal(t, 1, got.ResourceMetrics().At(0).ScopeMetrics().Len()) | ||
| require.Equal(t, 1, got.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().Len()) | ||
| require.Equal(t, "http_server_duration", got.ResourceMetrics().At(0).ScopeMetrics().At(0).Metrics().At(0).Name()) |
There was a problem hiding this comment.
All other tests compare the JSON representation of the metric. Can we please stick to this? Same for the other tests below.
| metricName := o.transformMetricName(metric.Name()) | ||
| err := batch.AddPoint(metricName, metric.Tags(), metric.Fields(), metric.Time(), vType) |
There was a problem hiding this comment.
Please fold the code in here
| metricName := o.transformMetricName(metric.Name()) | |
| err := batch.AddPoint(metricName, metric.Tags(), metric.Fields(), metric.Time(), vType) | |
| // Transform the metric name if required | |
| name := metric.Name() | |
| switch o.MetricNameFormat | |
| case "prometheus": | |
| // Prometheus doesn't like dots | |
| name = strings.ReplaceAll(name, ".", "_") | |
| } | |
| err := batch.AddPoint(name, metric.Tags(), metric.Fields(), metric.Time(), vType) |
| if o.MetricNameFormat == "" { | ||
| o.MetricNameFormat = defaultMetricNameFormat | ||
| } |
There was a problem hiding this comment.
Doesn't this change the existing behavior? In the existing code we do not replace anything in the metric name, do we?
| ## Override the default (prometheus) metric name format | ||
| ## prometheus: converts dots to underscores (default, Prometheus-compatible) | ||
| ## otel: preserves dot-separated names (OpenTelemetry semantic conventions) |
There was a problem hiding this comment.
Please be brief, defaults are documented in the option!
| ## Override the default (prometheus) metric name format | |
| ## prometheus: converts dots to underscores (default, Prometheus-compatible) | |
| ## otel: preserves dot-separated names (OpenTelemetry semantic conventions) | |
| ## Transform metric names according to the given format, available options: | |
| ## prometheus -- converts dots to underscores | |
| ## otel -- keep metric names as-is |
| ## Override the default (prometheus) metric name format | ||
| ## prometheus: converts dots to underscores (default, Prometheus-compatible) | ||
| ## otel: preserves dot-separated names (OpenTelemetry semantic conventions) | ||
| # metric_name_format = "prometheus" |
There was a problem hiding this comment.
In the code before this PR, I don't see where we replace dots with underscores, so you are changing the default behavior and break everyone using this plugin. Am I missing anything?
Summary
This is a reopened PR #18252 which was closed due to inactivity. I've personally reviewed the changes in this one and can answer any questions or make changes which may be requested during the review process.
Summary from original PR:
This PR adds support for preserving dot-separated OpenTelemetry metric names in the OpenTelemetry output plugin, addressing issue #18251.
Added a new metric_name_format configuration option that allows users to choose between:
This PR adds support for preserving dot-separated OpenTelemetry metric names in the OpenTelemetry output plugin
Checklist
Related issues
resolves #18251