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

Trying to write an instrumentation library, can't eagerly create a meter/instruments but can eagerly get a tracer #4065

Closed
1 task done
haines opened this issue Aug 15, 2023 · 3 comments
Labels
question User is asking a question not related to a new feature or bug stale

Comments

@haines
Copy link

haines commented Aug 15, 2023

  • This only affects the JavaScript OpenTelemetry library

I'm trying to integrate OpenTelemetry into our library, which provides a client for the Cerbos gRPC/HTTP API.

We successfully incorporated tracing and span context propagation. Now I am trying to add metrics, and have run into difficulty.

Our approach so far has been to provide a CerbosInstrumentation class that implements the Instrumentation interface. Rather than patching require/imports, its enable method installs a hook into our client classes that allows us to instrument the gRPC/HTTP calls.

Our instrumentation class has a tracer field that is set to trace.getTracer() in the constructor. This works fine.

If I try to do the same with a meter field set to metrics.getMeter(), it doesn't work at all, which is really confusing.

On investigation, it seems that

  • we construct the instrumentation instance before setting up the SDK with the tracer and meter providers; then
  • trace.getTracer() gives us a proxy tracer that gets updated with the real instance once the NodeSDK sets the global tracer provider; but
  • metrics.getMeter() gives us a no-op meter that doesn't get updated once the NodeSDK sets the global meter provider.

I don't really understand how our instrumentation class is supposed to use the global meter provider given this behaviour. I'll probably try lazily initialisation so that we only create the histograms we need at the time we first want to record a metric, but this is a bit of a pain to implement compared to the tracer, and will only work if we assume the global meter provider doesn't change after the first time we attempt to record a metric (which is probably a reasonable assumption in the case of our library, but I don't know that it would be true for all libraries).

Would it make sense for @opentelemetry/api to provide a proxy meter implementation that behaves the same as the tracer one? If not, how should we handle this as library authors?

@pichlermarc pichlermarc added the question User is asking a question not related to a new feature or bug label Aug 16, 2023
@pichlermarc
Copy link
Member

I agree that this should be clearer.

Unfortunately, introducing a proxy meter would introduce a lot of complexity. For Metrics, multiple levels need to be proxied (MeterProvider, Meter, Instruments, batch observable Callbacks), whereas for tracing, only two need to be proxied (TracerProvider and Tracer). See also #3622

You can, however, re-create the instruments that you're using by overriding and implementing the _updateMetricInstruments() methods of the instrumentation (see the code from the http instrumentation). This is called when a new MeterProvider is set, which happens automatically when instrumentation is registered (via registerInstrumentations(), this has to be called after the SDK is initialized, though).

@github-actions
Copy link

This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 14 days.

@github-actions github-actions bot added the stale label Oct 16, 2023
Copy link

github-actions bot commented Nov 6, 2023

This issue was closed because it has been stale for 14 days with no activity.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question User is asking a question not related to a new feature or bug stale
Projects
None yet
Development

No branches or pull requests

2 participants