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

Tracking getResourceAsStream() performance #5369

Closed
breedx-splk opened this issue Apr 10, 2023 · 6 comments · Fixed by #5622
Closed

Tracking getResourceAsStream() performance #5369

breedx-splk opened this issue Apr 10, 2023 · 6 comments · Fixed by #5622
Labels
Feature Request Suggest an idea for this project

Comments

@breedx-splk
Copy link
Contributor

@jack-berg asked in #5365 for this issue to be opened.

The basic idea is that getResourceAsStream() can have negative performance ramifications on some platforms, specifically Android.

This can be detected when initializing the SDK on the main thread with strict mode enabled, as shown in this issue.

There is some detailed information about the performance of getResourceAsStream() and some of the causes in this article:
https://blog.nimbledroid.com/2016/04/06/slow-ClassLoader.getResourceAsStream.html

To the extent that we can provide reasonable alternatives or remove usages of getResourceAsStream(), especially in SDK internals, this will help Android users. There is already a pretty well-establish precedent of not doing any heavy lifting in the service/application path and doing IO in the background, so this seems to fit in with that.

@breedx-splk breedx-splk added the Feature Request Suggest an idea for this project label Apr 10, 2023
@breedx-splk
Copy link
Contributor Author

breedx-splk commented Apr 10, 2023

One might be inclined to simply say "Well easy, the Android app should just initialize the SDK on a background thread and not the main/ui thread.".

But it's not that easy. Unfortunately, in order to track startup time and follow early application lifecycle events, the SDK must first be initialized. Without that, a mobile telemetry solution would essentially need to create its own flavor of instrumentation that could be used and deferred/buffered until the otel SDK initialization is completed. This parallel/shadow/deferred telemetry implementation would result in significant increase in complexity and weakens what is otherwise a straightforward use of the otel sdk.

As far as I can tell so far, there's really nothing else that's thread-blocking, nor is there other IO being done in SDK creation. If we discover some, we could address those on a case-by-case basis.

@jack-berg
Copy link
Member

Ok I think I understand better - thanks for that explanation! This sounds similar to some of the valid use cases for GlobalOpenTelemetry.get() and its opt-in side effect to initialize the SDK: sometimes its just not practical to wire up the SDK for stuff that is executing sufficiently early in the application lifecycle. In these cases, it's nice for that instrumentation to be able to trigger the initialization of the SDK before obtaining Tracer / Meter and calling respective APIs.

I'm not very familiar with android environments - are there other types of things we need to be aware of / avoid during SDK initialization besides reading from resources?

Is the pattern in #5365 something that opentelemetry-java-instrumentation should adopt as well? I know instrumentation widely depends on reading the version properties file via EmbeddedInstrumentationProperties. If android takes a dependency on any library instrumentation, would they be impacted by that instrumentation reading from stream?

@mateuszrzeszutek
Copy link
Member

Is the pattern in #5365 something that opentelemetry-java-instrumentation should adopt as well? I know instrumentation widely depends on reading the version properties file via EmbeddedInstrumentationProperties. If android takes a dependency on any library instrumentation, would they be impacted by that instrumentation reading from stream?

I haven't thought about it before but yes, that is something we'll need to do at least for the instrumentations that are commonly used on Android (probably these that use animalsniffer-conventions)

@breedx-splk
Copy link
Contributor Author

I'm not very familiar with android environments - are there other types of things we need to be aware of / avoid during SDK initialization besides reading from resources?

Yeah, the primary concern is doing any blocking I/O, like disk and network. The StrictMode builder has these methods:

image

I wonder if we'll hit DNS lookups again.

There are a few things in the android sdk that we were already able to defer or otherwise make lazy, but I can't remember details offhand.

@jack-berg
Copy link
Member

I wonder if we'll hit DNS lookups again.

Do you have ideas of when DNS lookups might occur during initialization?

@breedx-splk
Copy link
Contributor Author

I wonder if we'll hit DNS lookups again.

Do you have ideas of when DNS lookups might occur during initialization?

I don't.

I don't mind chatting through these things so that there's a record in case we eventually want to circle back....but I hope we can prevent this issue from becoming an android startup-delay omnibus instead of keeping the discussion narrowly focused on the thing we do know already causes a problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature Request Suggest an idea for this project
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants