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

Metrics SDK: allow several metric readers to share the same metric exporter #3616

Open
marcalff opened this issue Jul 24, 2023 · 13 comments
Open
Labels
spec:metrics Related to the specification/metrics directory triage:accepted:needs-sponsor Ready to be implemented, but does not yet have a specification sponsor

Comments

@marcalff
Copy link
Member

What are you trying to achieve?

For my application, I need to export metrics to an endpoint at different frequencies.

To do so, several PeriodicMetricReaders are defined, for example:

  • Reader A exports data every 15 seconds
  • Reader B exports data every 15 minutes

Because each reader owns an associated exporter, I now need to define:

  • An exporter for reader A
  • An exporter for reader B

even when these exporters have the same configuration and points to the same metric endpoint.

This leads to:

  • duplicated exporter instances, which each have their own memory consumption
  • duplicated network connections from my process to the endpoint
  • duplicated SSL sessions from each exporter to the endpoint

which is a concern for:

  • performances overhead in the instrumented application
  • network session overhead in the endpoint, with multiple connections originating from the same place

What did you expect to see?

Instead, I would like to define, in the SDK:

  • a unique exporter E
  • configure reader A to use exporter E
  • configure reader B to use exporter E

In other words, relax the requirement that a reader owns an exporter, and let the initialization code that sets up the SDK to decide (programmatically) how to deploy the pipelines, sharing (or not) exporters between readers. For example:

  • reader A uses exporter E
  • reader B uses exporter E
  • reader C uses exporter F

Consequences:

For a reader flush operation, the flush can be forwarded to the shared exporter, which may, as a side effect, also flush data from other readers. This is acceptable in my understanding.

For a reader shutdown operation, the shutdown is forwarded to the shared exporter. The exporter is to implement a refcount, and only effectively shutdown the exporter when the last reader is shutdown, to avoid side effects between readers.

Additional context.

Add any other context about the problem here. If you followed an existing documentation, please share the link to it.

@marcalff marcalff added the spec:metrics Related to the specification/metrics directory label Jul 24, 2023
@austinlparker austinlparker added the triage:deciding:needs-info Not enough information. Left open to provide the author with time to add more details label May 7, 2024
@austinlparker
Copy link
Member

Can you confirm that this isn't working, and in which language(s)? This doesn't sound like how things are supposed to work (e.g., exporters aren't owned by readers since exporters are stateless)

@pellared
Copy link
Member

pellared commented May 7, 2024

This doesn't sound like how things are supposed to work (e.g., exporters aren't owned by readers since exporters are stateless)

This is how it is supposed to work according to the spec:
https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk.md

Metric Exporters always have an associated MetricReader. [...] There could be multiple Push Metric Exporters or Pull Metric Exporters or even a mixture of both configured at the same time on a given MeterProvider using one MetricReader for each exporter.

One, not many.

Exporters can be stateful:

Side note: I think there is a similar problem when one would like to use the same exporter with different span/log processors.

@trask
Copy link
Member

trask commented May 7, 2024

@marcalff
Copy link
Member Author

marcalff commented Jun 20, 2024

I confirm this is not working for C++, and forces the application to duplicate exporters.

So, what is the outcome for this issue then ?

According to the spec, there is one reader for each exporter, not many.
The java implementation is not compliant then.
The C++ implementation follows the spec, which makes it difficult to use in my application.

I am asking to relax the spec to allow N readers using the same exporter, so that:

  • opentelemetry-java becomes compliant
  • opentelemetry-cpp can implement the change

@pellared
Copy link
Member

pellared commented Jun 20, 2024

For Go SDK it would be a problem only for stateful exporters. I think this change will be difficult to implement to have it out if the box. The problem is with synchronizing the shutdown of the stateful exporters. I think that in such scenario the exporter shutdown must be delayed until all readers are shut down.

Couldn't the described problem be solved by implementing "an exporter provider" which returns a new instance of exporter for each reader while under the hood there would be a reference counter and (a pool of) resources that are shared across all returned exporters? This would not require any chances in the SDKs and specification.

The other possiblilty is that exporters provided by SDK use shared resources.

@marcalff
Copy link
Member Author

For Go SDK it would be a problem only for stateful exporters. I think this change will be difficult to implement to have it out if the box. The problem is with synchronizing the shutdown of the stateful exporters. I think that in such scenario the exporter shutdown must be delayed until all readers are shut down.

Exactly, this is my suggestion to implement a refcount in the exporter, to effectively delay the shutdown when all readers are shutdown.

Couldn't the described problem be solved by implementing "an exporter provider" which returns a new instance of exporter for each reader while under the hood there would be a reference counter and (a pool of) resources that are shared across all returned exporters? This would not require any chances in the SDKs and specification.

I fail to see the logic here:

  • the spec is broken (or too restrictive for no apparent reason),
  • some implementations (java) are not compliant already,
  • the suggestion is to have more non compliant implementations,

and all this to avoid changing the broken spec ?

@pellared
Copy link
Member

Exactly, this is my suggestion to implement a refcount in the exporter, to effectively delay the shutdown when all readers are shutdown

Exporter is an interface. This would be still just an implementation detail of an exporter? Which one? Or the provider? How would we solve sharing an exporter across multiple providers? How would an exporter know that it is applied to a reader?

all this to avoid changing the broken spec

Nope. Mentioning to evaluate multiple options.

@marcalff
Copy link
Member Author

@svrnm svrnm added triage:deciding:tc-inbox Needs attention from the TC in order to move forward and removed triage:deciding:needs-info Not enough information. Left open to provide the author with time to add more details labels Jul 8, 2024
@svrnm
Copy link
Member

svrnm commented Jul 8, 2024

@open-telemetry/technical-committee please take a look

@jack-berg jack-berg added the triage:accepted:needs-sponsor Ready to be implemented, but does not yet have a specification sponsor label Jul 31, 2024
@jack-berg jack-berg removed the triage:deciding:tc-inbox Needs attention from the TC in order to move forward label Jul 31, 2024
@jack-berg
Copy link
Member

Talked about in the 7/31/24 TC meeting..

  • Metric exporters can't be associated with multiple readers because the spec doesn't require export to be thread safe. The motivation for this seems to be to promote increased simplicity of implementations.
  • This use case seems important, and is already possible in several languages.
  • We think that this is reasonable to pursue, and that someone should drive evolving the spec to accommodate this in a backwards compatible way. Updating the status to traige:accepted:needs-sponsor to reflect this.

@marcalff
Copy link
Member Author

marcalff commented Aug 2, 2024

This use case seems important, and is already possible in several languages.

@jack-berg

I think the long lasting consequences of this should not be underestimated, which is why the spec should be relaxed now.

So, "several languages", including Java, allows a configuration which is not allowed (in fact, explicitly forbidden) per the spec wording.

Meanwhile, the opentelemetry-configuration project defines a yaml schema to represent what a configuration is, based on the current spec.

The schema does not allow to share a metric exporter between several metrics readers, because the exporter configuration is included -- by value -- as a child of the metric reader configuration.

If we do nothing now, in 3 years from now, we will find out that some people using a shared exporter, by using the programatic API for the SDK configuration (say, in Java), will be unable to adopt and migrate to the yaml configuration provided by opentelemetry-configuration, because the yaml schema is too restrictive and does not allow to represent configurations that already exists today for some SIG.

In 3 years, when the yaml implementation of opentelemetry-configuration is already implemented in each SIG, and already used in the wild, it will be too late to change the schema to accommodate this use case.

@jack-berg
Copy link
Member

The schema does not allow to share a metric exporter between several metrics readers, because the exporter configuration is included -- by value -- as a child of the metric reader configuration.

Are you suggesting adjusting the schema so that exporter is configured separately from reader, and associating the exporter with the reader by some sort of reference? (This is analogous to how the collector configures receivers, processors, and exporters, and separately composes them into pipelines.) If so, this was previously considered and rejected in early discussions (see MrAlias/otel-schema#12, MrAlias/otel-schema#10). The configuration schema is still experimental and we could of course revisit that decision, but that's a pretty disruptive shift and would need strong arguments.

The set of people that would stand to be impacted by this are the intersection of people who want to have multiple periodic readers at different collection intervals AND have applications which are performance sensitive enough that the overhead of not sharing exporter resources is a non-starter. I think that may occur, but won't be common.

Putting that aside, I do think we should find a way to adjust the spec to support this since we couldn't think of any good reasons to justify this restriction.

@marcalff
Copy link
Member Author

marcalff commented Aug 7, 2024

Are you suggesting adjusting the schema so that exporter is configured separately from reader, and associating the exporter with the reader by some sort of reference?

So that the exporter may be configured separately, yes.

(This is analogous to how the collector configures receivers, processors, and exporters, and separately composes them into pipelines.)

No, it can be done differently.

A schema change does not have to be disruptive, this is an assumption on the solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
spec:metrics Related to the specification/metrics directory triage:accepted:needs-sponsor Ready to be implemented, but does not yet have a specification sponsor
Projects
Status: Spec - Accepted
Development

No branches or pull requests

7 participants