opentelemetry-specification
opentelemetry-specification copied to clipboard
Handle conflicting metric descriptions and types in prometheus exporter
With #2703 instrumentation scope name and version are included as attributes in the prometheus exporter, which helps to accommodate OpenTelemetry metric's ability to have instruments with the same name under different scopes.
However, these instruments can still have conflicting types and descriptions, which present problems in prometheus scrapers as discussed in open-telemetry/opentelemetry-java#4834.
The following scenario illustrates the problem:
- Scope name:
scope1, instrument name:my_instrument, instrument type:counter, description:description1 - Scope name:
scope2, instrument name:my_instrument, instrument type:gauge, description:description2
As of #2703, this will be serialized in the prometheus exporter as follows:
# HELP my_instrument description1
# TYPE my_instrument counter
my_instrument{otel_scope_name="scope1"} 1
# HELP my_instrument description2
# TYPE my_instrument gauge
my_instrument{otel_scope_name="scope2"} 1
One possible solution is to detect conflicting descriptions / types in the prometheus exporter and log an error and / or skip the offending metric. Views can be used to change the name of one of the offending instruments to avoid the conflict.
+1
OpenMetrics MetricFamily names (i.e. what type, description, unit, are associated with) MUST be unique within the metrics served on an endpoint:
Each MetricFamily name MUST be unique.
Here is what I'm thinking:
- This is not a unique problem in the exporter, we also have the same challenge when the Collector is trying to convert OTLP to Prometheus, and this is something @dashpole was trying to cover here
- For exporter, one approach is to make sure
SDK -> PrometheusExporter -> PrometheusandSDK -> OTLP Exporter -> Collector -> PromethuesExporter -> Prometheuswill end up having the same result, which sounds nice but I don't feel it is necessary. - The alternative approach is to be a bit conservative and only provide a subset of features, one extreme case is "if the same name is used by multiple streams, the behavior is undefined (it could cause Prometheus to completely drop the entire scraped results), and the expectation is that the user will use View API to rename things properly to avoid conflicts".
I would vote for something simple/conservative, rather than trying to introduce a perfect escape rule/sequence.