open-telemetry / opentelemetry-python

OpenTelemetry Python API and SDK
https://opentelemetry.io
Apache License 2.0
1.66k stars 569 forks source link

Prometheus exporter handles instrumentation scope and prevents collisions #3072

Open dashpole opened 1 year ago

dashpole commented 1 year ago

Now that https://github.com/open-telemetry/opentelemetry-specification/pull/2703 is released, we can update the prometheus exporter to make use of OpenTelemetry scope, particularly for reducing collisions between metrics with the same name.

Describe the solution you'd like

There are a few components:

Note that the exporter SHOULD do the above by default, but may allow disabling the behavior.

dashpole commented 1 year ago

One additional consideration: The prometheus spec says:

All lines for a given metric must be provided as one single group, with the optional HELP and TYPE lines first (in no particular order). Beyond that, reproducible sorting in repeated expositions is preferred but not required, i.e. do not sort if the computational cost is prohibitive.

When name collisions between two metrics occur, and we handle that by combining the two metic groups (e.g. adopting one of the two descriptions), we have to make sure the metrics points for a given metric family are grouped together. For example, we might produce these metrics today, if we had a foo metric in two different scopes:

# TYPE foo gauge
# HELP foo help text a
foo{} 1
# TYPE bar gauge
# HELP bar another useless gauge
bar{} 1
# TYPE foo gauge
# HELP foo help text b
foo{} 1

This would not be valid per the prometheus spec. If we adopted the spec for instrumentation scope labels, and prevented duplicate type and descriptions, we would get:

# TYPE foo gauge
# HELP foo help text a
foo{otel_scope_name ="scope1", otel_scope_version ="1.2.3"} 1
# TYPE bar gauge
# HELP bar another useless gauge
bar{otel_scope_name ="scope1", otel_scope_version ="1.2.3"} 1
foo{otel_scope_name ="scope2", otel_scope_version ="1.2.3"} 1

But we still need to make sure the resulting metric lines are grouped by metric name like this:

# TYPE foo gauge
# HELP foo help text a
foo{otel_scope_name ="scope1", otel_scope_version ="1.2.3"} 1
foo{otel_scope_name ="scope2", otel_scope_version ="1.2.3"} 1
# TYPE bar gauge
# HELP bar another useless gauge
bar{otel_scope_name ="scope1", otel_scope_version ="1.2.3"} 1
XuanWang-Amos commented 1 month ago

Hi @dashpole, has this feature been implemented yet?

dashpole commented 1 month ago

not that i'm aware of

XuanWang-Amos commented 1 month ago

Thanks for the reply, is there any plans to implement this? I'm from gRPC team and working on Python OpenTelemetry integration, without those labels Python will fail our interoperability tests.