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

Log warning if SDK is detected on classpath but has not been initialized when accessing global. #2396

Closed

Conversation

anuraaga
Copy link
Contributor

This is on the read side, whereas #2380 is on the write side. We'll probably want both.

Copy link
Member

@bogdandrutu bogdandrutu left a comment

Choose a reason for hiding this comment

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

This makes the assumption that we remove SPI, otherwise this is fine to happen. Do we want this if user expects to use SPI?

@anuraaga
Copy link
Contributor Author

@bogdandrutu I am proposing having all autoconfiguration in a separate artifact. That artifact could use SPI to allow configuration of non-env var controlled stuff. And this code could be updated to detect whether the artifact (which is under our control so doesn't need a generic entry point mechanism) is on the classpath and call it's initialization entry point with reflection if we want it to be a completely automatic process, and this log wouldn't be thrown for users of that SPI-approach.

Copy link
Contributor

@jkwatson jkwatson left a comment

Choose a reason for hiding this comment

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

I approve the removal of SPI from the main API, so I also approve of this as a stop-gap warning to show the user that they need to force their SDK init earlier.

@bogdandrutu
Copy link
Member

@jkwatson you said you approve removing of the SPI, but SPI is still there. So I am confused what this PR gives us (especially if I use SPI, which is still available).

static final Logger logger = Logger.getLogger(GlobalOpenTelemetry.class.getName());

private static final boolean suppressSdkCheck =
Boolean.getBoolean("otel.sdk.suppress-sdk-initialized-warning");
Copy link
Member

Choose a reason for hiding this comment

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

Why do we refer to SDK in the API?

Copy link
Contributor

Choose a reason for hiding this comment

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

Because our SDK is going to be the solution for 99.99% of all users. I think it's fine to refer to our SDK like this.


// Use an inner class that checks and logs in its static initializer to have log-once behavior
// using initial classloader lock and no further runtime locks or atomics.
private static class SdkChecker {
Copy link
Member

Choose a reason for hiding this comment

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

Call it "ImplementationChecker". We are currently refer as "SDK" to our official implementation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is indeed checking for our official implementation so SdkChecker seems correct

static {
boolean hasSdk = false;
try {
Class.forName("io.opentelemetry.sdk.OpenTelemetrySdk");
Copy link
Member

Choose a reason for hiding this comment

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

Why do we hardcode our implementation in the API artifact?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Bigger question is why not? We have an official implementation, the OpenTelemetry SDK, which we expect to be used in the vast majority of cases. If there's something we get from picking into other artifacts we publish, there isn't really a reason not to. It's a bit like how we have the comments "package-private to allow usage from auto-instrumentation" - that's even another repository, but we think it's worth it to allow good instrumentation experience.

Copy link
Contributor Author

@anuraaga anuraaga left a comment

Choose a reason for hiding this comment

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

you said you approve removing of the SPI, but SPI is still there. So I am confused what this PR gives us (especially if I use SPI, which is still available).

@bogdandrutu This PR gets us a warning when the global is used before the user initializes the SDK. It doesn't have any downside on the current SPI. And the current SPI will probably be removed after #2401, we've discussed that it isn't helping much in #2371. An API-level SPI for autoloading a custom implementation can be added later if it helps a lot, until we understand better the actual usage patterns of custom implementations it's hard to say. In the meantime, let's focus on the UX of what we expect, the OpenTelemetry SDK.


// Use an inner class that checks and logs in its static initializer to have log-once behavior
// using initial classloader lock and no further runtime locks or atomics.
private static class SdkChecker {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is indeed checking for our official implementation so SdkChecker seems correct

static {
boolean hasSdk = false;
try {
Class.forName("io.opentelemetry.sdk.OpenTelemetrySdk");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Bigger question is why not? We have an official implementation, the OpenTelemetry SDK, which we expect to be used in the vast majority of cases. If there's something we get from picking into other artifacts we publish, there isn't really a reason not to. It's a bit like how we have the comments "package-private to allow usage from auto-instrumentation" - that's even another repository, but we think it's worth it to allow good instrumentation experience.

Copy link
Contributor Author

@anuraaga anuraaga left a comment

Choose a reason for hiding this comment

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

@jkwatson @bogdandrutu Do you think we can add this in now that the SPI isn't there?

Base automatically changed from master to main January 26, 2021 00:26
Anuraag Agrawal added 2 commits March 5, 2021 16:43
@anuraaga
Copy link
Contributor Author

anuraaga commented Mar 5, 2021

@jkwatson @bogdandrutu I realized that we do need this PR (#2548 (review) was only about warning when set is called in the wrong order, but does not help in the case that buildAndRegisterGlobal is forgotten completely). Can we go ahead and add this?

@anuraaga
Copy link
Contributor Author

anuraaga commented Mar 5, 2021

Copy link
Member

@trask trask left a comment

Choose a reason for hiding this comment

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

@asarkar
Copy link

asarkar commented Mar 5, 2021

@anuraaga I suggest that the warning log clearly say what the problem is, and what to do to fix it, like "No OpenTelemetry implementation found; consider adding <Maven GAV> to classpath" instead of get/set stuff which dumb users like me won't understand.

@anuraaga
Copy link
Contributor Author

anuraaga commented Mar 5, 2021

@asarkar It says Make sure to initialize OpenTelemetrySdk, using OpenTelemetrySdk.builder()...buildAndRegisterGlobal(), as early as possible in your application. Isn't that what you need to know?

@asarkar
Copy link

asarkar commented Mar 5, 2021

It says Make sure to initialize OpenTelemetrySdk, using OpenTelemetrySdk.builder()...buildAndRegisterGlobal(), as early as possible in your application. Isn't that what you need to know?

I'd need to know where to get it. Remember, if someone is missing the SDK, they don't have OpenTelemetrySdk on classpath.

@anuraaga
Copy link
Contributor Author

anuraaga commented Mar 5, 2021

@asarkar Yeah this message is only thrown when the SDK is on the classpath, where it's almost always the case that it's an error to have forgotten to register it. It makes this PR a relative no-brainer.

This PR does not change the behavior when SDK isn't on the classpath, in which case noop is used - this actually does have real use cases for example, a library may be instrumented with OpenTelemetry but a user doesn't actually want to enable OpenTelemetry in their app by including the SDK. It might still be worth logging something for this case but it's not as clear cut and we can think about it separate from this one.

@jkwatson
Copy link
Contributor

jkwatson commented Mar 5, 2021

I still think this is a good addition. @bogdandrutu any new thoughts?

@jkwatson
Copy link
Contributor

I still think this is a good addition. @bogdandrutu any new thoughts?

@bogdandrutu seems like we should unblock and get this merged. You ok with that?

@jkwatson
Copy link
Contributor

jkwatson commented Jun 8, 2021

@anuraaga I think we can unblock this if you are interested.

@anuraaga
Copy link
Contributor Author

@jkwatson Yeah it'd be nice to merge this

+ "OpenTelemetrySdk.builder()...buildAndRegisterGlobal(), as early as possible in "
+ "your application. If you do not need to use the OpenTelemetry SDK, either "
+ "exclude it from your classpath or set the "
+ "'otel.sdk.suppress-sdk-initialized-warning' system property to true.",
Copy link

Choose a reason for hiding this comment

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

Looking at how we name configuration properties enabling/disabling various options here and in the "-instrumentation" I believe that a better one could be otel.sdk.not-initialized-warning.enable set by default to true. In all of the other cases we use "enable" rather that "supress (disable)".

@jkwatson jkwatson dismissed bogdandrutu’s stale review June 10, 2021 14:36

original object is now moot, since SPI has been removed.

@jkwatson
Copy link
Contributor

@anuraaga I'm sure this needs a rebase. Thanks!

@jkwatson jkwatson removed the request for review from tylerbenson April 8, 2022 17:25
@github-actions
Copy link
Contributor

This PR was marked stale due to lack of activity. It will be closed in 14 days.

@github-actions github-actions bot added the Stale label Jun 22, 2022
@github-actions
Copy link
Contributor

github-actions bot commented Jul 6, 2022

Closed as inactive. Feel free to reopen if this PR is still being worked on.

@github-actions github-actions bot closed this Jul 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants