1
0
mirror of https://github.com/open-telemetry/opentelemetry-go.git synced 2026-06-03 18:35:08 +02:00

prometheus exporter ignores metrics from the Prometheus bridge (#7688)

Related to
https://github.com/open-telemetry/opentelemetry-go/issues/7686.

This makes the Prometheus exporter ignore all metrics from the
Prometheus bridge. This is almost certainly a misconfiguration, but may
happen when using autoexport or other packages that automatically
install the bridge.
This commit is contained in:
David Ashpole
2025-12-09 13:50:55 -05:00
committed by GitHub
parent 18863cac73
commit bfbfdf9d53
6 changed files with 76 additions and 3 deletions
+5
View File
@@ -8,6 +8,11 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
## [Unreleased]
### Changed
- `Exporter` in `go.opentelemetry.io/otel/exporter/prometheus` ignores metrics with the scope `go.opentelemetry.io/contrib/bridges/prometheus`.
This prevents scrape failures when the Prometheus exporter is misconfigured to get data from the Prometheus bridge. (#7688)
<!-- Released section -->
<!-- Don't change this section unless doing release -->
+4
View File
@@ -4,4 +4,8 @@
// Package prometheus provides a Prometheus Exporter that converts
// OTLP metrics into the Prometheus exposition format and implements
// prometheus.Collector to provide a handler for these metrics.
//
// The Prometheus exporter ignores metrics from the Prometheus bridge. To
// export these metrics, simply register them directly with the Prometheus
// Handler.
package prometheus // import "go.opentelemetry.io/otel/exporters/prometheus"
+6 -3
View File
@@ -7,7 +7,10 @@ import "errors"
// Sentinel errors for consistent error checks in tests.
var (
errInvalidMetricType = errors.New("invalid metric type")
errInvalidMetric = errors.New("invalid metric")
errEHScaleBelowMin = errors.New("exponential histogram scale below minimum supported")
errInvalidMetricType = errors.New("invalid metric type")
errInvalidMetric = errors.New("invalid metric")
errEHScaleBelowMin = errors.New("exponential histogram scale below minimum supported")
errBridgeNotSupported = errors.New(
"metrics from the prometheus bridge are not supported in the prometheus exporter, and will be dropped",
)
)
+13
View File
@@ -35,6 +35,11 @@ const (
scopeNameLabel = scopeLabelPrefix + "name"
scopeVersionLabel = scopeLabelPrefix + "version"
scopeSchemaLabel = scopeLabelPrefix + "schema_url"
// metrics from the prometehus bridge are ignored because this produces
// errors. Users should directly register prometheus metrics with the
// Registerer, rather than round-tripping them through the bridge and
// exporter.
bridgeScopeName = "go.opentelemetry.io/contrib/bridges/prometheus"
)
var metricsPool = sync.Pool{
@@ -96,6 +101,8 @@ type collector struct {
unitNamer otlptranslator.UnitNamer
inst *observ.Instrumentation
bridgeErrorOnce sync.Once
}
// New returns a Prometheus Exporter.
@@ -229,6 +236,12 @@ func (c *collector) Collect(ch chan<- prometheus.Metric) {
}
for j, scopeMetrics := range metrics.ScopeMetrics {
if scopeMetrics.Scope.Name == bridgeScopeName {
c.bridgeErrorOnce.Do(func() {
otel.Handle(errBridgeNotSupported)
})
continue
}
n := len(c.resourceKeyVals.keys) + 2 // resource attrs + scope name + scope version
kv := keyVals{
keys: make([]string, 0, n),
+45
View File
@@ -797,6 +797,51 @@ func TestMultiScopes(t *testing.T) {
require.NoError(t, err)
}
func TestBridgeScopeIgnored(t *testing.T) {
var handledError error
eh := otel.ErrorHandlerFunc(func(e error) { handledError = errors.Join(handledError, e) })
otel.SetErrorHandler(eh)
ctx := t.Context()
registry := prometheus.NewRegistry()
exporter, err := New(
WithTranslationStrategy(otlptranslator.UnderscoreEscapingWithSuffixes),
WithRegisterer(registry),
)
require.NoError(t, err)
res, err := resource.New(ctx,
// always specify service.name because the default depends on the running OS
resource.WithAttributes(semconv.ServiceName("prometheus_test")),
// Overwrite the semconv.TelemetrySDKVersionKey value so we don't need to update every version
resource.WithAttributes(semconv.TelemetrySDKVersion("latest")),
)
require.NoError(t, err)
res, err = resource.Merge(resource.Default(), res)
require.NoError(t, err)
provider := metric.NewMeterProvider(
metric.WithReader(exporter),
metric.WithResource(res),
)
fooCounter, err := provider.Meter(bridgeScopeName, otelmetric.WithInstrumentationVersion("v0.1.0")).
Int64Counter(
"foo",
otelmetric.WithUnit("s"),
otelmetric.WithDescription("meter foo counter"))
assert.NoError(t, err)
fooCounter.Add(ctx, 100, otelmetric.WithAttributes(attribute.String("type", "foo")))
file, err := os.Open("testdata/just_target_info.txt")
require.NoError(t, err)
t.Cleanup(func() { require.NoError(t, file.Close()) })
err = testutil.GatherAndCompare(registry, file)
require.NoError(t, err)
require.ErrorIs(t, handledError, errBridgeNotSupported)
}
func TestDuplicateMetrics(t *testing.T) {
ab := attribute.NewSet(attribute.String("A", "B"))
withAB := otelmetric.WithAttributeSet(ab)
+3
View File
@@ -0,0 +1,3 @@
# HELP target_info Target metadata
# TYPE target_info gauge
target_info{service_name="prometheus_test",telemetry_sdk_language="go",telemetry_sdk_name="opentelemetry",telemetry_sdk_version="latest"} 1