Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle instrumentation scope in the Prometheus conversion spec #2422

Closed

Conversation

dashpole
Copy link
Contributor

@dashpole dashpole commented Mar 17, 2022

Related: #1906

Background

OpenMetrics Naming+Namespacing

Changes

This adds "short_name" to the instrumentation scope, which would be an optional, single-word name for the scope. If present, it would be used as the metric prefix in Prometheus exporters. In prometheus receivers, the opentelemetry_instrumentation_scope metric would identify prefixes that can be removed from metrics, and used to reconstruct the Instrumentation scope in OTLP.

Alternatives:

  • Turn the library name into the single-word metric prefix. E.g. goopentelemetryiocontribinstrumentationnethttpotelhttp_http_server_duration
    • Downside: This is ugly
  • Add it as a label to all metrics within the scope: {"instrumentation_scope": "go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp"}
    • Downside: This isn't how OpenMetrics is designed to namespace metrics. Removing this later would be breaking for users.

cc @jmacd @Aneurysm9 @jsuereth

@dashpole dashpole force-pushed the prom_instrumentation_scope branch from abb65d2 to 0a5973f Compare March 17, 2022 17:08
@dashpole dashpole marked this pull request as ready for review March 17, 2022 17:12
@dashpole dashpole requested review from a team March 17, 2022 17:12
Comment on lines 1189 to 1190
Instrumentation Scope MUST be left unset for metrics scraped from Prometheus
endpoints.
Copy link
Contributor

Choose a reason for hiding this comment

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

If the opentelemetry_instrumentation_scope info metric is present that that not be used for the instrumentation scope?

Copy link
Contributor Author

@dashpole dashpole Mar 22, 2022

Choose a reason for hiding this comment

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

Thats correct. It remains a separate metric stream to transmit that a given instrumentation library was used, but it doesn't allow you to figure out which metrics it applies to. I'm not sure it makes much sense, though, without the "short_name" in instrumentation scope. If we had that, then we could reconstruct the Instrumentation Scope here.

Maybe I should just skip this intermediary specification step, and just propose the "short_name" + round-tripping through prometheus...

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe I should just skip this intermediary specification step, and just propose the "short_name" + round-tripping through prometheus...

I'd be interested to hear what other think, but that sounds good to me.

@jmacd
Copy link
Contributor

jmacd commented Mar 23, 2022

We should be careful to call the OpenMetrics "metric namespace" an equivalent of OTel's instrumentation library. I don't think this is completely true, see below.

Proposal for round-tripping Instrumentation Scope

I would like to see a treatment of instrumentation scope that could preserve the information for an OTel SDK exporting Prometheus data, which means a Prometheus scrape ideally would produce the same metrics as the SDK would have pushed. I think this is possible.

I've studied the OpenMetrics guidance on target info,

https://github.com/OpenObservability/OpenMetrics/blob/main/specification/OpenMetrics.md#supporting-target-metadata-in-both-push-based-and-pull-based-systems

and consider instrumentation scope information to be in a similar category. Suppose we use an OM info metric:

# TYPE otel_scope_info info
# HELP otel_scope_info Instrumentation scope metadata
otel_scope_info{name="some.dns.name/lib",version="0.1",schema_url="standard/url"} 1

To round-trip this correctly with an OTel scraper, an OTel SDK would specifically produce one library of metrics at a time. The OM/OTel translation would infer that metrics are organized by instrumentation scope such that the most recent otel_scope_info is implicitly associated with metrics in a scoped section. OTLP data scraped from other sources would leave instrumentation scope empty, as you propose.

Argument in favor of a first-class namespace concept

OpenMetrics writes about metric namespacing "the aim is to keep to a lightweight informal approach" and has three standard instrument constructor fields: "Namespace", "Subsystem", and "Name". With two optional underscore-separated fields and the potential for "Name" itself to contain underscores, there's no way to parse an OM metric name and infer what is namespace, what is subsystem, and what is name. Given no way to distinguish these, "metric namespace" appears to be a user-level option to ensure that when the same kind of instrumentation is produced by multiple distinct instances of the same instrumentation inside a single process, the user can force them not to aggregate or display in the same queries by adding an additional prefix. This would be done as-needed when the user is aware of conflicts and has the intention to solve them using namespaces, otherwise would not be done to keep metric names short.

To illustrate when metric namespace appears to solve for an OM user, imagine an OTel SDK configured with two clients speaking to two separate Redis instances with different load patterns, different kinds of data, different purposes. You've got two instances of the Redis client, and two instances of the OTel instrumentation.

Can the user have a way to distinguish the two scopes that works for both OM and OTel? IMO the user needs a first-class namespace concept here, which is not what OTel's instrumentation scope is at this time. Adding an additional property or property list to the Instrumentation Scope message type could help, and we could extend the OM<->OTel translation rules, for example, as follows. Suppose the MeterProvider has a new method called MeterProvider.Namespace(string) returning a MeterProvider where each Meter has the associated namespace. OTLP consumers would be advised to recognize this by prefixing metrics names in the section when displayed and queried.

This is what two instrumentation scopes for the same instrumentation library would look like when scraped, using the OM metric namespace:

# TYPE otel_scope_info info
# HELP otel_scope_info Instrumentation scope metadata
otel_scope_info{name="...",version="...",schema_url="...,namespace="firstprefix_"} 1

# TYPE firstprefix_http_requests
# HELP firstprefix_http_requests Number of HTTP requests
firstprefix_http_requests{} 1000

# TYPE otel_scope_info info
# HELP otel_scope_info Instrumentation scope metadata
otel_scope_info{name="...",version="...",schema_url="...,namespace="secondprefix_"} 1

# TYPE secondprefix_http_requests
# HELP secondprefix_http_requests Number of HTTP requests
secondprefix_http_requests{} 1000

@dashpole
Copy link
Contributor Author

Unfortunately, I don't think the "Proposal for round-tripping Instrumentation Scope" complies with the OM spec: MetricFamilies MUST NOT be interleaved.

I haven't actually ever seen Namespace used to distinguish multiple instances of instrumentation--people just seem to use it as a second "subsystem" (e.g. in k8s), but maybe they were just using it wrong :). Since prom doesn't have a "View" concept, all metrics i've seen are fully named (including namespace, subsystem, etc.) by the library itself.

I think this is implied by the OM spec as well: the more public a library is the better namespaced its metric names should be implies that namespacing is performed by the library to keep it from colliding with other libraries.

So I think we are roughly on the same page, but need to figure out if the OM namespace is the equivalent of the instrumentation library, or if it is meant to be more than that.

@brian-brazil, we discussed this briefly at the prom WG yesterday. Can you help clarify the purpose of the OM namespace?

@brian-brazil
Copy link

brian-brazil commented Mar 24, 2022

Unfortunately, I don't think the "Proposal for round-tripping Instrumentation Scope" complies with the OM spec: MetricFamilies MUST NOT be interleaved.

I see no problems with the sample output. Though name and version are poor choices of label name that are highly likely to clash with something.

Can you help clarify the purpose of the OM namespace?

There's no formal concept of it in OM, as you say namespacing is performed by the library to keep it from colliding with other libraries.

@jmacd
Copy link
Contributor

jmacd commented Mar 24, 2022

Unfortunately, I don't think the "Proposal for round-tripping Instrumentation Scope" complies with the OM spec: MetricFamilies MUST NOT be interleaved.

I see. A workaround would be to namespace the otel_scope_info section divider itself.

# TYPE firstprefix_otel_scope_info info
# HELP firstprefix_otel_scope_info Instrumentation scope metadata
firstprefix_otel_scope_info{name="...",version="...",schema_url="...,namespace="firstprefix_"} 1

# TYPE firstprefix_http_requests
# HELP firstprefix_http_requests Number of HTTP requests
firstprefix_http_requests{} 1000

# TYPE secondprefix_otel_scope_info info
# HELP secondprefix_otel_scope_info Instrumentation scope metadata
secondprefix_otel_scope_info{name="...",version="...",schema_url="...,namespace="secondprefix_"} 1

# TYPE secondprefix_http_requests
# HELP secondprefix_http_requests Number of HTTP requests
secondprefix_http_requests{} 1000

@brian-brazil
Copy link

OpenMetrics writes about metric namespacing "the aim is to keep to a lightweight informal approach" and has three standard instrument constructor fields: "Namespace", "Subsystem", and "Name".

OM has no such fields or notiions, that's what some client libraries did historically and I personally now consider it a bad idea. At the least it breaks grepability of metric names.

@dashpole dashpole requested review from a team March 24, 2022 15:44
@dashpole
Copy link
Contributor Author

I updated this to propose the short_name.

@jmacd
Copy link
Contributor

jmacd commented Mar 24, 2022

This proposal from @bogdandrutu #2307 would give us a nice place to store the new "short_name" concept. I'm eager to see us add a list of arbitrary key:values to the scope, it would give us a way to distinguish two instances of the same instrumentation library which today we cannot do.

@tigrannajaryan
Copy link
Member

I'm eager to see us add a list of arbitrary key:values to the scope, it would give us a way to distinguish two instances of the same instrumentation library which today we cannot do.

+1 to this. There are other use cases for this key:value list in the scope too, such as differentiating the type of data emitted from the scopes that belong to different data domains, e.g. profiling data emitted as log records or client-side data emitted as log records needs to be differentiated so that it can be easily routed and processed differently in the backends. We don't have a good way to handle this today.

@tigrannajaryan
Copy link
Member

Given the comments about key-value lists in the Scope should the addition of ShortName be paused for now and instead we make it a semantic convention to be recorded in the key-value list?

@dashpole
Copy link
Contributor Author

Yes. I'll close this for now, and will reopen after we've introduced the key-value list.

@dashpole dashpole closed this Mar 24, 2022
tigrannajaryan added a commit to tigrannajaryan/rfcs that referenced this pull request Apr 25, 2022
There are a few reasons why Scope attributes are a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry/opentelemetry-specification#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with other primary data types: Resource, Span, Metric, LogRecord.

See additional [discussion here](open-telemetry/opentelemetry-specification#2450).
tigrannajaryan added a commit to tigrannajaryan/rfcs that referenced this pull request Apr 25, 2022
There are a few reasons why Scope attributes are a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry/opentelemetry-specification#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with other primary data types: Resource, Span, Metric, LogRecord.

See additional [discussion here](open-telemetry/opentelemetry-specification#2450).
tigrannajaryan added a commit to tigrannajaryan/rfcs that referenced this pull request Apr 25, 2022
There are a few reasons why Scope attributes are a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry/opentelemetry-specification#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with other primary data types: Resource, Span, Metric, LogRecord.

See additional [discussion here](open-telemetry/opentelemetry-specification#2450).
tigrannajaryan added a commit to tigrannajaryan/rfcs that referenced this pull request Apr 25, 2022
There are a few reasons why Scope attributes are a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry/opentelemetry-specification#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with other primary data types: Resource, Span, Metric, LogRecord.

See additional [discussion here](open-telemetry/opentelemetry-specification#2450).
tigrannajaryan added a commit to tigrannajaryan/rfcs that referenced this pull request Apr 25, 2022
There are a few reasons why adding Scope attributes are a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry/opentelemetry-specification#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with the other primary data types: Resource, Span, Metric,
  LogRecord.

See additional [discussion here](open-telemetry/opentelemetry-specification#2450).
tigrannajaryan added a commit to tigrannajaryan/rfcs that referenced this pull request Apr 25, 2022
There are a few reasons why adding Scope attributes is a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry/opentelemetry-specification#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with the other primary data types: Resource, Span, Metric,
  LogRecord.

See additional [discussion here](open-telemetry/opentelemetry-specification#2450).
tigrannajaryan added a commit to tigrannajaryan/rfcs that referenced this pull request Apr 25, 2022
There are a few reasons why adding Scope attributes is a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry/opentelemetry-specification#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with the other primary data types: Resource, Span, Metric,
  LogRecord.

See additional [discussion here](open-telemetry/opentelemetry-specification#2450).
tigrannajaryan added a commit to tigrannajaryan/rfcs that referenced this pull request Apr 25, 2022
There are a few reasons why adding Scope attributes is a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry/opentelemetry-specification#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with the other primary data types: Resource, Span, Metric,
  LogRecord.

See additional [discussion here](open-telemetry/opentelemetry-specification#2450).
tigrannajaryan added a commit to tigrannajaryan/rfcs that referenced this pull request Apr 25, 2022
There are a few reasons why adding Scope attributes is a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry/opentelemetry-specification#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with the other primary data types: Resource, Span, Metric,
  LogRecord.

See additional [discussion here](open-telemetry/opentelemetry-specification#2450).
tigrannajaryan added a commit to tigrannajaryan/rfcs that referenced this pull request Apr 25, 2022
There are a few reasons why adding Scope attributes is a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry/opentelemetry-specification#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with the other primary data types: Resource, Span, Metric,
  LogRecord.

See additional [discussion here](open-telemetry/opentelemetry-specification#2450).
tigrannajaryan added a commit to tigrannajaryan/rfcs that referenced this pull request Apr 25, 2022
There are a few reasons why adding Scope attributes is a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry/opentelemetry-specification#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with the other primary data types: Resource, Span, Metric,
  LogRecord.

See additional [discussion here](open-telemetry/opentelemetry-specification#2450).
carlosalberto pushed a commit to open-telemetry/oteps that referenced this pull request May 24, 2022
* Introduce Scope Attributes

There are a few reasons why adding Scope attributes is a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry/opentelemetry-specification#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with the other primary data types: Resource, Span, Metric,
  LogRecord.

See additional [discussion here](open-telemetry/opentelemetry-specification#2450).
@joaopgrassi
Copy link
Member

joaopgrassi commented Jun 28, 2022

@tigrannajaryan @dashpole now that we have the scope attributes, should we bring this topic back, and define the semantic convention for scope attribute(s), where short_name would be the first?

@tigrannajaryan
Copy link
Member

@tigrannajaryan @dashpole now that we have the scope attributes, should we bring this topic back, and define the semantic convention for scope attribute(s), where short_name would be the first?

Yes, feel free to make a proposal (or @dashpole feel free to do it).

We may need changes to semantic convention generator tooling to support scopes.

@joaopgrassi
Copy link
Member

Unfortunately I don't have the cycles to work on this now, but I quickly tried it out and I think we don't need to change the convention generator.

Here's what I tried:
https://github.com/open-telemetry/opentelemetry-specification/compare/main...dynatrace-oss-contrib:opentelemetry-specification:feature/scope_attributes_semconv?expand=1

We could have a document inside specification/common/scope.md for the common scope attributes (short_name) for ex. Then, if there's scope attributes specific for each signal, those can be defined inside their appropriate folder like: semantic_conventions/metrics/scope-metrics.yaml -> specification/metrics/semantic_conventions/scope-metrics.md.

@tigrannajaryan
Copy link
Member

@dashpole will you be able to work on this?

@dashpole
Copy link
Contributor Author

Yes, I plan to work on this

@joaopgrassi
Copy link
Member

joaopgrassi commented Jul 19, 2022

Do we have an issue for it? Also, do you folks have an idea on how would we name this? We already have this page that states otel.scope.name and otel.scope.version. Would short_name also be mapped under the same? otel.scope.short_name? Or would it be under a new thing with just scope.short_name?

@tigrannajaryan
Copy link
Member

Do we have an issue for it? Also, do you folks have an idea on how would we name this? We already have this page that states otel.scope.name and otel.scope.version. Would short_name also be mapped under the same? otel.scope.short_name? Or would it be under a new thing with just scope.short_name?

I don't think anything is decided yet. I would not assume otel.scope.* is the right approach. Should all scope attribute names start with otel.scope? Is there a reason the names cannot start from the root namespace?

@joaopgrassi
Copy link
Member

Yeah I don't particularly have any answers, but was rather fishing for your ideas. I think we probably should have a new issue to discuss this topic further and lay out a good foundation for other attributes to come. I also don't think we need otel.scope.* as those are a bit "special".

@joaopgrassi
Copy link
Member

I created an issue #2682 so we have a forum to discuss it. :)

tigrannajaryan pushed a commit that referenced this pull request Oct 12, 2022
Fixes: #2493

Related: #1906

This is a second attempt at #2422.

## Changes

### Background: Naming Collisions

OpenTelemetry encourages the use of semantic conventions to make metric naming similar across instrumentation.  For example, if I have two http client libraries in my application, they would each produce a metric named `http.client.duration`, but with different meters (e.g. [otelmux](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/0dd27453a1ce8e433cb632e175a27f28ee83998d/instrumentation/github.com/gorilla/mux/otelmux) vs [otelhttp](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/0dd27453a1ce8e433cb632e175a27f28ee83998d/instrumentation/net/http/otelhttp)).  A prometheus exporter which receives both of these metrics would not be able to serve both of those histograms.  This would occur anytime a user uses two libraries which produces the same category (e.g. http, database, rpc, etc) of metrics, or if the two libraries just happen to use the same name for a metric.  Depending on the language, it may fail to create the Prometheus exporter, or may fail to send some, or all metrics if the same labels keys and values are present in both.

### Desired User Experience

As a user, I can use a Prometheus exporter with OpenTelemetry without experiencing strange errors/behavior due to naming collisions, and without having to apply transformations to metric names to work around these, except in rare cases.

As a user, I can easily add scope attributes to my metrics in Prometheus by joining with an info-style metric.  This is a common pattern in Prometheus: https://grafana.com/blog/2021/08/04/how-to-use-promql-joins-for-more-effective-queries-of-prometheus-metrics-at-scale/.

### Design

Add `opentelemetry_scope_name` and `opentelemetry_scope_version` as labels to all metrics.  This ensures that if two libraries produce the same metric points, they don't collide because the scope name/version labels will differ.

Those labels also serve as "join keys" to be able to add scope attributes to Prometheus metrics.  This is accomplished by introducing an `opentelemetry_scope_info` metric containing the same `opentelemetry_scope_name` and `opentelemetry_scope_version` labels, but also including scope attributes.  This also enables the collector's Prometheus receiver to reconstruct the original Instrumentation Scope when receiving the metrics.
ChengJinbao added a commit to ChengJinbao/opentelemetry-specification that referenced this pull request Nov 16, 2022
Fixes: #2493

Related: open-telemetry/opentelemetry-specification#1906

This is a second attempt at open-telemetry/opentelemetry-specification#2422.

## Changes

### Background: Naming Collisions

OpenTelemetry encourages the use of semantic conventions to make metric naming similar across instrumentation.  For example, if I have two http client libraries in my application, they would each produce a metric named `http.client.duration`, but with different meters (e.g. [otelmux](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/0dd27453a1ce8e433cb632e175a27f28ee83998d/instrumentation/github.com/gorilla/mux/otelmux) vs [otelhttp](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/0dd27453a1ce8e433cb632e175a27f28ee83998d/instrumentation/net/http/otelhttp)).  A prometheus exporter which receives both of these metrics would not be able to serve both of those histograms.  This would occur anytime a user uses two libraries which produces the same category (e.g. http, database, rpc, etc) of metrics, or if the two libraries just happen to use the same name for a metric.  Depending on the language, it may fail to create the Prometheus exporter, or may fail to send some, or all metrics if the same labels keys and values are present in both.

### Desired User Experience

As a user, I can use a Prometheus exporter with OpenTelemetry without experiencing strange errors/behavior due to naming collisions, and without having to apply transformations to metric names to work around these, except in rare cases.

As a user, I can easily add scope attributes to my metrics in Prometheus by joining with an info-style metric.  This is a common pattern in Prometheus: https://grafana.com/blog/2021/08/04/how-to-use-promql-joins-for-more-effective-queries-of-prometheus-metrics-at-scale/.

### Design

Add `opentelemetry_scope_name` and `opentelemetry_scope_version` as labels to all metrics.  This ensures that if two libraries produce the same metric points, they don't collide because the scope name/version labels will differ.

Those labels also serve as "join keys" to be able to add scope attributes to Prometheus metrics.  This is accomplished by introducing an `opentelemetry_scope_info` metric containing the same `opentelemetry_scope_name` and `opentelemetry_scope_version` labels, but also including scope attributes.  This also enables the collector's Prometheus receiver to reconstruct the original Instrumentation Scope when receiving the metrics.
joaopgrassi pushed a commit to dynatrace-oss-contrib/semantic-conventions that referenced this pull request Mar 21, 2024
Fixes: #2493

Related: open-telemetry/opentelemetry-specification#1906

This is a second attempt at open-telemetry/opentelemetry-specification#2422.

## Changes

### Background: Naming Collisions

OpenTelemetry encourages the use of semantic conventions to make metric naming similar across instrumentation.  For example, if I have two http client libraries in my application, they would each produce a metric named `http.client.duration`, but with different meters (e.g. [otelmux](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/0dd27453a1ce8e433cb632e175a27f28ee83998d/instrumentation/github.com/gorilla/mux/otelmux) vs [otelhttp](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/0dd27453a1ce8e433cb632e175a27f28ee83998d/instrumentation/net/http/otelhttp)).  A prometheus exporter which receives both of these metrics would not be able to serve both of those histograms.  This would occur anytime a user uses two libraries which produces the same category (e.g. http, database, rpc, etc) of metrics, or if the two libraries just happen to use the same name for a metric.  Depending on the language, it may fail to create the Prometheus exporter, or may fail to send some, or all metrics if the same labels keys and values are present in both.

### Desired User Experience

As a user, I can use a Prometheus exporter with OpenTelemetry without experiencing strange errors/behavior due to naming collisions, and without having to apply transformations to metric names to work around these, except in rare cases.

As a user, I can easily add scope attributes to my metrics in Prometheus by joining with an info-style metric.  This is a common pattern in Prometheus: https://grafana.com/blog/2021/08/04/how-to-use-promql-joins-for-more-effective-queries-of-prometheus-metrics-at-scale/.

### Design

Add `opentelemetry_scope_name` and `opentelemetry_scope_version` as labels to all metrics.  This ensures that if two libraries produce the same metric points, they don't collide because the scope name/version labels will differ.

Those labels also serve as "join keys" to be able to add scope attributes to Prometheus metrics.  This is accomplished by introducing an `opentelemetry_scope_info` metric containing the same `opentelemetry_scope_name` and `opentelemetry_scope_version` labels, but also including scope attributes.  This also enables the collector's Prometheus receiver to reconstruct the original Instrumentation Scope when receiving the metrics.
carlosalberto pushed a commit to carlosalberto/opentelemetry-specification that referenced this pull request Oct 21, 2024
* Introduce Scope Attributes

There are a few reasons why adding Scope attributes is a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with the other primary data types: Resource, Span, Metric,
  LogRecord.

See additional [discussion here](open-telemetry#2450).
carlosalberto pushed a commit to carlosalberto/oteps that referenced this pull request Oct 23, 2024
* Introduce Scope Attributes

There are a few reasons why adding Scope attributes is a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry/opentelemetry-specification#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with the other primary data types: Resource, Span, Metric,
  LogRecord.

See additional [discussion here](open-telemetry/opentelemetry-specification#2450).
carlosalberto pushed a commit to carlosalberto/oteps that referenced this pull request Oct 23, 2024
* Introduce Scope Attributes

There are a few reasons why adding Scope attributes is a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry/opentelemetry-specification#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with the other primary data types: Resource, Span, Metric,
  LogRecord.

See additional [discussion here](open-telemetry/opentelemetry-specification#2450).
carlosalberto pushed a commit to carlosalberto/oteps that referenced this pull request Oct 30, 2024
* Introduce Scope Attributes

There are a few reasons why adding Scope attributes is a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](open-telemetry/opentelemetry-specification#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with the other primary data types: Resource, Span, Metric,
  LogRecord.

See additional [discussion here](open-telemetry/opentelemetry-specification#2450).
carlosalberto pushed a commit that referenced this pull request Nov 8, 2024
* Introduce Scope Attributes

There are a few reasons why adding Scope attributes is a good idea:
- There are 2 known use cases where Scope attributes can solve specific problems:
  - Add support for [Meter "short_name"](#2422),
    represented as an attribute of Meter's Scope.
  - Add support for differentiating the type of data emitted from the scopes that belong
    to different data domains, e.g. profiling data emitted as log records or client-side
    data emitted as log records needs to be differentiated so that it can be easily
    routed and processed differently in the backends. We don't have a good way to handle
    this today. The type of the data can be recorded as an attribute Logger's Scope.
- It makes Scope consistent with the other primary data types: Resource, Span, Metric,
  LogRecord.

See additional [discussion here](#2450).
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.

7 participants