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

Http/sURLConnection auto instrumentation #133

Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
83eedb2
Instrument HttpURLConnection using Bytebuddy
surbhiia Oct 30, 2023
0e4c44f
Merge branch 'open-telemetry:main' into develop/HttpURLConnection-aut…
surbhiia Oct 30, 2023
2ded0e8
Merge branch 'open-telemetry:main' into develop/HttpURLConnection-aut…
surbhiia Nov 2, 2023
d1e21be
Update target matching, Add contentLength, contentLengthLong, headerF…
surbhiia Nov 2, 2023
7664dfa
Spotless Apply
surbhiia Nov 2, 2023
2c31c1d
Add HttpURLConnection tracing
surbhiia Nov 3, 2023
116391e
Merge branch 'open-telemetry:main' into develop/HttpURLConnection-aut…
surbhiia Nov 13, 2023
e9a1242
Move runnable API to config, Update Time used, Add README, remove scope
surbhiia Nov 15, 2023
df4e4de
Merge branch 'open-telemetry:main' into develop/HttpURLConnection-aut…
surbhiia Nov 15, 2023
fa389ed
Correct previous commit - Move runnable API to config, Update Time us…
surbhiia Nov 15, 2023
3b84a50
Differentiate opentelemetry-java and opentelemetry-java-instrumentation
surbhiia Nov 15, 2023
e96e6aa
Update auto-instrumentation/httpurlconnection/README.md
surbhiia Nov 16, 2023
e2516ac
Update auto-instrumentation/httpurlconnection/README.md
surbhiia Nov 16, 2023
d2cb68b
Merge branch 'open-telemetry:main' into develop/HttpURLConnection-aut…
surbhiia Nov 16, 2023
a92a360
Update Readme
surbhiia Nov 17, 2023
2337523
Merge branch 'main' into develop/HttpURLConnection-auto-instrumentation
surbhiia Nov 20, 2023
277bf7d
Remove synchronized, make code concise, add min sdk setting, update r…
surbhiia Nov 22, 2023
c0a3bc6
Minor readme correction, add android.minSdk in agent build
surbhiia Nov 22, 2023
2ce934e
Added Logs and tackled another TODO
surbhiia Nov 22, 2023
2cd6e49
Merge branch 'open-telemetry:main' into develop/HttpURLConnection-aut…
surbhiia Nov 29, 2023
fb92c89
Expand Input/Output Stream to capture IOExceptions on read
surbhiia Dec 14, 2023
3d2a414
Merge branch 'main' into develop/HttpURLConnection-auto-instrumentation
surbhiia May 28, 2024
458b341
Move httpurlconnection under instrumentation and update imports
surbhiia May 28, 2024
c858470
Improvements - Use ConcurentHashMap, harvester shedule with fixed del…
surbhiia May 30, 2024
ba541f7
Change to android library, add baseline lint and use System.uptimeMil…
surbhiia Jun 3, 2024
d4be67e
Merge branch 'main' into develop/HttpURLConnection-auto-instrumentation
surbhiia Jun 3, 2024
9460e1f
Update readme.md and a correction
surbhiia Jun 5, 2024
073d5cb
Depend on instrumentation-bom for version resolution
surbhiia Jun 6, 2024
ca183b6
Address review comments
surbhiia Jun 7, 2024
c8eb574
Update instrumentation/httpurlconnection/library/src/main/java/io/ope…
surbhiia Jun 7, 2024
92eec96
spotlessApply
surbhiia Jun 7, 2024
1ab8d1a
Update to permalinks
surbhiia Jun 13, 2024
91c40e3
Remove lint baseline and add suppress annotation instead.
surbhiia Jun 14, 2024
5102e2f
SpotlessApply
surbhiia Jun 14, 2024
36f9de3
Rename to CONNECTION_INACTIVITY_TIMEOUT_MS
surbhiia Jun 17, 2024
20ec9f5
SpotlessApply
surbhiia Jun 17, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@ androidx-core = "androidx.core:core:1.13.1"
findbugs-jsr305 = "com.google.code.findbugs:jsr305:3.0.2"
byteBuddy = { module = "net.bytebuddy:byte-buddy", version.ref = "byteBuddy" }
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
opentelemetry-instrumentation-api = { module = "io.opentelemetry.instrumentation:opentelemetry-instrumentation-api" }
opentelemetry-instrumentation-apiSemconv = { module = "io.opentelemetry.instrumentation:opentelemetry-instrumentation-api-incubator" }
opentelemetry-instrumentation-api = { module = "io.opentelemetry.instrumentation:opentelemetry-instrumentation-api"}
opentelemetry-instrumentation-apiSemconv = { module = "io.opentelemetry.instrumentation:opentelemetry-instrumentation-api-incubator", version.ref = "opentelemetry-instrumentation-alpha"}
opentelemetry-instrumentation-okhttp = { module = "io.opentelemetry.instrumentation:opentelemetry-okhttp-3.0", version.ref = "opentelemetry-instrumentation-alpha" }
opentelemetry-semconv = { module = "io.opentelemetry.semconv:opentelemetry-semconv", version.ref = "opentelemetry-semconv" }
opentelemetry-semconv-incubating = { module = "io.opentelemetry.semconv:opentelemetry-semconv-incubating", version.ref = "opentelemetry-semconv" }
opentelemetry-api = { module = "io.opentelemetry:opentelemetry-api" }
opentelemetry-api = { module = "io.opentelemetry:opentelemetry-api"}
opentelemetry-api-incubator = { module = "io.opentelemetry:opentelemetry-api-incubator" }
opentelemetry-sdk-extension-incubator = { module = "io.opentelemetry:opentelemetry-sdk-extension-incubator", version.ref = "opentelemetry-alpha" }
opentelemetry-sdk = { module = "io.opentelemetry:opentelemetry-sdk" }
opentelemetry-sdk = { module = "io.opentelemetry:opentelemetry-sdk"}
opentelemetry-context = { module = "io.opentelemetry:opentelemetry-context", version.ref = "opentelemetry"}
opentelemetry-exporter-logging = { module = "io.opentelemetry:opentelemetry-exporter-logging" }
opentelemetry-diskBuffering = { module = "io.opentelemetry.contrib:opentelemetry-disk-buffering", version.ref = "opentelemetry-contrib" }
opentelemetry-exporter-otlp = { module = "io.opentelemetry:opentelemetry-exporter-otlp", version.ref = "opentelemetry" }
Expand Down
75 changes: 75 additions & 0 deletions instrumentation/httpurlconnection/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Android Instrumentation for URLConnection, HttpURLConnection and HttpsURLConnection

## Status : Experimental

Provides OpenTelemetry instrumentation for:
- [URLConnection](https://developer.android.com/reference/java/net/URLConnection)
- [HttpURLConnection](https://developer.android.com/reference/java/net/HttpURLConnection)
- [HttpsURLConnection](https://developer.android.com/reference/javax/net/ssl/HttpsURLConnection)

## Quickstart

### Overview

This plugin enhances the Android application host code by instrumenting all critical APIs (specifically those that initiate a connection). It intercepts calls to these APIs to ensure the following actions are performed:
- Context is added for distributed tracing before actual API is called (i.e before connection is initiated).
- Traces and spans are generated and properly closed.
- Any exceptions thrown are recorded.

A span associated with a given request is concluded in the following scenarios:
- When the getInputStream()/getErrorStream() APIs are called, the span concludes after the stream is fully read, an IOException is encountered, or the stream is closed.
- When the disconnect API is called.

Spans won't be automatically ended and reported otherwise. If any of your URLConnection requests do not call the span concluding APIs mentioned above, refer the section entitled ["Scheduling Harvester Thread"](#scheduling-harvester-thread). This section provides guidance on setting up a recurring thread that identifies unreported, idle connections (those that have been read from but have been inactive for more than 10 seconds) and concludes any open spans associated with them.

> The minimum supported Android SDK version is 21, though it will also instrument APIs added in the Android SDK version 24 when running on devices with API level 24 and above.

> If your project's minSdk is lower than 26, then you must enable
Copy link
Contributor

Choose a reason for hiding this comment

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

Desugaring is necessary for minSdk 24 now because of the dependency on the semconv module. You may just want to point to the reference in main README instead instead of putting this and the AGP requirements here?

Copy link
Contributor Author

@surbhiia surbhiia Jun 17, 2024

Choose a reason for hiding this comment

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

I did think of that, but I was/am more inclined to keep this here as this module can be used separately to the main module. Customers do not need to navigate to and read the other readme.

If not, maybe we can pull out the similar text mentioned in main readme to a separate section in main readme itself, something like "Critical Notes"(there is a slight more addition to that we can make - for AGP < 8.3.0, the property to be used for correct dexing is different). And link to that section from this readme. But then, all the incremental callouts that would go in that section might not apply to this module always.

Which one sounds better to you? :)

Copy link
Contributor

Choose a reason for hiding this comment

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

I did a similar duplication in the Java sem conv repo earlier but was advised to put the details in one place so if we need to update, we didn't have to do it multiple places. But I think both ways have advantages, so it's up to you which one you prefer. I think merging as is and figuring it out later is perfectly reasonable.

> [corelib desugaring](https://developer.android.com/studio/write/java8-support#library-desugaring).
>
> If your project's minSdk is lower than 24, in order to run the app built on debug, you need to add the following property in `gradle.properties` file:
> - If AGP <= 8.3.0, set `android.enableDexingArtifactTransform=false`
> - if AGP > 8.3.0, set `android.useFullClasspathForDexingTransform=true`
>
> For the full context for these workaround, please see
> [this issue](https://issuetracker.google.com/issues/334281968) for AGP <= 8.3.0
> or [this issue](https://issuetracker.google.com/issues/230454566#comment18) for AGP > 8.3.0.

### Add these dependencies to your project

Replace `AUTO_HTTP_URL_INSTRUMENTATION_VERSION` with the [latest release](https://central.sonatype.com/search?q=g%3Aio.opentelemetry.android++a%3Ahttpurlconnection-library&smo=true).

Replace `BYTEBUDDY_VERSION` with the [latest release](https://search.maven.org/search?q=g:net.bytebuddy%20AND%20a:byte-buddy).

#### Byte buddy compilation plugin

This plugin leverages Android's [Transform API](https://developer.android.com/reference/tools/gradle-api/current/com/android/build/api/variant/ScopedArtifactsOperation#toTransform(com.android.build.api.artifact.ScopedArtifact,kotlin.Function1,kotlin.Function1,kotlin.Function1)) to instrument bytecode at compile time. You can find more info on its [repo page](https://github.com/raphw/byte-buddy/tree/master/byte-buddy-gradle-plugin/android-plugin).

```groovy
plugins {
id 'net.bytebuddy.byte-buddy-gradle-plugin' version 'BYTEBUDDY_VERSION'
}
```

#### Project dependencies

```kotlin
implementation("io.opentelemetry.android:httpurlconnection-library:AUTO_HTTP_URL_INSTRUMENTATION_VERSION")
byteBuddy("io.opentelemetry.android:httpurlconnection-agent:AUTO_HTTP_URL_INSTRUMENTATION_VERSION")
breedx-splk marked this conversation as resolved.
Show resolved Hide resolved
```

### Configurations

#### Scheduling Harvester Thread

To schedule a periodically running thread to conclude spans on any unreported, idle connections, add the below code in the function where your application starts ( that could be onCreate() method of first Activity/Fragment/Service):
```Java
Executors.newSingleThreadScheduledExecutor().scheduleWithFixedDelay(HttpUrlInstrumentationConfig.getReportIdleConnectionRunnable(), 0, HttpUrlInstrumentationConfig.getReportIdleConnectionInterval(), TimeUnit.MILLISECONDS);
```

`HttpUrlInstrumentationConfig.getReportIdleConnectionRunnable()` is the API to get the runnable. `HttpUrlInstrumentationConfig.getReportIdleConnectionInterval()` is the API to get the fixed interval (10s) in milli seconds.

#### Other Optional Configurations
You can optionally configure the automatic instrumentation by using the setters in [HttpUrlInstrumentationConfig](library/src/main/java/io/opentelemetry/instrumentation/library/httpurlconnection/HttpUrlInstrumentationConfig.java).

After adding the plugin and the dependencies to your project, and after doing the required configurations, your requests will be traced automatically.
15 changes: 15 additions & 0 deletions instrumentation/httpurlconnection/agent/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
plugins {
id("otel.android-library-conventions")
id("otel.publish-conventions")
}

description = "OpenTelemetry build-time auto-instrumentation for HttpURLConnection on Android"

android {
namespace = "io.opentelemetry.android.httpurlconnection.agent"
}

dependencies {
implementation(project(":instrumentation:httpurlconnection:library"))
implementation(libs.byteBuddy)
}
Loading