-
Notifications
You must be signed in to change notification settings - Fork 840
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
JIT exporter metrics #4993
JIT exporter metrics #4993
Conversation
Codecov ReportBase: 91.24% // Head: 91.26% // Increases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## main #4993 +/- ##
============================================
+ Coverage 91.24% 91.26% +0.02%
- Complexity 4894 4900 +6
============================================
Files 552 552
Lines 14481 14497 +16
Branches 1386 1388 +2
============================================
+ Hits 13213 13231 +18
Misses 878 878
+ Partials 390 388 -2
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what will happen if a user has configured OpenTelemetrySdk
without registering it global?
They have to manually call |
I guess, I'm wondering what happens if they don't do this, will the GlobalOpenTelemetry usage force another sdk to be auto-initialized? |
Ugh.. yes. Geez I'm really not a fan of GlobalOpenTelemetry#maybeAutoconfigureAndSetGlobal. |
We could have a separate "global" meter that autoconfigure sets. For example, ExporterMetrics could have a This would work well for export providers which are built in to the core SDK, and can take advantage of special behavior in the autoconfigure module. But the more generalized problem is how do SDK extension components (exporters, processors, etc) get access to Couple of ideas come to mind:
|
I prefer this option. We're discouraging everybody from using the |
…y-java into jit-exporter-metrics
With #5010 merged we don't need to worry about side affects of calling @open-telemetry/java-approvers can you take another look? |
.../all/src/main/java/io/opentelemetry/exporter/otlp/metrics/OtlpGrpcMetricExporterBuilder.java
Show resolved
Hide resolved
...src/main/java/io/opentelemetry/exporter/otlp/http/metrics/OtlpHttpMetricExporterBuilder.java
Show resolved
Hide resolved
private LongCounter seen() { | ||
LongCounter seen = this.seen; | ||
if (seen == null) { | ||
seen = meter().counterBuilder(exporterName + ".exporter.seen").build(); | ||
this.seen = seen; | ||
} | ||
return seen; | ||
} | ||
|
||
private LongCounter exported() { | ||
LongCounter exported = this.exported; | ||
if (exported == null) { | ||
exported = meter().counterBuilder(exporterName + ".exporter.exported").build(); | ||
this.exported = exported; | ||
} | ||
return exported; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it's not clear to me if this initialization should be synchronized or not, but I think it's ok either way for now and will get cleaned up by #5021 since then there will be post-init method that can be used for initialization
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't need to be synchronized. It looks a bit weird, but if two threads call exported()
at the same time, both will initialize a counter and set this.exported
, but this isn't a problem.
@jkwatson any thoughts on this? |
Ship it |
* Build ExporterMetrics instruments just in time * Exporters use GlobalOpenTelemetry#getMeterProvider() if meter provider is not set * FullConfigTest reset GlobalOpenTelemetry * MetricExporters use MeterProvider.noop()
What is the recommended approach? |
Inject an instance of OpenTelemetry into the places where it's needed. |
Let me add some context: If I'm writing a library such as riptide - what should I do? |
ExporterMetrics standardizes metric collection from exporters. Instrumenting exporters presents a chicken and the egg problem since exporters are part of the SDK, yet rely on the SDK for instrumentation.
The effort to split out exporter configuration into SPI implementations in #4949 makes this more clear as exporter configuration code (like jaeger configuration) sets the meter provider in a way that SPI implementations can't because they don't have access to the meter provider.
IMO instrumenting exporters is one of the few cases where depending on
GlobalOpenTelemetry
makes sense: Rather than worry about the ordering of initializingSdkMeterProvider
and passing it to other exporters, just have those exporters instrument themselves usingGlobalOpenTelemetry#getMeterProvider()
. The one caveat is that instrumentation has to be "just in time", ensuring thatGlobalOpenTelemetry#set
has been called before instrumentation begins.This PR adjusts
ExporterMetrics
instrumentation to be "just in time". It also adjusts all the exporters to useGlobalOpenTelemetry.getMeterProvider
by default instead ofMeterProvider.noop()
.