├── .java-version
├── manual_licenses_map.txt
├── agent-common
├── metadata
│ └── agent-common.api
├── build.gradle.kts
└── src
│ └── main
│ └── java
│ └── co
│ └── elastic
│ └── otel
│ └── android
│ └── common
│ └── internal
│ ├── package-info.java
│ ├── annotations
│ └── InternalApi.kt
│ └── logging
│ ├── ELoggerFactory.kt
│ ├── Elog.kt
│ └── BaseELogger.kt
├── checks.sh
├── instrumentation
├── api
│ ├── metadata
│ │ └── api.api
│ ├── src
│ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ └── java
│ │ │ └── co
│ │ │ └── elastic
│ │ │ └── otel
│ │ │ └── android
│ │ │ └── instrumentation
│ │ │ └── internal
│ │ │ ├── package-info.java
│ │ │ └── Instrumentation.kt
│ └── build.gradle.kts
├── okhttp
│ ├── library
│ │ ├── metadata
│ │ │ └── library.api
│ │ ├── src
│ │ │ └── main
│ │ │ │ └── java
│ │ │ │ └── co
│ │ │ │ └── elastic
│ │ │ │ └── otel
│ │ │ │ └── android
│ │ │ │ └── okhttp
│ │ │ │ └── internal
│ │ │ │ ├── package-info.java
│ │ │ │ ├── delegate
│ │ │ │ └── InterceptorDelegator.kt
│ │ │ │ ├── OkHttpInstrumentation.kt
│ │ │ │ └── plugin
│ │ │ │ └── TracingCallback.java
│ │ └── build.gradle.kts
│ ├── bytebuddy
│ │ ├── metadata
│ │ │ └── bytebuddy.api
│ │ ├── src
│ │ │ └── main
│ │ │ │ ├── resources
│ │ │ │ └── META-INF
│ │ │ │ │ └── net.bytebuddy
│ │ │ │ │ └── build.plugins
│ │ │ │ └── java
│ │ │ │ └── co
│ │ │ │ └── elastic
│ │ │ │ └── otel
│ │ │ │ └── android
│ │ │ │ └── okhttp
│ │ │ │ └── internal
│ │ │ │ ├── package-info.java
│ │ │ │ ├── callback
│ │ │ │ └── OkHttpCallbackAdvice.java
│ │ │ │ └── OkHttpClientAdvice.java
│ │ └── build.gradle.kts
│ └── plugin
│ │ ├── metadata
│ │ └── plugin.api
│ │ ├── build.gradle.kts
│ │ └── src
│ │ └── main
│ │ └── java
│ │ └── co
│ │ └── elastic
│ │ └── otel
│ │ └── android
│ │ └── okhttp
│ │ └── OkHttpInstrumentationPlugin.kt
└── oteladapter
│ ├── library
│ ├── metadata
│ │ └── library.api
│ ├── src
│ │ └── main
│ │ │ └── java
│ │ │ └── co
│ │ │ └── elastic
│ │ │ └── otel
│ │ │ └── android
│ │ │ └── oteladapter
│ │ │ └── internal
│ │ │ ├── package-info.java
│ │ │ └── delegate
│ │ │ ├── tools
│ │ │ ├── Delegator.kt
│ │ │ └── MultipleReference.kt
│ │ │ ├── meter
│ │ │ └── MeterProviderDelegator.kt
│ │ │ └── logger
│ │ │ └── noop
│ │ │ └── NoopLoggerBuilder.kt
│ └── build.gradle.kts
│ └── plugin
│ ├── metadata
│ └── plugin.api
│ ├── build.gradle.kts
│ └── src
│ └── main
│ └── java
│ └── co
│ └── elastic
│ └── otel
│ └── android
│ └── oteladapter
│ └── ExperimentalOtelAdapterPlugin.kt
├── android_tests.sh
├── docs
├── release-notes
│ ├── toc.yml
│ └── known-issues.md
├── reference
│ └── edot-android
│ │ ├── images
│ │ ├── opentelemetry-logo.png
│ │ ├── find-export-endpoint
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ ├── 3.png
│ │ │ └── 4.png
│ │ ├── span-visualization
│ │ │ ├── 1.png
│ │ │ ├── 2.png
│ │ │ └── 3.png
│ │ ├── intro
│ │ │ └── distributed-tracing.png
│ │ └── dynamic-config.svg
│ │ └── toc.yml
├── docset.yml
└── redirects.yml
├── .ci
├── release-wrapper.sh
├── upload-logs.sh
└── release.sh
├── internal-tools
├── agent-rule
│ ├── src
│ │ └── main
│ │ │ └── AndroidManifest.xml
│ └── build.gradle.kts
├── test-common
│ ├── src
│ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ └── java
│ │ │ └── co
│ │ │ └── elastic
│ │ │ └── otel
│ │ │ └── android
│ │ │ └── test
│ │ │ └── common
│ │ │ └── ElasticAttributes.kt
│ └── build.gradle.kts
├── otel-test-common
│ ├── src
│ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ └── java
│ │ │ └── co
│ │ │ └── elastic
│ │ │ └── otel
│ │ │ └── android
│ │ │ └── test
│ │ │ └── processor
│ │ │ └── SimpleProcessorFactory.kt
│ └── build.gradle.kts
├── androidtest-agent-rule
│ ├── src
│ │ └── main
│ │ │ ├── AndroidManifest.xml
│ │ │ └── java
│ │ │ └── co
│ │ │ └── elastic
│ │ │ └── otel
│ │ │ └── android
│ │ │ └── test
│ │ │ └── rule
│ │ │ └── AndroidTestAgentRule.kt
│ └── build.gradle.kts
└── robolectric-agent-rule
│ ├── src
│ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── co
│ │ └── elastic
│ │ └── otel
│ │ └── android
│ │ └── test
│ │ └── rule
│ │ └── RobolectricAgentRule.kt
│ └── build.gradle.kts
├── gradle
├── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
└── instrumentation.versions.toml
├── integration-test
├── app
│ ├── src
│ │ └── main
│ │ │ ├── res
│ │ │ ├── values
│ │ │ │ └── strings.xml
│ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.webp
│ │ │ │ └── ic_launcher_round.webp
│ │ │ ├── mipmap-anydpi-v26
│ │ │ │ ├── ic_launcher.xml
│ │ │ │ └── ic_launcher_round.xml
│ │ │ └── drawable
│ │ │ │ └── ic_launcher_foreground.xml
│ │ │ ├── java
│ │ │ └── co
│ │ │ │ └── elastic
│ │ │ │ └── otel
│ │ │ │ └── android
│ │ │ │ └── integration
│ │ │ │ ├── MyApp.kt
│ │ │ │ └── MainActivity.kt
│ │ │ └── AndroidManifest.xml
│ └── build.gradle.kts
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradle.properties
├── settings.gradle.kts
└── build.gradle.kts
├── agent-api
├── build.gradle.kts
├── metadata
│ └── agent-api.api
└── src
│ └── main
│ └── java
│ └── co
│ └── elastic
│ └── otel
│ └── android
│ └── api
│ ├── ElasticOtelAgent.kt
│ └── flusher
│ ├── MetricFlusher.kt
│ ├── SpanFlusher.kt
│ └── LogRecordFlusher.kt
├── .github
├── labeler-config.yml
├── community-label.yml
├── CODEOWNERS
├── workflows
│ ├── docs-cleanup.yml
│ ├── github-commands-comment.yml
│ ├── docs-build.yml
│ ├── draft-changelog.yml
│ ├── catalog-info.yml
│ ├── test-reporter.yml
│ ├── ci-docs.yml
│ ├── addToProject.yml
│ └── README.md
├── scripts
│ ├── generate-release-notes
│ │ └── sample.json
│ ├── integration-test
│ │ ├── await_port.sh
│ │ └── Makefile
│ ├── bump-minor-version
│ │ └── main.sh
│ └── change-log
│ │ └── draft.sh
├── dependabot.yml
└── actions
│ └── setup
│ └── action.yml
├── instrumentation-test
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── instrumentation
│ ├── okhttp
│ │ ├── src
│ │ │ └── main
│ │ │ │ ├── java
│ │ │ │ └── co
│ │ │ │ │ └── elastic
│ │ │ │ │ └── otel
│ │ │ │ │ └── android
│ │ │ │ │ └── test
│ │ │ │ │ └── MainActivity.kt
│ │ │ │ └── AndroidManifest.xml
│ │ └── build.gradle.kts
│ └── oteladapter
│ │ ├── src
│ │ ├── main
│ │ │ ├── java
│ │ │ │ └── co
│ │ │ │ │ └── elastic
│ │ │ │ │ └── otel
│ │ │ │ │ └── android
│ │ │ │ │ └── test
│ │ │ │ │ └── MainActivity.kt
│ │ │ └── AndroidManifest.xml
│ │ └── androidTest
│ │ │ └── java
│ │ │ └── co
│ │ │ └── elastic
│ │ │ └── otel
│ │ │ └── android
│ │ │ └── test
│ │ │ └── InstrumentationTest.kt
│ │ └── build.gradle.kts
├── buildSrc
│ ├── build.gradle.kts
│ ├── settings.gradle.kts
│ └── src
│ │ └── main
│ │ └── kotlin
│ │ └── elastic.instrumentation-test-app.gradle.kts
├── gradle.properties
├── settings.gradle.kts
└── build.gradle.kts
├── agent-sdk
├── src
│ ├── main
│ │ ├── java
│ │ │ └── co
│ │ │ │ └── elastic
│ │ │ │ └── otel
│ │ │ │ └── android
│ │ │ │ ├── internal
│ │ │ │ ├── package-info.java
│ │ │ │ ├── provider
│ │ │ │ │ ├── StringProvider.kt
│ │ │ │ │ └── Provider.kt
│ │ │ │ ├── services
│ │ │ │ │ ├── Service.kt
│ │ │ │ │ └── network
│ │ │ │ │ │ ├── data
│ │ │ │ │ │ ├── CarrierInfo.kt
│ │ │ │ │ │ └── NetworkType.kt
│ │ │ │ │ │ └── listener
│ │ │ │ │ │ └── NetworkChangeListener.kt
│ │ │ │ ├── opentelemetry
│ │ │ │ │ ├── SignalType.kt
│ │ │ │ │ └── processors
│ │ │ │ │ │ ├── logs
│ │ │ │ │ │ └── LogRecordAttributesProcessor.kt
│ │ │ │ │ │ └── spans
│ │ │ │ │ │ └── SpanAttributesProcessor.kt
│ │ │ │ ├── features
│ │ │ │ │ ├── exportergate
│ │ │ │ │ │ ├── latch
│ │ │ │ │ │ │ └── Latch.kt
│ │ │ │ │ │ ├── GateSpanExporter.kt
│ │ │ │ │ │ └── GateLogRecordExporter.kt
│ │ │ │ │ ├── httpinterceptor
│ │ │ │ │ │ └── HttpSpanExporterInterceptor.kt
│ │ │ │ │ ├── clock
│ │ │ │ │ │ ├── SystemTimeClock.kt
│ │ │ │ │ │ ├── MutableClock.kt
│ │ │ │ │ │ └── ElasticClockBroadcastReceiver.kt
│ │ │ │ │ ├── centralconfig
│ │ │ │ │ │ └── CentralConfiguration.kt
│ │ │ │ │ └── conditionaldrop
│ │ │ │ │ │ ├── ConditionalDropSpanExporter.kt
│ │ │ │ │ │ └── ConditionalDropLogRecordExporter.kt
│ │ │ │ ├── connectivity
│ │ │ │ │ ├── ConnectivityConfiguration.kt
│ │ │ │ │ └── SignalConnectivityChangeListener.kt
│ │ │ │ ├── utilities
│ │ │ │ │ ├── cache
│ │ │ │ │ │ ├── CacheHandler.kt
│ │ │ │ │ │ ├── PreferencesLongCacheHandler.kt
│ │ │ │ │ │ ├── PreferencesStringCacheHandler.kt
│ │ │ │ │ │ └── PreferencesIntegerCacheHandler.kt
│ │ │ │ │ ├── NumberTools.kt
│ │ │ │ │ ├── interceptor
│ │ │ │ │ │ ├── NoopInterceptor.kt
│ │ │ │ │ │ ├── MultiInterceptor.kt
│ │ │ │ │ │ └── MutableInterceptor.kt
│ │ │ │ │ ├── logging
│ │ │ │ │ │ └── AndroidLoggerFactory.kt
│ │ │ │ │ ├── AttributesOverrideLogRecordData.kt
│ │ │ │ │ └── AttributesOverrideSpanData.kt
│ │ │ │ ├── session
│ │ │ │ │ ├── DefaultSession.kt
│ │ │ │ │ └── DefaultSessionProvider.kt
│ │ │ │ ├── time
│ │ │ │ │ ├── SystemTimeProvider.kt
│ │ │ │ │ └── ntp
│ │ │ │ │ │ └── SntpClient.kt
│ │ │ │ ├── api
│ │ │ │ │ └── ManagedElasticOtelAgentContract.kt
│ │ │ │ ├── logging
│ │ │ │ │ ├── SimpleLoggingPolicy.kt
│ │ │ │ │ └── DefaultLoggingPolicy.kt
│ │ │ │ └── exporters
│ │ │ │ │ └── configurable
│ │ │ │ │ └── MutableSpanExporter.kt
│ │ │ │ ├── logging
│ │ │ │ └── LogLevel.kt
│ │ │ │ ├── exporters
│ │ │ │ ├── configuration
│ │ │ │ │ └── ExportProtocol.kt
│ │ │ │ ├── ExporterProvider.kt
│ │ │ │ └── NoopExporterProvider.kt
│ │ │ │ ├── connectivity
│ │ │ │ ├── ExportEndpointConfiguration.kt
│ │ │ │ └── Authentication.kt
│ │ │ │ ├── features
│ │ │ │ ├── session
│ │ │ │ │ ├── Session.kt
│ │ │ │ │ ├── SessionProvider.kt
│ │ │ │ │ └── SessionIdGenerator.kt
│ │ │ │ └── diskbuffering
│ │ │ │ │ └── DiskBufferingConfiguration.kt
│ │ │ │ └── interceptor
│ │ │ │ └── Interceptor.kt
│ │ └── AndroidManifest.xml
│ └── test
│ │ └── java
│ │ └── co
│ │ └── elastic
│ │ └── otel
│ │ └── android
│ │ ├── testutils
│ │ ├── DummySntpClient.kt
│ │ ├── TestUdpServer.kt
│ │ └── NtpUtils.kt
│ │ └── internal
│ │ └── logging
│ │ ├── DefaultLoggingPolicyTest.kt
│ │ └── SimpleLoggingPolicyTest.kt
└── build.gradle.kts
├── agent-plugin
├── src
│ └── main
│ │ └── java
│ │ └── co
│ │ └── elastic
│ │ └── otel
│ │ └── android
│ │ └── plugin
│ │ ├── internal
│ │ ├── package-info.java
│ │ ├── BuildVariantListener.kt
│ │ ├── logging
│ │ │ └── GradleLoggerFactory.kt
│ │ ├── ByteBuddyDependencyAttacher.kt
│ │ └── InstrumentationPlugin.kt
│ │ └── extensions
│ │ ├── BytecodeInstrumentation.kt
│ │ └── ElasticApmExtension.kt
├── metadata
│ └── agent-plugin.api
└── build.gradle.kts
├── gradle.properties
├── .buildkite
├── release.yml
└── README.md
├── shared-rules.pro
├── renovate.json
├── install-android-sdk.sh
├── README.md
├── settings.gradle.kts
├── .gitignore
└── catalog-info.yaml
/.java-version:
--------------------------------------------------------------------------------
1 | 17
--------------------------------------------------------------------------------
/manual_licenses_map.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/agent-common/metadata/agent-common.api:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/checks.sh:
--------------------------------------------------------------------------------
1 | set -e
2 | ./gradlew check
--------------------------------------------------------------------------------
/instrumentation/api/metadata/api.api:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/instrumentation/okhttp/library/metadata/library.api:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/instrumentation/okhttp/bytebuddy/metadata/bytebuddy.api:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/instrumentation/oteladapter/library/metadata/library.api:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/android_tests.sh:
--------------------------------------------------------------------------------
1 | set -e
2 | ./gradlew -p "instrumentation-test" connectedCheck
3 |
--------------------------------------------------------------------------------
/docs/release-notes/toc.yml:
--------------------------------------------------------------------------------
1 | toc:
2 | - file: index.md
3 | - file: known-issues.md
--------------------------------------------------------------------------------
/instrumentation/api/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.ci/release-wrapper.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | set -euo pipefail
3 |
4 | .ci/release.sh | tee release.out
5 |
--------------------------------------------------------------------------------
/internal-tools/agent-rule/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/internal-tools/test-common/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/internal-tools/otel-test-common/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/internal-tools/androidtest-agent-rule/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/internal-tools/robolectric-agent-rule/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/integration-test/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | EDOT Integration
3 |
--------------------------------------------------------------------------------
/agent-api/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.java-library")
3 | }
4 |
5 | dependencies {
6 | api(libs.opentelemetry.sdk)
7 | }
--------------------------------------------------------------------------------
/.github/labeler-config.yml:
--------------------------------------------------------------------------------
1 | # add 'agent-ios' and 'agent-mobile' label to all new issues
2 | agent-android:
3 | - '.*'
4 | agent-mobile:
5 | - '.*'
--------------------------------------------------------------------------------
/.github/community-label.yml:
--------------------------------------------------------------------------------
1 | # add 'community' label to all new issues and PRs created by the community
2 | community:
3 | - '.*'
4 | triage:
5 | - '.*'
--------------------------------------------------------------------------------
/integration-test/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/integration-test/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/integration-test/gradle.properties:
--------------------------------------------------------------------------------
1 | description=Integration application for EDOT Android
2 | org.gradle.jvmargs=-XX\:MaxMetaspaceSize\=2G
3 | android.useAndroidX=true
--------------------------------------------------------------------------------
/instrumentation-test/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/instrumentation-test/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/docs/reference/edot-android/images/opentelemetry-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/docs/reference/edot-android/images/opentelemetry-logo.png
--------------------------------------------------------------------------------
/internal-tools/test-common/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.android-test-library")
3 | }
4 |
5 | dependencies {
6 | implementation(libs.opentelemetry.sdk)
7 | }
--------------------------------------------------------------------------------
/docs/reference/edot-android/images/find-export-endpoint/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/docs/reference/edot-android/images/find-export-endpoint/1.png
--------------------------------------------------------------------------------
/docs/reference/edot-android/images/find-export-endpoint/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/docs/reference/edot-android/images/find-export-endpoint/2.png
--------------------------------------------------------------------------------
/docs/reference/edot-android/images/find-export-endpoint/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/docs/reference/edot-android/images/find-export-endpoint/3.png
--------------------------------------------------------------------------------
/docs/reference/edot-android/images/find-export-endpoint/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/docs/reference/edot-android/images/find-export-endpoint/4.png
--------------------------------------------------------------------------------
/docs/reference/edot-android/images/span-visualization/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/docs/reference/edot-android/images/span-visualization/1.png
--------------------------------------------------------------------------------
/docs/reference/edot-android/images/span-visualization/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/docs/reference/edot-android/images/span-visualization/2.png
--------------------------------------------------------------------------------
/docs/reference/edot-android/images/span-visualization/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/docs/reference/edot-android/images/span-visualization/3.png
--------------------------------------------------------------------------------
/agent-common/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.java-library")
3 | }
4 |
5 | dependencies {
6 | api(libs.slf4j.api)
7 | implementation(libs.androidx.annotations)
8 | }
--------------------------------------------------------------------------------
/integration-test/app/src/main/res/mipmap-hdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/integration-test/app/src/main/res/mipmap-hdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/integration-test/app/src/main/res/mipmap-mdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/integration-test/app/src/main/res/mipmap-mdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/integration-test/app/src/main/res/mipmap-xhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/integration-test/app/src/main/res/mipmap-xhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/docs/reference/edot-android/images/intro/distributed-tracing.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/docs/reference/edot-android/images/intro/distributed-tracing.png
--------------------------------------------------------------------------------
/integration-test/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/integration-test/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/integration-test/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/integration-test/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp
--------------------------------------------------------------------------------
/integration-test/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/integration-test/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/integration-test/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/integration-test/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/integration-test/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/integration-test/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/integration-test/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/integration-test/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/integration-test/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/elastic/apm-agent-android/main/integration-test/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp
--------------------------------------------------------------------------------
/internal-tools/otel-test-common/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.android-test-library")
3 | }
4 |
5 | dependencies {
6 | api(project(":agent-sdk"))
7 | api(libs.opentelemetry.testing)
8 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/package-info.java:
--------------------------------------------------------------------------------
1 | @InternalApi
2 | package co.elastic.otel.android.internal;
3 |
4 | import co.elastic.otel.android.common.internal.annotations.InternalApi;
5 |
--------------------------------------------------------------------------------
/instrumentation-test/instrumentation/okhttp/src/main/java/co/elastic/otel/android/test/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package co.elastic.otel.android.test
2 |
3 | import android.app.Activity
4 |
5 | class MainActivity : Activity()
--------------------------------------------------------------------------------
/instrumentation/okhttp/bytebuddy/src/main/resources/META-INF/net.bytebuddy/build.plugins:
--------------------------------------------------------------------------------
1 | co.elastic.otel.android.okhttp.internal.OkHttpClientPlugin
2 | co.elastic.otel.android.okhttp.internal.callback.OkHttpCallbackPlugin
--------------------------------------------------------------------------------
/instrumentation-test/buildSrc/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | `kotlin-dsl`
3 | }
4 |
5 | dependencies {
6 | implementation(rootLibs.kotlin.plugin)
7 | implementation(rootLibs.android.plugin)
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | *.md @elastic/ingest-docs @elastic/apm-agent-approvers
2 | /docs/ @elastic/ingest-docs @elastic/apm-agent-approvers
3 |
4 | /.github/actions @elastic/observablt-ci
5 | /.github/workflows @elastic/observablt-ci
6 |
--------------------------------------------------------------------------------
/agent-common/src/main/java/co/elastic/otel/android/common/internal/package-info.java:
--------------------------------------------------------------------------------
1 | @InternalApi
2 | package co.elastic.otel.android.common.internal;
3 |
4 | import co.elastic.otel.android.common.internal.annotations.InternalApi;
5 |
--------------------------------------------------------------------------------
/agent-plugin/src/main/java/co/elastic/otel/android/plugin/internal/package-info.java:
--------------------------------------------------------------------------------
1 | @InternalApi
2 | package co.elastic.otel.android.plugin.internal;
3 |
4 | import co.elastic.otel.android.common.internal.annotations.InternalApi;
5 |
--------------------------------------------------------------------------------
/internal-tools/robolectric-agent-rule/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.android-test-library")
3 | }
4 |
5 | dependencies {
6 | api(project(":internal-tools:agent-rule"))
7 | implementation(libs.robolectric)
8 | }
--------------------------------------------------------------------------------
/.ci/upload-logs.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | ## This script uploads the given logs to a google bucket
3 | ##
4 |
5 | # Let's avoid failing the build
6 | set +e
7 |
8 | ls -l $1 || true
9 | echo 'TBC upload artifacts to google'
10 |
--------------------------------------------------------------------------------
/instrumentation/okhttp/library/src/main/java/co/elastic/otel/android/okhttp/internal/package-info.java:
--------------------------------------------------------------------------------
1 | @InternalApi
2 | package co.elastic.otel.android.okhttp.internal;
3 |
4 | import co.elastic.otel.android.common.internal.annotations.InternalApi;
--------------------------------------------------------------------------------
/instrumentation/okhttp/bytebuddy/src/main/java/co/elastic/otel/android/okhttp/internal/package-info.java:
--------------------------------------------------------------------------------
1 | @InternalApi
2 | package co.elastic.otel.android.okhttp.internal;
3 |
4 | import co.elastic.otel.android.common.internal.annotations.InternalApi;
--------------------------------------------------------------------------------
/instrumentation/api/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.android-library")
3 | }
4 |
5 | android {
6 | namespace = "co.elastic.otel.android.instrumentation.api"
7 | }
8 |
9 | dependencies {
10 | api(project(":agent-api"))
11 | }
--------------------------------------------------------------------------------
/instrumentation/api/src/main/java/co/elastic/otel/android/instrumentation/internal/package-info.java:
--------------------------------------------------------------------------------
1 | @InternalApi
2 | package co.elastic.otel.android.instrumentation.internal;
3 |
4 | import co.elastic.otel.android.common.internal.annotations.InternalApi;
--------------------------------------------------------------------------------
/instrumentation/oteladapter/library/src/main/java/co/elastic/otel/android/oteladapter/internal/package-info.java:
--------------------------------------------------------------------------------
1 | @InternalApi
2 | package co.elastic.otel.android.oteladapter.internal;
3 |
4 | import co.elastic.otel.android.common.internal.annotations.InternalApi;
--------------------------------------------------------------------------------
/internal-tools/agent-rule/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.android-test-library")
3 | }
4 |
5 | dependencies {
6 | implementation(project(":agent-sdk"))
7 | implementation(project(":internal-tools:test-common"))
8 | implementation(libs.opentelemetry.testing)
9 | }
--------------------------------------------------------------------------------
/internal-tools/androidtest-agent-rule/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.android-test-library")
3 | }
4 |
5 | dependencies {
6 | api(project(":internal-tools:agent-rule"))
7 | api(instrumentation.bundles.androidTest)
8 | api(libs.opentelemetry.testing)
9 | api(libs.assertj)
10 | }
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/instrumentation/okhttp/plugin/metadata/plugin.api:
--------------------------------------------------------------------------------
1 | public final class co/elastic/otel/android/okhttp/OkHttpInstrumentationPlugin : co/elastic/otel/android/plugin/internal/InstrumentationPlugin {
2 | public fun ()V
3 | public fun onApply (Lorg/gradle/api/Project;Lco/elastic/otel/android/plugin/ElasticAgentPlugin;)V
4 | }
5 |
6 |
--------------------------------------------------------------------------------
/integration-test/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/instrumentation-test/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 |
--------------------------------------------------------------------------------
/instrumentation-test/instrumentation/oteladapter/src/main/java/co/elastic/otel/android/test/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package co.elastic.otel.android.test
2 |
3 | import android.app.Activity
4 | import android.util.Log
5 |
6 | class MainActivity : Activity() {
7 |
8 | fun sendLog() {
9 | Log.d("elastic", "My log")
10 | }
11 | }
--------------------------------------------------------------------------------
/instrumentation/oteladapter/plugin/metadata/plugin.api:
--------------------------------------------------------------------------------
1 | public final class co/elastic/otel/android/oteladapter/ExperimentalOtelAdapterPlugin : co/elastic/otel/android/plugin/internal/InstrumentationPlugin {
2 | public fun ()V
3 | public fun onApply (Lorg/gradle/api/Project;Lco/elastic/otel/android/plugin/ElasticAgentPlugin;)V
4 | }
5 |
6 |
--------------------------------------------------------------------------------
/integration-test/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.github/workflows/docs-cleanup.yml:
--------------------------------------------------------------------------------
1 | name: docs-cleanup
2 |
3 | on:
4 | pull_request_target:
5 | types:
6 | - closed
7 |
8 | jobs:
9 | docs-preview:
10 | uses: elastic/docs-builder/.github/workflows/preview-cleanup.yml@main
11 | permissions:
12 | contents: none
13 | id-token: write
14 | deployments: write
--------------------------------------------------------------------------------
/integration-test/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.github/scripts/generate-release-notes/sample.json:
--------------------------------------------------------------------------------
1 | {
2 | "features_enhancements": [
3 | {
4 | "prId": 340,
5 | "message": "Bumping upstream libs"
6 | },
7 | {
8 | "message": "Adding consumer R8 rules"
9 | }
10 | ],
11 | "fixes": [
12 | {
13 | "prId": 319,
14 | "message": "HTTP exporting"
15 | }
16 | ]
17 | }
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | #Mon Jul 29 12:17:40 UTC 2024
2 | description=OpenTelemetry Android agent for the Elastic stack
3 | org.gradle.jvmargs=-XX\:MaxMetaspaceSize\=2G
4 | version=1.5.0
5 | android.useAndroidX=true
6 | elastic.android.minSdk=21
7 | elastic.android.compileSdk=36
8 | elastic.java.compatibility=11
9 | elastic.kotlin.compatibility=1.9
10 | group=co.elastic.otel.android
11 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | ---
2 | version: 2
3 | updates:
4 |
5 | # GitHub actions
6 | - package-ecosystem: "github-actions"
7 | directories:
8 | - "/"
9 | - "/.github/actions/*"
10 | schedule:
11 | interval: "weekly"
12 | day: "sunday"
13 | time: "22:00"
14 | groups:
15 | github-actions:
16 | patterns:
17 | - "*"
18 |
--------------------------------------------------------------------------------
/instrumentation/okhttp/bytebuddy/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.instrumentation-library")
3 | }
4 |
5 | android {
6 | namespace = "co.elastic.otel.android.instrumentation.okhttp.bytebuddy"
7 | }
8 |
9 | dependencies {
10 | implementation(project(":instrumentation:okhttp:library"))
11 | implementation(libs.byteBuddy)
12 | implementation(libs.okhttp)
13 | }
--------------------------------------------------------------------------------
/.github/workflows/github-commands-comment.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: github-commands-comment
3 |
4 | on:
5 | pull_request_target:
6 | types:
7 | - opened
8 |
9 | permissions:
10 | contents: read
11 |
12 | jobs:
13 | comment:
14 | runs-on: ubuntu-latest
15 | permissions:
16 | pull-requests: write
17 | steps:
18 | - uses: elastic/oblt-actions/elastic/github-commands@v1
19 |
--------------------------------------------------------------------------------
/instrumentation-test/gradle.properties:
--------------------------------------------------------------------------------
1 | # AndroidX package structure to make it clearer which packages are bundled with the
2 | # Android operating system, and which are packaged with your app"s APK
3 | # https://developer.android.com/topic/libraries/support-library/androidx-rn
4 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
5 | android.useAndroidX=true
--------------------------------------------------------------------------------
/docs/reference/edot-android/toc.yml:
--------------------------------------------------------------------------------
1 | toc:
2 | - file: index.md
3 | - file: getting-started.md
4 | - file: configuration.md
5 | - file: manual-instrumentation.md
6 | - file: automatic-instrumentation.md
7 | - title: Troubleshooting
8 | crosslink: docs-content://troubleshoot/ingest/opentelemetry/edot-sdks/android/index.md
9 | - title: Release notes
10 | crosslink: apm-agent-android://release-notes/index.md
--------------------------------------------------------------------------------
/.github/workflows/docs-build.yml:
--------------------------------------------------------------------------------
1 | name: docs-build
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request_target: ~
8 |
9 | jobs:
10 | docs-preview:
11 | uses: elastic/docs-builder/.github/workflows/preview-build.yml@main
12 | with:
13 | path-pattern: docs/**
14 | permissions:
15 | deployments: write
16 | id-token: write
17 | contents: read
18 | pull-requests: write
--------------------------------------------------------------------------------
/.github/workflows/draft-changelog.yml:
--------------------------------------------------------------------------------
1 | name: Draft CHANGELOG entries for a release
2 |
3 | on:
4 | workflow_dispatch:
5 |
6 | permissions:
7 | contents: read
8 |
9 | jobs:
10 | create_draft:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v6
14 | with:
15 | fetch-depth: 0
16 | - name: Run changelog draft script
17 | run: ./.github/scripts/change-log/draft.sh
18 |
--------------------------------------------------------------------------------
/.buildkite/release.yml:
--------------------------------------------------------------------------------
1 | agents:
2 | provider: "gcp"
3 | image: "family/apm-agent-android-ubuntu-2204"
4 |
5 | env:
6 | TARBALL_FILE: ${TARBALL_FILE:-dist.tar}
7 |
8 | steps:
9 | - label: "Run the release"
10 | key: "release"
11 | commands: .ci/release-wrapper.sh
12 | artifact_paths:
13 | - "release.out"
14 | - "${TARBALL_FILE}"
15 |
16 | notify:
17 | - slack:
18 | channels:
19 | - "#apm-agent-mobile"
20 |
--------------------------------------------------------------------------------
/instrumentation-test/instrumentation/okhttp/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.instrumentation-test-app")
3 | id("co.elastic.otel.android.agent")
4 | id("co.elastic.otel.android.instrumentation.okhttp")
5 | }
6 |
7 | android {
8 | namespace = "co.elastic.otel.android.test.okhttp"
9 | }
10 |
11 | dependencies {
12 | androidTestImplementation(libs.okhttp)
13 | androidTestImplementation(instrumentation.mockWebServer)
14 | }
--------------------------------------------------------------------------------
/instrumentation/okhttp/plugin/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.instrumentation-plugin")
3 | }
4 |
5 | elasticBuildConfig {
6 | libraryUri()
7 | byteBuddyPluginUri()
8 | }
9 |
10 | elasticInstrumentationPlugins {
11 | create {
12 | implementationClass = "co.elastic.otel.android.okhttp.OkHttpInstrumentationPlugin"
13 | displayName = "Elastic OTel Android instrumentation for tracking OkHttp requests"
14 | }
15 | }
--------------------------------------------------------------------------------
/.github/workflows/catalog-info.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: catalog-info
3 |
4 | on:
5 | pull_request:
6 | branches:
7 | - main
8 | paths:
9 | - 'catalog-info.yaml'
10 |
11 | permissions:
12 | contents: read
13 |
14 | jobs:
15 | validate:
16 | runs-on: ubuntu-latest
17 | permissions:
18 | contents: read
19 | packages: read
20 | steps:
21 | - uses: actions/checkout@v6
22 |
23 | - uses: elastic/oblt-actions/elastic/validate-catalog@v1
24 |
25 |
--------------------------------------------------------------------------------
/instrumentation/okhttp/library/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.instrumentation-library")
3 | }
4 |
5 | android {
6 | namespace = "co.elastic.otel.android.instrumentation.okhttp"
7 | }
8 |
9 | dependencies {
10 | implementation(instrumentation.opentelemetry.instrumentation.api)
11 | implementation(instrumentation.opentelemetry.instrumentation.api.incubator)
12 | implementation(instrumentation.opentelemetry.instrumentation.okhttp)
13 | compileOnly(libs.okhttp)
14 | }
--------------------------------------------------------------------------------
/instrumentation/oteladapter/plugin/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.instrumentation-plugin")
3 | }
4 |
5 | elasticBuildConfig {
6 | libraryUri()
7 | }
8 |
9 | elasticInstrumentationPlugins {
10 | create(extraTags = listOf("experimental")) {
11 | implementationClass = "co.elastic.otel.android.oteladapter.ExperimentalOtelAdapterPlugin"
12 | displayName =
13 | "Elastic OTel Android experimental instrumentation adapter for OTel Android instrumentations"
14 | }
15 | }
--------------------------------------------------------------------------------
/instrumentation/oteladapter/library/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.instrumentation-library")
3 | }
4 |
5 | android {
6 | namespace = "co.elastic.otel.android.instrumentation.oteladapter"
7 | }
8 |
9 | dependencies {
10 | implementation(instrumentation.opentelemetry.android.session)
11 | implementation(instrumentation.opentelemetry.android.instrumentation)
12 | implementation(instrumentation.opentelemetry.instrumentation.api.incubator)
13 | implementation(instrumentation.weakLockFree)
14 | }
--------------------------------------------------------------------------------
/internal-tools/robolectric-agent-rule/src/main/java/co/elastic/otel/android/test/rule/RobolectricAgentRule.kt:
--------------------------------------------------------------------------------
1 | package co.elastic.otel.android.test.rule
2 |
3 | import android.app.Application
4 | import org.robolectric.RuntimeEnvironment
5 |
6 | class RobolectricAgentRule : AgentRule() {
7 |
8 | override fun runInitialization(initialization: () -> Unit) {
9 | initialization()
10 | }
11 |
12 | override fun getApplication(): Application {
13 | return RuntimeEnvironment.getApplication()
14 | }
15 | }
--------------------------------------------------------------------------------
/instrumentation-test/buildSrc/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | mavenCentral()
4 | google()
5 | gradlePluginPortal()
6 | }
7 | }
8 | dependencyResolutionManagement {
9 | versionCatalogs {
10 | create("rootLibs") {
11 | from(files("../../gradle/libs.versions.toml"))
12 | }
13 | }
14 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
15 | repositories {
16 | mavenCentral()
17 | google()
18 | gradlePluginPortal()
19 | }
20 | }
--------------------------------------------------------------------------------
/.github/scripts/integration-test/await_port.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 | port_to_wait=$1
4 | max_seconds_to_wait=$2
5 | waited_seconds=0
6 | timedout=0
7 | while ! nc -z localhost "$port_to_wait"; do
8 | if [ $waited_seconds == "$max_seconds_to_wait" ]; then
9 | timedout=1
10 | break
11 | fi
12 | echo "$waited_seconds/$max_seconds_to_wait seconds waiting for port $port_to_wait to open"
13 | sleep 1
14 | waited_seconds=$((waited_seconds+1))
15 | done
16 | if [ $timedout == 1 ]; then
17 | echo "Timeout waiting for the port $port_to_wait to open"
18 | exit 1
19 | fi
20 |
--------------------------------------------------------------------------------
/shared-rules.pro:
--------------------------------------------------------------------------------
1 | -keepclassmembers enum io.opentelemetry.** {
2 | public static **[] values();
3 | }
4 | -keepclassmembers enum co.elastic.otel.android.** {
5 | public static **[] values();
6 | }
7 | -keep class io.opentelemetry.api.incubator.** { *; }
8 | -dontwarn com.fasterxml.jackson.**
9 | -dontwarn com.google.auto.service.AutoService
10 | -dontwarn com.google.auto.value.**
11 | -dontwarn com.google.common.io.ByteStreams
12 | -dontwarn com.google.errorprone.annotations.**
13 | -dontwarn io.grpc.**
14 | -dontwarn java.awt.**
15 | -dontwarn javax.json.bind.spi.JsonbProvider
16 |
--------------------------------------------------------------------------------
/.github/scripts/bump-minor-version/main.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | bump_minor_version() {
4 | local version="$1"
5 |
6 | if [[ $version =~ ^([0-9]+)\.([0-9]+)[0-9\.]*$ ]]; then
7 | local major_version=${BASH_REMATCH[1]}
8 | local minor_version=${BASH_REMATCH[2]}
9 |
10 | local new_minor_version=$((minor_version + 1))
11 | local new_version="$major_version.$new_minor_version.0"
12 |
13 | echo "$new_version"
14 | else
15 | echo "Could not find minor version in: $version" >&2
16 | return 1
17 | fi
18 | }
19 |
20 | bump_minor_version "$1"
21 |
--------------------------------------------------------------------------------
/instrumentation-test/instrumentation/okhttp/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/instrumentation-test/instrumentation/oteladapter/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.instrumentation-test-app")
3 | id("co.elastic.otel.android.agent")
4 | id("co.elastic.otel.android.instrumentation.oteladapter")
5 | }
6 |
7 | android {
8 | namespace = "co.elastic.otel.android.test.oteladapter"
9 | }
10 |
11 | val logInstrumentationVersion = "0.11.0-alpha"
12 | dependencies {
13 | implementation("io.opentelemetry.android.instrumentation:android-log-library:$logInstrumentationVersion")
14 | byteBuddy("io.opentelemetry.android.instrumentation:android-log-agent:$logInstrumentationVersion")
15 | }
--------------------------------------------------------------------------------
/integration-test/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | mavenCentral()
4 | google()
5 | gradlePluginPortal()
6 | }
7 | }
8 | dependencyResolutionManagement {
9 | versionCatalogs {
10 | create("rootLibs") {
11 | from(files("../gradle/libs.versions.toml"))
12 | }
13 | }
14 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
15 | repositories {
16 | mavenCentral()
17 | google()
18 | }
19 | }
20 | rootProject.name = "EDOT Android ES integration test"
21 | includeBuild("..")
22 | include(":app")
23 |
--------------------------------------------------------------------------------
/instrumentation-test/instrumentation/oteladapter/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/integration-test/app/src/main/java/co/elastic/otel/android/integration/MyApp.kt:
--------------------------------------------------------------------------------
1 | package co.elastic.otel.android.integration
2 |
3 | import android.app.Application
4 | import co.elastic.otel.android.ElasticApmAgent
5 | import co.elastic.otel.android.api.ElasticOtelAgent
6 |
7 | class MyApp : Application() {
8 | companion object {
9 | internal lateinit var agent: ElasticOtelAgent
10 | }
11 |
12 | override fun onCreate() {
13 | super.onCreate()
14 | agent = ElasticApmAgent.builder(this)
15 | .setExportUrl("http://10.0.2.2:4318")
16 | .setServiceName("integration-test-app")
17 | .build()
18 | }
19 | }
--------------------------------------------------------------------------------
/.github/actions/setup/action.yml:
--------------------------------------------------------------------------------
1 | ---
2 |
3 | name: common build tasks
4 | description: Install specific JDK
5 |
6 | inputs:
7 | java-version:
8 | description: 'Testing Java version'
9 | required: true
10 | default: '17'
11 | java-distribution:
12 | description: 'Testing Java distribution'
13 | required: true
14 | default: 'temurin'
15 | shell:
16 | description: 'Default shell'
17 | default: 'bash'
18 | required: false
19 |
20 | runs:
21 | using: "composite"
22 | steps:
23 | - name: Set up testing JDK
24 | uses: actions/setup-java@v5
25 | with:
26 | java-version: ${{ inputs.java-version }}
27 | distribution: ${{ inputs.java-distribution }}
28 |
--------------------------------------------------------------------------------
/.buildkite/README.md:
--------------------------------------------------------------------------------
1 | # Buildkite
2 |
3 | This README provides an overview of the Buildkite pipeline to automate the build and publishing process.
4 |
5 | ## Release pipeline
6 |
7 | The Buildkite pipeline for the APM Agent Android is responsible for the releases.
8 |
9 | ### Pipeline Configuration
10 |
11 | To view the pipeline and its configuration, click [here](https://buildkite.com/elastic/apm-agent-android-release) or
12 | go to the definition in the `elastic/ci` repository.
13 |
14 | ### Credentials
15 |
16 | The release team provides the credentials to publish the artifacts in Maven Central/Gradle Plugin and sign them
17 | with the GPG.
18 |
19 | If further details are needed, please go to [pre-command](hooks/pre-command).
20 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/docs/docset.yml:
--------------------------------------------------------------------------------
1 | project: 'APM Android agent docs'
2 | products:
3 | - id: apm-agent
4 | cross_links:
5 | - docs-content
6 | - opentelemetry
7 | - elastic-agent
8 | - apm-agent-android
9 | toc:
10 | - toc: release-notes
11 | - toc: reference/edot-android
12 | subs:
13 | motlp: Elastic Cloud Managed OTLP Endpoint
14 | edot: Elastic Distribution of OpenTelemetry
15 | ecloud: "Elastic Cloud"
16 | edot-cf: "EDOT Cloud Forwarder"
17 | ech: "Elastic Cloud Hosted"
18 | ess: "Elasticsearch Service"
19 | ece: "Elastic Cloud Enterprise"
20 | serverless-full: "Elastic Cloud Serverless"
21 | agent: "Elastic Agent"
22 | agents: "Elastic Agents"
23 | stack: "Elastic Stack"
24 | es: "Elasticsearch"
25 | kib: "Kibana"
26 | ls: "Logstash"
27 |
28 |
--------------------------------------------------------------------------------
/integration-test/app/src/main/java/co/elastic/otel/android/integration/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package co.elastic.otel.android.integration
2 |
3 | import android.app.Activity
4 | import android.os.Bundle
5 | import co.elastic.otel.android.extensions.log
6 | import co.elastic.otel.android.extensions.span
7 | import co.elastic.otel.android.integration.MyApp.Companion.agent
8 |
9 | class MainActivity : Activity() {
10 |
11 | override fun onCreate(savedInstanceState: Bundle?) {
12 | super.onCreate(savedInstanceState)
13 |
14 | val meter = agent.getOpenTelemetry().getMeter("co.elastic.android.integration")
15 | meter.counterBuilder("meter counter").build().add(5)
16 |
17 | agent.span("span name") {
18 | agent.log("log body")
19 | }
20 | }
21 | }
--------------------------------------------------------------------------------
/agent-api/metadata/agent-api.api:
--------------------------------------------------------------------------------
1 | public abstract interface class co/elastic/otel/android/api/ElasticOtelAgent : java/io/Closeable {
2 | public abstract fun getOpenTelemetry ()Lio/opentelemetry/api/OpenTelemetry;
3 | }
4 |
5 | public abstract interface class co/elastic/otel/android/api/flusher/LogRecordFlusher {
6 | public abstract fun flushLogRecords ()Lio/opentelemetry/sdk/common/CompletableResultCode;
7 | }
8 |
9 | public abstract interface class co/elastic/otel/android/api/flusher/MetricFlusher {
10 | public abstract fun flushMetrics ()Lio/opentelemetry/sdk/common/CompletableResultCode;
11 | }
12 |
13 | public abstract interface class co/elastic/otel/android/api/flusher/SpanFlusher {
14 | public abstract fun flushSpans ()Lio/opentelemetry/sdk/common/CompletableResultCode;
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/internal-tools/androidtest-agent-rule/src/main/java/co/elastic/otel/android/test/rule/AndroidTestAgentRule.kt:
--------------------------------------------------------------------------------
1 | package co.elastic.otel.android.test.rule
2 |
3 | import android.annotation.SuppressLint
4 | import android.app.Application
5 | import androidx.test.internal.runner.junit4.statement.UiThreadStatement.runOnUiThread
6 | import androidx.test.platform.app.InstrumentationRegistry
7 |
8 | class AndroidTestAgentRule : AgentRule() {
9 |
10 | @SuppressLint("RestrictedApi")
11 | override fun runInitialization(initialization: () -> Unit) {
12 | runOnUiThread {
13 | initialization()
14 | }
15 | }
16 |
17 | override fun getApplication(): Application {
18 | return InstrumentationRegistry.getInstrumentation().targetContext.applicationContext as Application
19 | }
20 | }
--------------------------------------------------------------------------------
/integration-test/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
11 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/.github/workflows/test-reporter.yml:
--------------------------------------------------------------------------------
1 | ---
2 | ## Workflow to process the JUnit test results and add a report to the checks.
3 | name: test-reporter
4 | on:
5 | workflow_run:
6 | workflows:
7 | - ci
8 | - release
9 | - snapshoty
10 | types:
11 | - completed
12 |
13 | permissions:
14 | contents: read
15 | actions: read
16 | checks: write
17 |
18 | jobs:
19 | report:
20 | runs-on: ubuntu-latest
21 | steps:
22 | - uses: elastic/oblt-actions/test-report@v1
23 | with:
24 | artifact: /test-results(.*)/ # artifact name pattern
25 | name: 'Test Report $1' # Name of the check run which will be created
26 | path: "**/*.xml" # Path to test results (inside artifact .zip)
27 | reporter: java-junit # Format of test results
28 |
--------------------------------------------------------------------------------
/agent-plugin/metadata/agent-plugin.api:
--------------------------------------------------------------------------------
1 | public final class co/elastic/otel/android/plugin/ElasticAgentPlugin : org/gradle/api/Plugin {
2 | public fun ()V
3 | public final fun addBuildVariantListener (Lco/elastic/otel/android/plugin/internal/BuildVariantListener;)V
4 | public synthetic fun apply (Ljava/lang/Object;)V
5 | public fun apply (Lorg/gradle/api/Project;)V
6 | }
7 |
8 | public abstract interface class co/elastic/otel/android/plugin/extensions/BytecodeInstrumentation {
9 | public abstract fun getDisableForBuildTypes ()Lorg/gradle/api/provider/ListProperty;
10 | }
11 |
12 | public abstract class co/elastic/otel/android/plugin/extensions/ElasticApmExtension {
13 | public fun (Lorg/gradle/api/model/ObjectFactory;)V
14 | public final fun bytecodeInstrumentation (Lorg/gradle/api/Action;)V
15 | public final fun getBytecodeInstrumentation ()Lco/elastic/otel/android/plugin/extensions/BytecodeInstrumentation;
16 | }
17 |
18 |
--------------------------------------------------------------------------------
/integration-test/app/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
2 |
3 | plugins {
4 | id("com.android.application")
5 | id("org.jetbrains.kotlin.android")
6 | id("co.elastic.otel.android.agent")
7 | id("co.elastic.otel.android.instrumentation.okhttp")
8 | }
9 |
10 | android {
11 | namespace = "co.elastic.otel.android.integration"
12 | compileSdk = 36
13 |
14 | defaultConfig {
15 | applicationId = "co.elastic.otel.android.integration"
16 | minSdk = 26
17 | }
18 |
19 | buildTypes {
20 | release {
21 | isMinifyEnabled = true
22 | signingConfig = signingConfigs["debug"]
23 | }
24 | }
25 | compileOptions {
26 | sourceCompatibility = JavaVersion.VERSION_1_8
27 | targetCompatibility = JavaVersion.VERSION_1_8
28 | }
29 | }
30 | kotlin {
31 | compilerOptions {
32 | jvmTarget.set(JvmTarget.JVM_1_8)
33 | }
34 | }
--------------------------------------------------------------------------------
/agent-plugin/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.java-library")
3 | id("java-gradle-plugin")
4 | id("com.github.gmazzo.buildconfig")
5 | }
6 |
7 | dependencies {
8 | api(project(":agent-common"))
9 | implementation(libs.byteBuddy)
10 | implementation(libs.byteBuddy.plugin)
11 | compileOnly(libs.android.plugin)
12 | }
13 |
14 | buildConfig {
15 | packageName("${group}.generated")
16 | buildConfigField("String", "SDK_DEPENDENCY_URI", "\"$group:agent-sdk:$version\"")
17 | }
18 |
19 | gradlePlugin {
20 | plugins {
21 | create("elasticAndroidAgent") {
22 | id = "co.elastic.otel.android.agent"
23 | implementationClass = "co.elastic.otel.android.plugin.ElasticAgentPlugin"
24 | displayName = "Elastic OTel Android Agent"
25 | description = project.description
26 | tags.addAll("Android", "APM", "Elastic", "ELK", "opentelemetry")
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/docs/redirects.yml:
--------------------------------------------------------------------------------
1 | # Related to https://github.com/elastic/opentelemetry/issues/228
2 | redirects:
3 | 'release-notes/apm/agents/android/index.md': 'release-notes/index.md'
4 | 'reference/apm/agents/android/index.md': 'reference/edot-android/index.md'
5 | 'reference/apm/agents/android/getting-started.md': 'reference/edot-android/getting-started.md'
6 | 'reference/apm/agents/android/configuration.md': 'reference/edot-android/configuration.md'
7 | 'reference/apm/agents/android/manual-instrumentation.md': 'reference/edot-android/manual-instrumentation.md'
8 | 'reference/apm/agents/android/automatic-instrumentation.md': 'reference/edot-android/automatic-instrumentation.md'
9 | 'reference/apm/agents/android/faq.md': 'reference/edot-android/index.md'
10 | 'reference/apm/agents/android/how-tos.md': 'reference/edot-android/getting-started.md'
11 | 'reference/apm/agents/android/troubleshooting': 'opentelemetry://reference/edot-sdks/android/troubleshooting.md'
12 |
--------------------------------------------------------------------------------
/internal-tools/test-common/src/main/java/co/elastic/otel/android/test/common/ElasticAttributes.kt:
--------------------------------------------------------------------------------
1 | package co.elastic.otel.android.test.common
2 |
3 | import io.opentelemetry.api.common.Attributes
4 |
5 | object ElasticAttributes {
6 | const val DEFAULT_SESSION_ID = "session-id"
7 | const val DEFAULT_NETWORK_CONNECTION_TYPE = "unavailable"
8 |
9 | fun getLogRecordDefaultAttributes(
10 | sessionId: String = DEFAULT_SESSION_ID,
11 | networkConnectionType: String = DEFAULT_NETWORK_CONNECTION_TYPE
12 | ): Attributes =
13 | Attributes.builder()
14 | .put("session.id", sessionId)
15 | .put("network.connection.type", networkConnectionType)
16 | .build()
17 |
18 | fun getSpanDefaultAttributes(logRecordAttributes: Attributes = getLogRecordDefaultAttributes()): Attributes =
19 | Attributes.builder()
20 | .putAll(logRecordAttributes)
21 | .put("type", "mobile")
22 | .build()
23 | }
--------------------------------------------------------------------------------
/docs/reference/edot-android/images/dynamic-config.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.github/scripts/change-log/draft.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash -e
2 |
3 | version=$(cat gradle.properties | grep version= | sed s/version=//g)
4 |
5 | if [[ $version =~ ([0-9]+)\.([0-9]+)\.0 ]]; then
6 | echo "Version found: ${version}"
7 | major="${BASH_REMATCH[1]}"
8 | minor="${BASH_REMATCH[2]}"
9 | else
10 | echo "unexpected version: $version"
11 | exit 1
12 | fi
13 |
14 | if [[ $minor == 0 ]]; then
15 | prior_major=$((major - 1))
16 | prior_minor=$(sed -n "s/^## Version $prior_major\.\([0-9]\+\)\..*/\1/p" CHANGELOG.md | head -1)
17 | if [[ -z $prior_minor ]]; then
18 | # assuming this is the first release
19 | range=
20 | else
21 | range="v$prior_major.$prior_minor.0..HEAD"
22 | fi
23 | else
24 | range="v$major.$((minor - 1)).0..HEAD"
25 | fi
26 |
27 | echo "[$(
28 | git log --reverse \
29 | --perl-regexp \
30 | --author='^((?!elastic-renovate).*)$' \
31 | --pretty=format:"%s" \
32 | "$range" \
33 | | sed -r 's;^(.+) \(#([0-9]+)\)$;{"message":"\1", "prId":"\2"},;g' \
34 | | sed '$ s/,$//g'
35 | )]"
--------------------------------------------------------------------------------
/docs/release-notes/known-issues.md:
--------------------------------------------------------------------------------
1 | ---
2 | navigation_title: "Known issues"
3 | description: Known issues for the Elastic Distribution of OpenTelemetry Android.
4 | applies_to:
5 | stack:
6 | serverless:
7 | observability:
8 | products:
9 | - id: cloud-serverless
10 | - id: observability
11 | - id: edot-sdk
12 | ---
13 |
14 | # Elastic Distribution of OpenTelemetry Android known issues
15 |
16 | Known issues are significant defects or limitations that may impact your implementation. These issues are actively being worked on and will be addressed in a future release. Review known issues to help you make informed decisions, such as upgrading to a new version.
17 |
18 | % Use the following template to add entries to this page.
19 |
20 | % :::{dropdown} Title of known issue
21 | % **Details**
22 | % On [Month/Day/Year], a known issue was discovered that [description of known issue].
23 |
24 | % **Workaround**
25 | % Workaround description.
26 |
27 | % **Resolved**
28 | % On [Month/Day/Year], this issue was resolved.
29 |
30 | :::
31 |
32 | _No known issues_
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/logging/LogLevel.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.logging
20 |
21 | enum class LogLevel(val value: Int) {
22 | TRACE(0), DEBUG(1), INFO(2), WARN(3), ERROR(4)
23 | }
24 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3 | "extends": [
4 | "local>elastic/renovate-config"
5 | ],
6 | "ignorePaths": [
7 | ".ci/**",
8 | ".buildkite/**",
9 | ".github/*",
10 | ".github/actions/**",
11 | ".github/workflows/*"
12 | ],
13 | "packageRules": [
14 | {
15 | "matchPackageNames": [
16 | "io.opentelemetry:**"
17 | ],
18 | "ignoreUnstable": false,
19 | "groupName": "otel-core"
20 | },
21 | {
22 | "matchPackageNames": [
23 | "io.opentelemetry.contrib:**"
24 | ],
25 | "ignoreUnstable": false,
26 | "groupName": "otel-contrib"
27 | },
28 | {
29 | "matchPackageNames": [
30 | "io.opentelemetry.semconv:**"
31 | ],
32 | "ignoreUnstable": false,
33 | "groupName": "otel-semconv"
34 | },
35 | {
36 | "matchPackageNames": [
37 | "io.opentelemetry.instrumentation:**"
38 | ],
39 | "ignoreUnstable": false,
40 | "groupName": "otel-instrumentation"
41 | }
42 | ]
43 | }
44 |
--------------------------------------------------------------------------------
/install-android-sdk.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | set -e
4 |
5 | SDKDIR=$PWD/.android-sdk
6 | export ANDROID_SDK_ROOT=${SDKDIR}
7 | export ANDROID_HOME=${SDKDIR}
8 | export ANDROID_AVD_HOME=${SDKDIR}/avd
9 |
10 | mkdir ${SDKDIR}
11 | mkdir ${SDKDIR}/cmdline-tools
12 |
13 | echo Downloading Android SDK...
14 | cd ${SDKDIR}/cmdline-tools
15 | COMMAND_LINE_TOOLS_ZIP=${SDKDIR}/commandlinetools.zip
16 | # https://developer.android.com/studio#command-tools
17 | TYPE=linux
18 | if [[ "$OSTYPE" == "darwin"* ]]; then
19 | TYPE=mac
20 | fi
21 | curl -q https://dl.google.com/android/repository/commandlinetools-${TYPE}-8512546_latest.zip -o ${COMMAND_LINE_TOOLS_ZIP}
22 | unzip ${COMMAND_LINE_TOOLS_ZIP}
23 | rm ${COMMAND_LINE_TOOLS_ZIP}
24 | mv cmdline-tools latest
25 | ln -s ${SDKDIR}/cmdline-tools/latest ${SDKDIR}/tools
26 |
27 | echo Installing emulator...
28 | yes | ${ANDROID_HOME}/tools/bin/sdkmanager --install platform-tools emulator
29 |
30 | echo Installing platform SDK...
31 | yes | ${ANDROID_HOME}/tools/bin/sdkmanager --install "platforms;android-33"
32 |
33 | echo Starting ADB...
34 | ${ANDROID_HOME}/platform-tools/adb devices
35 |
--------------------------------------------------------------------------------
/instrumentation-test/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | gradlePluginPortal()
4 | mavenCentral()
5 | google()
6 | }
7 | }
8 | dependencyResolutionManagement {
9 | versionCatalogs {
10 | create("libs") {
11 | from(files("../gradle/libs.versions.toml"))
12 | }
13 | create("instrumentation") {
14 | from(files("../gradle/instrumentation.versions.toml"))
15 | }
16 | }
17 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
18 | repositories {
19 | mavenCentral()
20 | google()
21 | }
22 | }
23 | includeBuild("..")
24 |
25 | val instrumentationDirName = "instrumentation"
26 | val instrumentationDir = File(rootDir, instrumentationDirName)
27 | val separator = Regex("[/\\\\]")
28 | instrumentationDir.walk().maxDepth(2).forEach {
29 | if (it.name.equals("build.gradle.kts")) {
30 | include(
31 | ":$instrumentationDirName:${
32 | it.parentFile.toRelativeString(instrumentationDir).replace(separator, ":")
33 | }"
34 | )
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/.github/workflows/ci-docs.yml:
--------------------------------------------------------------------------------
1 | # This workflow sets the ci / ci status check to success in case it's a docs only PR and ci.yml is not triggered
2 | # https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/defining-the-mergeability-of-pull-requests/troubleshooting-required-status-checks#handling-skipped-but-required-checks
3 | name: ci # The name must be the same as in ci.yml
4 |
5 | on:
6 | pull_request:
7 | paths-ignore: # This expression needs to match the paths ignored on ci.yml.
8 | - '**'
9 | - '!**/*.md'
10 | - '!**/*.asciidoc'
11 | - '!**/*.png'
12 |
13 | permissions:
14 | contents: read
15 |
16 | ## Concurrency only allowed in the main branch.
17 | ## So old builds running for old commits within the same Pull Request are cancelled
18 | concurrency:
19 | group: ${{ github.workflow }}-${{ github.ref }}
20 | cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
21 |
22 | jobs:
23 |
24 | # dummy steps that allow to bypass those mandatory checks for tests
25 | ci:
26 | runs-on: ubuntu-latest
27 | steps:
28 | - run: 'echo "Not required for docs"'
29 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/exporters/configuration/ExportProtocol.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.exporters.configuration
20 |
21 | /**
22 | * The protocol used to contact the Elastic server.
23 | */
24 | enum class ExportProtocol {
25 | HTTP,
26 | GRPC
27 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # apm-agent-android
2 |
3 | Elastic OTel Android Agent
4 |
5 | See the [documentation](https://www.elastic.co/docs/reference/opentelemetry/edot-sdks/android) to find out more about its features, how to setup, and configuration details.
6 |
7 | ## Try it out
8 |
9 | Follow the [Demo application guide](https://github.com/elastic/android-agent-demo) to set up a test environment and take a quick
10 | look at the agent's functionalities.
11 |
12 | ## Publishing it locally
13 |
14 | In order to use a local build for your local projects, you'll need to publish it into your machine's
15 | maven local repo. To do so, open up a terminal in this project's root dir and
16 | run: `./gradlew publishToMavenLocal`. After that, you can apply the agent into an Android
17 | application project (that uses [mavenLocal()](https://docs.gradle.org/current/kotlin-dsl/gradle/org.gradle.api.artifacts.dsl/-repository-handler/maven-local.html) as one of its dependency repositories)
18 | by following the [Getting started](https://www.elastic.co/docs/reference/opentelemetry/edot-sdks/android/getting-started) guide and using the version defined [here](gradle.properties).
19 |
--------------------------------------------------------------------------------
/.github/workflows/addToProject.yml:
--------------------------------------------------------------------------------
1 | name: Auto Assign to Project(s)
2 |
3 | on:
4 | issues:
5 | types: [opened, edited, milestoned]
6 |
7 | permissions:
8 | contents: read
9 |
10 | jobs:
11 | assign_one_project:
12 | runs-on: ubuntu-latest
13 | name: Assign milestoned to Project
14 | steps:
15 | - name: Get token
16 | id: get_token
17 | uses: tibdex/github-app-token@3beb63f4bd073e61482598c45c71c1019b59b73a # v2.1.0
18 | with:
19 | app_id: ${{ secrets.OBS_AUTOMATION_APP_ID }}
20 | private_key: ${{ secrets.OBS_AUTOMATION_APP_PEM }}
21 | permissions: >-
22 | {
23 | "organization_projects": "write",
24 | "issues": "read"
25 | }
26 |
27 | - name: Assign issues with milestones to project
28 | uses: elastic/assign-one-project-github-action@1.2.2
29 | if: github.event.issue && github.event.issue.milestone
30 | with:
31 | project: 'https://github.com/orgs/elastic/projects/454'
32 | project_id: '5882982'
33 | column_name: 'Planned'
34 | env:
35 | MY_GITHUB_TOKEN: ${{ steps.get_token.outputs.token }}
36 |
--------------------------------------------------------------------------------
/agent-plugin/src/main/java/co/elastic/otel/android/plugin/extensions/BytecodeInstrumentation.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.plugin.extensions
20 |
21 | import org.gradle.api.provider.ListProperty
22 |
23 | interface BytecodeInstrumentation {
24 | val disableForBuildTypes: ListProperty
25 | }
26 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/provider/StringProvider.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.provider
20 |
21 | /**
22 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
23 | * any time.
24 | */
25 | fun interface StringProvider : Provider
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/provider/Provider.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.provider
20 |
21 | /**
22 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
23 | * any time.
24 | */
25 | fun interface Provider {
26 | fun get(): T
27 | }
--------------------------------------------------------------------------------
/agent-common/src/main/java/co/elastic/otel/android/common/internal/annotations/InternalApi.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.common.internal.annotations
20 |
21 | /**
22 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
23 | * any time.
24 | */
25 | annotation class InternalApi
26 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/services/Service.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.services
20 |
21 | /**
22 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
23 | * any time.
24 | */
25 | internal interface Service {
26 | fun start() {}
27 |
28 | fun stop() {}
29 | }
--------------------------------------------------------------------------------
/agent-plugin/src/main/java/co/elastic/otel/android/plugin/internal/BuildVariantListener.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.plugin.internal
20 |
21 | /**
22 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
23 | * any time.
24 | */
25 | interface BuildVariantListener {
26 | fun onBuildVariant(name: String)
27 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/opentelemetry/SignalType.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.opentelemetry
20 |
21 | /**
22 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
23 | * any time.
24 | */
25 | internal enum class SignalType {
26 | TRACE,
27 | METRIC,
28 | LOG
29 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/features/exportergate/latch/Latch.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.features.exportergate.latch
20 |
21 | /**
22 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
23 | * any time.
24 | */
25 | internal data class Latch(val gateName: String, val name: String)
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/connectivity/ExportEndpointConfiguration.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.connectivity
20 |
21 | import co.elastic.otel.android.exporters.configuration.ExportProtocol
22 |
23 | data class ExportEndpointConfiguration(
24 | val url: String,
25 | val authentication: Authentication,
26 | val protocol: ExportProtocol
27 | )
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/services/network/data/CarrierInfo.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.services.network.data
20 |
21 | /**
22 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
23 | * any time.
24 | */
25 | internal data class CarrierInfo(val name: String, val mcc: String, val mnc: String, val icc: String)
26 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/connectivity/ConnectivityConfiguration.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.connectivity
20 |
21 | /**
22 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
23 | * any time.
24 | */
25 | interface ConnectivityConfiguration {
26 | fun getUrl(): String
27 |
28 | fun getHeaders(): Map
29 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/utilities/cache/CacheHandler.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.utilities.cache
20 |
21 | /**
22 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
23 | * any time.
24 | */
25 | internal interface CacheHandler {
26 | fun retrieve(): T?
27 |
28 | fun store(value: T)
29 |
30 | fun clear()
31 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/features/session/Session.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.features.session
20 |
21 | import co.elastic.otel.android.internal.session.DefaultSession
22 |
23 | interface Session {
24 | fun getId(): String
25 |
26 | companion object {
27 | @JvmStatic
28 | fun create(id: String): Session {
29 | return DefaultSession(id)
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/utilities/NumberTools.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.utilities
20 |
21 | import java.util.Random
22 |
23 | /**
24 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
25 | * any time.
26 | */
27 | internal class NumberTools {
28 | fun random(): Double {
29 | return Random().nextDouble()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/agent-sdk/src/test/java/co/elastic/otel/android/testutils/DummySntpClient.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.testutils
20 |
21 | import co.elastic.otel.android.internal.time.ntp.SntpClient
22 |
23 | internal class DummySntpClient : SntpClient {
24 |
25 | override fun fetchTimeOffset(currentTimeMillis: Long): SntpClient.Response {
26 | return SntpClient.Response.Success(0)
27 | }
28 |
29 | override fun close() {
30 | }
31 | }
--------------------------------------------------------------------------------
/agent-api/src/main/java/co/elastic/otel/android/api/ElasticOtelAgent.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.api
20 |
21 | import io.opentelemetry.api.OpenTelemetry
22 | import java.io.Closeable
23 |
24 | /**
25 | * Entry point for the Elastic Android OpenTelemetry agent.
26 | */
27 | interface ElasticOtelAgent : Closeable {
28 |
29 | /**
30 | * Provides the underlying [OpenTelemetry] instance.
31 | */
32 | fun getOpenTelemetry(): OpenTelemetry
33 | }
--------------------------------------------------------------------------------
/instrumentation-test/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import java.util.Properties
2 |
3 | val agentProperties = Properties()
4 | val propertiesFile = File(rootDir, "../gradle.properties")
5 | propertiesFile.inputStream().use {
6 | agentProperties.load(it)
7 | }
8 | val agentVersion = agentProperties["version"]
9 |
10 | extra.apply {
11 | set("jvmCompatibility", JavaVersion.VERSION_17)
12 | set("androidCompileSdk", 35)
13 | set("androidMinSdk", 26)
14 | set("agentVersion", agentVersion)
15 | }
16 |
17 | val instrumentationProjectPattern = Regex(":instrumentation:([^:]+)$")
18 | subprojects {
19 | instrumentationProjectPattern.matchEntire(path)?.let {
20 | val moduleId = it.groupValues[1]
21 | configurations.all {
22 | resolutionStrategy.dependencySubstitution {
23 | substitute(module("co.elastic.otel.android.instrumentation:${moduleId}-library"))
24 | .using(module("co.elastic.otel.android.${moduleId}:library:$agentVersion"))
25 | }
26 | resolutionStrategy.dependencySubstitution {
27 | substitute(module("co.elastic.otel.android.instrumentation:${moduleId}-bytebuddy"))
28 | .using(module("co.elastic.otel.android.${moduleId}:bytebuddy:$agentVersion"))
29 | }
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/features/session/SessionProvider.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.features.session
20 |
21 | import co.elastic.otel.android.internal.session.DefaultSessionProvider
22 |
23 | fun interface SessionProvider {
24 | fun getSession(): Session?
25 |
26 | companion object {
27 | @JvmStatic
28 | fun getDefault(): SessionProvider {
29 | return DefaultSessionProvider()
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------
1 | pluginManagement {
2 | repositories {
3 | mavenLocal()
4 | mavenCentral()
5 | google()
6 | gradlePluginPortal()
7 | }
8 | }
9 | dependencyResolutionManagement {
10 | versionCatalogs {
11 | create("instrumentation") {
12 | from(files("./gradle/instrumentation.versions.toml"))
13 | }
14 | }
15 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
16 | repositories {
17 | mavenLocal()
18 | mavenCentral()
19 | google()
20 | }
21 | }
22 | rootProject.name = "elastic-otel-android"
23 | includeBuild("build-tools")
24 | include(":agent-api")
25 | include(":agent-sdk")
26 | include(":agent-plugin")
27 | include(":agent-common")
28 | includeFromDir("instrumentation")
29 | includeFromDir("internal-tools", 2)
30 |
31 | fun includeFromDir(dirName: String, maxDepth: Int = 3) {
32 | val instrumentationDir = File(rootDir, dirName)
33 | val separator = Regex("[/\\\\]")
34 | instrumentationDir.walk().maxDepth(maxDepth).forEach {
35 | if (it.name.equals("build.gradle.kts")) {
36 | include(
37 | ":$dirName:${
38 | it.parentFile.toRelativeString(instrumentationDir).replace(separator, ":")
39 | }"
40 | )
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/session/DefaultSession.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.session
20 |
21 | import co.elastic.otel.android.features.session.Session
22 |
23 | /**
24 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
25 | * any time.
26 | */
27 | internal data class DefaultSession(private val id: String) : Session {
28 |
29 | override fun getId(): String {
30 | return id
31 | }
32 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/connectivity/SignalConnectivityChangeListener.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.connectivity
20 |
21 | import co.elastic.otel.android.internal.opentelemetry.SignalType
22 |
23 | /**
24 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
25 | * any time.
26 | */
27 | internal interface SignalConnectivityChangeListener {
28 | fun onConnectivityConfigurationChange(signalType: SignalType)
29 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/services/network/listener/NetworkChangeListener.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.services.network.listener
20 |
21 | import android.net.NetworkCapabilities
22 |
23 | /**
24 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
25 | * any time.
26 | */
27 | internal interface NetworkChangeListener {
28 | fun onNewNetwork(capabilities: NetworkCapabilities)
29 |
30 | fun onNetworkLost()
31 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/utilities/interceptor/NoopInterceptor.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.utilities.interceptor
20 |
21 | import co.elastic.otel.android.interceptor.Interceptor
22 |
23 | /**
24 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
25 | * any time.
26 | */
27 | internal class NoopInterceptor : Interceptor {
28 |
29 | override fun intercept(item: T): T {
30 | return item
31 | }
32 | }
--------------------------------------------------------------------------------
/integration-test/build.gradle.kts:
--------------------------------------------------------------------------------
1 | import java.util.Properties
2 |
3 | plugins {
4 | alias(rootLibs.plugins.androidApp) apply false
5 | alias(rootLibs.plugins.kotlin.android) apply false
6 | }
7 |
8 | val agentProperties = Properties()
9 | val propertiesFile = File(rootDir, "../gradle.properties")
10 | propertiesFile.inputStream().use {
11 | agentProperties.load(it)
12 | }
13 |
14 | val agentVersion = agentProperties["version"]
15 | subprojects {
16 | if (name == "app") {
17 | configurations.all {
18 | File(rootDir, "../instrumentation").listFiles().forEach {
19 | val dirName = it.name
20 | if (dirName != "api") {
21 | resolutionStrategy.dependencySubstitution {
22 | substitute(module("co.elastic.otel.android.instrumentation:${dirName}-library"))
23 | .using(module("co.elastic.otel.android.${dirName}:library:$agentVersion"))
24 | }
25 | resolutionStrategy.dependencySubstitution {
26 | substitute(module("co.elastic.otel.android.instrumentation:${dirName}-bytebuddy"))
27 | .using(module("co.elastic.otel.android.${dirName}:bytebuddy:$agentVersion"))
28 | }
29 | }
30 | }
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/.github/workflows/README.md:
--------------------------------------------------------------------------------
1 | # CI/CD
2 |
3 | There are 2 main stages that run on GitHub actions for every push or Pull Request:
4 |
5 | * Linting
6 | * Test
7 |
8 | ## Scenarios
9 |
10 | * Tests should be triggered on branch, tag and PR basis.
11 | * Commits that are only affecting the docs files should not trigger any test or similar stages that are not required.
12 | * **This is not the case yet**, but if Github secrets are required then Pull Requests from forked repositories won't run any build accessing those secrets. If needed, then create a feature branch.
13 |
14 | ## How to interact with the CI?
15 |
16 | ### On a PR basis
17 |
18 | Once a PR has been opened then there are two different ways you can trigger builds in the CI:
19 |
20 | 1. Commit based.
21 | 2. UI based, any Elasticians can force a build through the GitHub UI
22 |
23 | ### Branches
24 |
25 | Every time there is a merge to main or any release branches the main workflow will lint and test all on Linux.
26 |
27 | ## Release
28 |
29 | The release automation relies on Buildkite for generating and publishing the artifacts,
30 | for further details please go to [the buildkite folder](../../.buildkite/README.md).
31 |
32 | ## OpenTelemetry
33 |
34 | Every workflow and its logs are exported to OpenTelemetry traces/logs/metrics. Those details can be seen in
35 | [here](https://ela.st/oblt-ci-cd-stats) (**NOTE**: only available for Elasticians).
36 |
--------------------------------------------------------------------------------
/gradle/instrumentation.versions.toml:
--------------------------------------------------------------------------------
1 | [versions]
2 | opentelemetry-instrumentation-alpha = "2.21.0-alpha"
3 | opentelemetry-android = "0.11.0-alpha"
4 |
5 | [libraries]
6 | opentelemetry-instrumentation-api = "io.opentelemetry.instrumentation:opentelemetry-instrumentation-api:2.21.0"
7 | opentelemetry-instrumentation-api-incubator = { module = "io.opentelemetry.instrumentation:opentelemetry-instrumentation-api-incubator", version.ref = "opentelemetry-instrumentation-alpha" }
8 | opentelemetry-instrumentation-okhttp = { module = "io.opentelemetry.instrumentation:opentelemetry-okhttp-3.0", version.ref = "opentelemetry-instrumentation-alpha" }
9 | opentelemetry-android-session = { module = "io.opentelemetry.android:session", version.ref = "opentelemetry-android" }
10 | opentelemetry-android-instrumentation = { module = "io.opentelemetry.android.instrumentation:android-instrumentation", version.ref = "opentelemetry-android" }
11 | weakLockFree = "com.blogspot.mydailyjava:weak-lock-free:0.18"
12 |
13 | # Testing
14 | androidx-test-core = "androidx.test:core-ktx:1.7.0"
15 | androidx-test-rules = "androidx.test:rules:1.7.0"
16 | androidx-test-runner = "androidx.test:runner:1.7.0"
17 | androidx-test-ext = "androidx.test.ext:junit:1.3.0"
18 | mockWebServer = "com.squareup.okhttp3:mockwebserver:5.3.2"
19 |
20 | [bundles]
21 | androidTest = ["androidx-test-rules", "androidx-test-runner", "androidx-test-ext", "androidx-test-core"]
22 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/time/SystemTimeProvider.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.time
20 |
21 | import android.os.SystemClock
22 |
23 | /**
24 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
25 | * any time.
26 | */
27 | class SystemTimeProvider {
28 |
29 | fun getCurrentTimeMillis(): Long = System.currentTimeMillis()
30 |
31 | fun getNanoTime(): Long = System.nanoTime()
32 |
33 | fun getElapsedRealTime(): Long = SystemClock.elapsedRealtime()
34 | }
35 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/services/network/data/NetworkType.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.services.network.data
20 |
21 | /**
22 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
23 | * any time.
24 | */
25 | internal sealed class NetworkType(val name: String) {
26 | data class Cell(val subTypeName: String?) : NetworkType("cell")
27 | data object Wifi : NetworkType("wifi")
28 | data object Unknown : NetworkType("unknown")
29 | data object None : NetworkType("unavailable")
30 | }
--------------------------------------------------------------------------------
/agent-plugin/src/main/java/co/elastic/otel/android/plugin/extensions/ElasticApmExtension.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.plugin.extensions
20 |
21 | import javax.inject.Inject
22 | import org.gradle.api.Action
23 | import org.gradle.api.model.ObjectFactory
24 |
25 | abstract class ElasticApmExtension @Inject constructor(objects: ObjectFactory) {
26 | val bytecodeInstrumentation = objects.newInstance(BytecodeInstrumentation::class.java)
27 |
28 | fun bytecodeInstrumentation(action: Action) {
29 | action.execute(bytecodeInstrumentation)
30 | }
31 | }
--------------------------------------------------------------------------------
/agent-plugin/src/main/java/co/elastic/otel/android/plugin/internal/logging/GradleLoggerFactory.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.plugin.internal.logging
20 |
21 | import co.elastic.otel.android.common.internal.logging.ELoggerFactory
22 | import org.gradle.api.logging.Logging
23 | import org.slf4j.Logger
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | class GradleLoggerFactory : ELoggerFactory() {
30 |
31 | override fun getLogger(name: String): Logger {
32 | return Logging.getLogger(name)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/agent-api/src/main/java/co/elastic/otel/android/api/flusher/MetricFlusher.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.api.flusher
20 |
21 | import io.opentelemetry.sdk.common.CompletableResultCode
22 | import io.opentelemetry.sdk.metrics.export.MetricReader
23 |
24 | /**
25 | * Marks the ability to force flush metrics.
26 | */
27 | interface MetricFlusher {
28 |
29 | /**
30 | * Flushes metrics. This is useful to signal the [MetricReader] to read and export metrics on demand.
31 | *
32 | * @return [CompletableResultCode] to keep track of the async operation.
33 | */
34 | fun flushMetrics(): CompletableResultCode
35 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/api/ManagedElasticOtelAgentContract.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.api
20 |
21 | import co.elastic.otel.android.api.ElasticOtelAgent
22 | import co.elastic.otel.android.api.flusher.LogRecordFlusher
23 | import co.elastic.otel.android.api.flusher.MetricFlusher
24 | import co.elastic.otel.android.api.flusher.SpanFlusher
25 |
26 | /**
27 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
28 | * any time.
29 | */
30 | interface ManagedElasticOtelAgentContract : ElasticOtelAgent, SpanFlusher, LogRecordFlusher,
31 | MetricFlusher
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/exporters/ExporterProvider.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.exporters
20 |
21 | import io.opentelemetry.sdk.logs.export.LogRecordExporter
22 | import io.opentelemetry.sdk.metrics.export.MetricExporter
23 | import io.opentelemetry.sdk.trace.export.SpanExporter
24 |
25 | interface ExporterProvider {
26 | companion object {
27 | fun noop(): ExporterProvider {
28 | return NoopExporterProvider()
29 | }
30 | }
31 |
32 | fun getSpanExporter(): SpanExporter?
33 |
34 | fun getLogRecordExporter(): LogRecordExporter?
35 |
36 | fun getMetricExporter(): MetricExporter?
37 | }
--------------------------------------------------------------------------------
/agent-sdk/build.gradle.kts:
--------------------------------------------------------------------------------
1 | plugins {
2 | id("elastic.android-library")
3 | }
4 |
5 | android {
6 | namespace = "co.elastic.otel.android"
7 | buildFeatures.buildConfig = true
8 |
9 | defaultConfig {
10 | buildConfigField("String", "APM_AGENT_VERSION", "\"${project.version}\"")
11 | }
12 |
13 | testOptions {
14 | unitTests {
15 | isIncludeAndroidResources = true
16 | all {
17 | it.systemProperty("agent_version", project.version)
18 | }
19 | }
20 | }
21 | }
22 |
23 | apiValidation {
24 | ignoredClasses.add("co.elastic.otel.android.BuildConfig")
25 | }
26 |
27 | dependencies {
28 | api(project(":agent-api"))
29 | api(project(":instrumentation:api"))
30 | implementation(libs.opentelemetry.api.incubator)
31 | implementation(libs.stagemonitor.configuration)
32 | implementation(libs.opentelemetry.exporter.otlp)
33 | implementation(libs.bundles.opentelemetry.semconv)
34 | implementation(libs.opentelemetry.diskBuffering)
35 | implementation(libs.opentelemetry.opamp)
36 | implementation(libs.androidx.annotations)
37 | implementation(libs.androidx.core)
38 | implementation(libs.dsl.json)
39 | implementation(libs.okhttp)
40 | testImplementation(project(":internal-tools:otel-test-common"))
41 | testImplementation(libs.wireMock)
42 | testImplementation(libs.opentelemetry.testing)
43 | testImplementation(libs.robolectric)
44 | testImplementation(libs.awaitility)
45 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/exporters/NoopExporterProvider.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.exporters
20 |
21 | import io.opentelemetry.sdk.logs.export.LogRecordExporter
22 | import io.opentelemetry.sdk.metrics.export.MetricExporter
23 | import io.opentelemetry.sdk.trace.export.SpanExporter
24 |
25 | internal class NoopExporterProvider : ExporterProvider {
26 | override fun getSpanExporter(): SpanExporter? {
27 | return null
28 | }
29 |
30 | override fun getLogRecordExporter(): LogRecordExporter? {
31 | return null
32 | }
33 |
34 | override fun getMetricExporter(): MetricExporter? {
35 | return null
36 | }
37 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/features/session/SessionIdGenerator.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.features.session
20 |
21 | /**
22 | * Generates a session id to be sent as a [session.id](https://opentelemetry.io/docs/specs/semconv/attributes-registry/session/#session-id) attribute.
23 | */
24 | fun interface SessionIdGenerator {
25 | /**
26 | * Called every time a span or log record is created to set its [session.id](https://opentelemetry.io/docs/specs/semconv/attributes-registry/session/#session-id) attribute.
27 | *
28 | * @return The generated session id, or null if no session id is needed.
29 | */
30 | fun generate(): String?
31 | }
--------------------------------------------------------------------------------
/agent-api/src/main/java/co/elastic/otel/android/api/flusher/SpanFlusher.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.api.flusher
20 |
21 | import io.opentelemetry.sdk.common.CompletableResultCode
22 | import io.opentelemetry.sdk.trace.SpanProcessor
23 |
24 | /**
25 | * Marks the ability to force flush spans.
26 | */
27 | interface SpanFlusher {
28 |
29 | /**
30 | * Flushes spans. This is useful when the [SpanProcessor] temporarily stores items in-memory
31 | * and it's needed to send them to the exporter before they're due.
32 | *
33 | * @return [CompletableResultCode] to keep track of the async operation.
34 | */
35 | fun flushSpans(): CompletableResultCode
36 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/utilities/logging/AndroidLoggerFactory.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.utilities.logging
20 |
21 | import co.elastic.otel.android.common.internal.logging.ELoggerFactory
22 | import co.elastic.otel.android.logging.LoggingPolicy
23 | import org.slf4j.Logger
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | internal class AndroidLoggerFactory(private val policy: LoggingPolicy) : ELoggerFactory() {
30 |
31 | override fun getLogger(name: String): Logger {
32 | return AndroidLogger(name, policy)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/utilities/interceptor/MultiInterceptor.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.utilities.interceptor
20 |
21 | import co.elastic.otel.android.interceptor.Interceptor
22 |
23 | /**
24 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
25 | * any time.
26 | */
27 | internal class MultiInterceptor(private val interceptors: List>) :
28 | Interceptor {
29 |
30 | override fun intercept(item: T): T {
31 | var result = item
32 | interceptors.forEach {
33 | result = it.intercept(result)
34 | }
35 | return result
36 | }
37 | }
--------------------------------------------------------------------------------
/agent-plugin/src/main/java/co/elastic/otel/android/plugin/internal/ByteBuddyDependencyAttacher.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.plugin.internal
20 |
21 | import org.gradle.api.Project
22 |
23 | /**
24 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
25 | * any time.
26 | */
27 | class ByteBuddyDependencyAttacher(
28 | private val project: Project,
29 | private val dependencyUri: String
30 | ) : BuildVariantListener {
31 |
32 | override fun onBuildVariant(name: String) {
33 | project.configurations.maybeCreate("${name}ByteBuddy").dependencies.add(
34 | project.dependencies.create(dependencyUri)
35 | )
36 | }
37 | }
--------------------------------------------------------------------------------
/agent-api/src/main/java/co/elastic/otel/android/api/flusher/LogRecordFlusher.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.api.flusher
20 |
21 | import io.opentelemetry.sdk.common.CompletableResultCode
22 | import io.opentelemetry.sdk.logs.LogRecordProcessor
23 |
24 | /**
25 | * Marks the ability to force flush log records.
26 | */
27 | interface LogRecordFlusher {
28 |
29 | /**
30 | * Flushes log records. This is useful when the [LogRecordProcessor] temporarily stores items in-memory
31 | * and it's needed to send them to the exporter before they're due.
32 | *
33 | * @return [CompletableResultCode] to keep track of the async operation.
34 | */
35 | fun flushLogRecords(): CompletableResultCode
36 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/session/DefaultSessionProvider.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.session
20 |
21 | import co.elastic.otel.android.features.session.Session
22 | import co.elastic.otel.android.features.session.SessionProvider
23 | import java.util.UUID
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | internal class DefaultSessionProvider : SessionProvider {
30 | private val providedSession by lazy {
31 | Session.create(UUID.randomUUID().toString())
32 | }
33 |
34 | override fun getSession(): Session {
35 | return providedSession
36 | }
37 | }
--------------------------------------------------------------------------------
/instrumentation-test/instrumentation/oteladapter/src/androidTest/java/co/elastic/otel/android/test/InstrumentationTest.kt:
--------------------------------------------------------------------------------
1 | package co.elastic.otel.android.test
2 |
3 | import androidx.test.core.app.launchActivity
4 | import co.elastic.otel.android.test.rule.AndroidTestAgentRule
5 | import io.opentelemetry.api.common.AttributeKey
6 | import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat
7 | import java.util.concurrent.TimeUnit
8 | import org.junit.Rule
9 | import org.junit.Test
10 |
11 | class InstrumentationTest {
12 |
13 | @get:Rule
14 | val agentRule = AndroidTestAgentRule()
15 |
16 | @Test
17 | fun verifyAndroidLogsAreInstrumented() {
18 | launchActivity().onActivity { activity ->
19 | activity.sendLog()
20 |
21 | agentRule.flushLogs().join(5, TimeUnit.SECONDS)
22 |
23 | val finishedLogRecords = agentRule.getFinishedLogRecords()
24 | assertThat(finishedLogRecords).hasSize(1)
25 | assertThat(finishedLogRecords.first())
26 | .hasBody("My log")
27 | .hasAttributesSatisfying {
28 | assertThat(it.get(AttributeKey.stringKey("android.log.tag"))).isEqualTo("elastic")
29 | }
30 |
31 | // Closing instrumentation
32 | agentRule.getInstrumentationManager().close()
33 |
34 | activity.sendLog()
35 |
36 | agentRule.flushLogs().join(5, TimeUnit.SECONDS)
37 | assertThat(agentRule.getFinishedLogRecords()).isEmpty()
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/instrumentation/oteladapter/plugin/src/main/java/co/elastic/otel/android/oteladapter/ExperimentalOtelAdapterPlugin.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.oteladapter
20 |
21 | import co.elastic.otel.android.instrumentation.generated.oteladapter.BuildConfig
22 | import co.elastic.otel.android.plugin.ElasticAgentPlugin
23 | import co.elastic.otel.android.plugin.internal.InstrumentationPlugin
24 | import org.gradle.api.Project
25 |
26 | class ExperimentalOtelAdapterPlugin : InstrumentationPlugin() {
27 |
28 | override fun onApply(target: Project, agentPlugin: ElasticAgentPlugin) {
29 | target.dependencies.add(
30 | "implementation",
31 | target.dependencies.create(BuildConfig.LIBRARY_URI)
32 | )
33 | }
34 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/logging/SimpleLoggingPolicy.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.logging
20 |
21 | import co.elastic.otel.android.logging.LogLevel
22 | import co.elastic.otel.android.logging.LoggingPolicy
23 |
24 | /**
25 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
26 | * any time.
27 | */
28 | internal class SimpleLoggingPolicy(
29 | private val isEnabled: Boolean,
30 | private val minimumLevel: LogLevel
31 | ) :
32 | LoggingPolicy {
33 |
34 | override fun isEnabled(): Boolean {
35 | return isEnabled
36 | }
37 |
38 | override fun getMinimumLevel(): LogLevel {
39 | return minimumLevel
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/features/httpinterceptor/HttpSpanExporterInterceptor.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.features.httpinterceptor
20 |
21 | import co.elastic.otel.android.interceptor.Interceptor
22 | import io.opentelemetry.sdk.trace.data.SpanData
23 | import io.opentelemetry.sdk.trace.export.SpanExporter
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | internal class HttpSpanExporterInterceptor(private val httpSpanInterceptor: Interceptor) :
30 | Interceptor {
31 |
32 | override fun intercept(item: SpanExporter): SpanExporter {
33 | return HttpSpanExporter(item, httpSpanInterceptor)
34 | }
35 | }
--------------------------------------------------------------------------------
/instrumentation/api/src/main/java/co/elastic/otel/android/instrumentation/internal/Instrumentation.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.instrumentation.internal
20 |
21 | import android.app.Application
22 | import co.elastic.otel.android.api.ElasticOtelAgent
23 | import java.io.Closeable
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | interface Instrumentation {
30 |
31 | fun install(application: Application, agent: ElasticOtelAgent): Installation
32 |
33 | fun getId(): String
34 |
35 | fun getVersion(): String
36 |
37 | fun interface Installation : Closeable {
38 | companion object {
39 | val NOOP = Installation {}
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.aar
4 | *.ap_
5 | *.aab
6 |
7 | # Files for the ART/Dalvik VM
8 | *.dex
9 |
10 | # Java class files
11 | *.class
12 |
13 | # Generated files
14 | bin/
15 | gen/
16 | out/
17 | # Uncomment the following line in case you need and you don't have the release build type files in your app
18 | # release/
19 |
20 | # Gradle files
21 | .gradle/
22 | build/
23 |
24 | # Local configuration file (sdk path, etc)
25 | local.properties
26 |
27 | # Proguard folder generated by Eclipse
28 | proguard/
29 |
30 | # Log Files
31 | *.log
32 |
33 | # Android Studio Navigation editor temp files
34 | .navigation/
35 |
36 | # Android Studio captures folder
37 | captures/
38 |
39 | # IntelliJ
40 | *.iml
41 | .idea/
42 | .java-version
43 |
44 | # Keystore files
45 | # Uncomment the following lines if you do not want to check your keystore files in.
46 | #*.jks
47 | #*.keystore
48 |
49 | # External native build folder generated in Android Studio 2.2 and later
50 | .externalNativeBuild
51 | .cxx/
52 |
53 | # Google Services (e.g. APIs or Firebase)
54 | # google-services.json
55 |
56 | # Freeline
57 | freeline.py
58 | freeline/
59 | freeline_project_description.json
60 |
61 | # fastlane
62 | fastlane/report.xml
63 | fastlane/Preview.html
64 | fastlane/screenshots
65 | fastlane/test_output
66 | fastlane/readme.md
67 |
68 | # Version control
69 | vcs.xml
70 |
71 | # lint
72 | lint/intermediates/
73 | lint/generated/
74 | lint/outputs/
75 | lint/tmp/
76 | # lint/reports/
77 |
78 | # Deploy task
79 | .android-sdk
80 |
81 | # built documentation
82 | html_docs
83 | .artifacts
84 | docs/.artifacts
85 |
86 | .DS_Store
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/utilities/interceptor/MutableInterceptor.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.utilities.interceptor
20 |
21 | import co.elastic.otel.android.interceptor.Interceptor
22 | import java.util.concurrent.atomic.AtomicReference
23 |
24 | /**
25 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
26 | * any time.
27 | */
28 | internal class MutableInterceptor(initialValue: Interceptor) : Interceptor {
29 | private val delegate = AtomicReference(initialValue)
30 |
31 | override fun intercept(item: T): T {
32 | return delegate.get().intercept(item)
33 | }
34 |
35 | fun setDelegate(value: Interceptor) {
36 | delegate.set(value)
37 | }
38 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/features/clock/SystemTimeClock.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.features.clock
20 |
21 | import co.elastic.otel.android.internal.time.SystemTimeProvider
22 | import io.opentelemetry.sdk.common.Clock
23 | import java.util.concurrent.TimeUnit
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | internal class SystemTimeClock(private val systemTimeProvider: SystemTimeProvider) : Clock {
30 |
31 | override fun now(): Long {
32 | return TimeUnit.MILLISECONDS.toNanos(systemTimeProvider.getCurrentTimeMillis())
33 | }
34 |
35 | override fun nanoTime(): Long {
36 | return systemTimeProvider.getNanoTime()
37 | }
38 | }
--------------------------------------------------------------------------------
/.github/scripts/integration-test/Makefile:
--------------------------------------------------------------------------------
1 | MAKEFLAGS += --no-print-directory
2 | .SHELLFLAGS = -euc
3 | SHELL = /bin/bash
4 |
5 | elastic_version?=9.2.0
6 | elastic-start-local: ## Start ES locally
7 | curl -fsSL https://elastic.co/start-local | sh -s -- --esonly -v $(elastic_version)
8 |
9 | .PHONY: start-edot-collector
10 | demo_app_dir="build/demo-app"
11 | edot_collector_build="$(demo_app_dir)/edot-collector/build"
12 | start-edot-collector: elastic-start-local ## Start EDOT Collector
13 | git clone https://github.com/elastic/android-agent-demo.git $(demo_app_dir)
14 | . elastic-start-local/.env; \
15 | printf "endpoint=$$ES_LOCAL_URL\napi_key=$$ES_LOCAL_API_KEY" > "$(demo_app_dir)/elasticsearch.properties"
16 |
17 | # Preparing collector binary
18 | $(demo_app_dir)/gradlew -p "$(demo_app_dir)" :edot-collector:prepareEdotCollector
19 |
20 | # Launching EDOT Collector
21 | "$(edot_collector_build)/bin/otelcol" --config "$(edot_collector_build)/configuration/edot-configuration.yml" &
22 |
23 | # Waiting for EDOT Collector to run
24 | ./await_port.sh 4318 30
25 |
26 | .PHONY: run-tests
27 | run-tests: elastic-start-local ## Run integration tests
28 | . elastic-start-local/.env; \
29 | ./integration_test.sh $$ES_LOCAL_URL $$ES_LOCAL_API_KEY
30 |
31 | .PHONY: clean
32 | clean: clean-es clean-edot-collector
33 |
34 | .PHONY: clean-es
35 | clean-es: ## Stop and uninstall ES
36 | yes | elastic-start-local/stop.sh
37 | yes | elastic-start-local/uninstall.sh
38 | rm -rf elastic-start-local
39 |
40 | .PHONY: clean-edot-collector
41 | clean-edot-collector: ## Stop and cleans EDOT Collector
42 | kill $$(lsof -t -i:4318)
43 | rm -rf $(demo_app_dir)
--------------------------------------------------------------------------------
/instrumentation/oteladapter/library/src/main/java/co/elastic/otel/android/oteladapter/internal/delegate/tools/Delegator.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.oteladapter.internal.delegate.tools
20 |
21 | import java.util.concurrent.atomic.AtomicReference
22 |
23 | /**
24 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
25 | * any time.
26 | */
27 | abstract class Delegator(initialValue: T) {
28 | private val delegate = AtomicReference(initialValue)
29 |
30 | abstract fun getNoopValue(): T
31 |
32 | open fun setDelegate(value: T) {
33 | delegate.set(value)
34 | }
35 |
36 | open fun reset() {
37 | delegate.set(getNoopValue())
38 | }
39 |
40 | fun getDelegate(): T {
41 | return delegate.get()
42 | }
43 | }
--------------------------------------------------------------------------------
/internal-tools/otel-test-common/src/main/java/co/elastic/otel/android/test/processor/SimpleProcessorFactory.kt:
--------------------------------------------------------------------------------
1 | package co.elastic.otel.android.test.processor
2 |
3 | import co.elastic.otel.android.api.flusher.MetricFlusher
4 | import co.elastic.otel.android.processors.ProcessorFactory
5 | import io.opentelemetry.sdk.common.CompletableResultCode
6 | import io.opentelemetry.sdk.logs.LogRecordProcessor
7 | import io.opentelemetry.sdk.logs.export.LogRecordExporter
8 | import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor
9 | import io.opentelemetry.sdk.metrics.export.MetricExporter
10 | import io.opentelemetry.sdk.metrics.export.MetricReader
11 | import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader
12 | import io.opentelemetry.sdk.trace.SpanProcessor
13 | import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor
14 | import io.opentelemetry.sdk.trace.export.SpanExporter
15 |
16 | class SimpleProcessorFactory : ProcessorFactory, MetricFlusher {
17 | private lateinit var metricReader: PeriodicMetricReader
18 |
19 | override fun createSpanProcessor(exporter: SpanExporter?): SpanProcessor? {
20 | return SimpleSpanProcessor.create(exporter)
21 | }
22 |
23 | override fun createLogRecordProcessor(exporter: LogRecordExporter?): LogRecordProcessor? {
24 | return SimpleLogRecordProcessor.create(exporter)
25 | }
26 |
27 | override fun createMetricReader(exporter: MetricExporter?): MetricReader {
28 | metricReader = PeriodicMetricReader.create(exporter)
29 | return metricReader
30 | }
31 |
32 | override fun flushMetrics(): CompletableResultCode {
33 | return metricReader.forceFlush()
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/features/clock/MutableClock.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.features.clock
20 |
21 | import io.opentelemetry.sdk.common.Clock
22 | import java.util.concurrent.atomic.AtomicReference
23 |
24 | /**
25 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
26 | * any time.
27 | */
28 | internal class MutableClock(initialClock: Clock) : Clock {
29 | private val delegate: AtomicReference = AtomicReference(initialClock)
30 |
31 | override fun now(): Long {
32 | return delegate.get().now()
33 | }
34 |
35 | override fun nanoTime(): Long {
36 | return delegate.get().nanoTime()
37 | }
38 |
39 | internal fun setDelegate(clock: Clock) {
40 | delegate.set(clock)
41 | }
42 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/utilities/AttributesOverrideLogRecordData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.utilities
20 |
21 | import io.opentelemetry.api.common.Attributes
22 | import io.opentelemetry.sdk.logs.data.LogRecordData
23 |
24 | /**
25 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
26 | * any time.
27 | */
28 | internal open class AttributesOverrideLogRecordData(
29 | delegate: LogRecordData,
30 | private val attributes: Attributes,
31 | private val totalAttributeCount: Int
32 | ) : DelegateLogRecordData(delegate) {
33 |
34 | override fun getAttributes(): Attributes {
35 | return attributes
36 | }
37 |
38 | override fun getTotalAttributeCount(): Int {
39 | return totalAttributeCount
40 | }
41 | }
--------------------------------------------------------------------------------
/agent-sdk/src/test/java/co/elastic/otel/android/internal/logging/DefaultLoggingPolicyTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.logging
20 |
21 | import co.elastic.otel.android.logging.LogLevel
22 | import org.assertj.core.api.Assertions.assertThat
23 | import org.junit.Test
24 |
25 | class DefaultLoggingPolicyTest {
26 |
27 | @Test
28 | fun `Validate minimum level on debuggable app`() {
29 | assertThat(getInstance(true).getMinimumLevel()).isEqualTo(LogLevel.DEBUG)
30 | }
31 |
32 | @Test
33 | fun `Validate minimum level on non-debuggable app`() {
34 | assertThat(getInstance(false).getMinimumLevel()).isEqualTo(LogLevel.INFO)
35 | }
36 |
37 | private fun getInstance(appIsDebuggable: Boolean): DefaultLoggingPolicy {
38 | return DefaultLoggingPolicy(appIsDebuggable)
39 | }
40 | }
--------------------------------------------------------------------------------
/agent-sdk/src/test/java/co/elastic/otel/android/internal/logging/SimpleLoggingPolicyTest.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.logging
20 |
21 | import co.elastic.otel.android.logging.LogLevel
22 | import co.elastic.otel.android.logging.LoggingPolicy
23 | import org.junit.Assert
24 | import org.junit.Test
25 |
26 | class SimpleLoggingPolicyTest {
27 | @Test
28 | fun verifyProvidedValues() {
29 | val policy: LoggingPolicy = SimpleLoggingPolicy(true, LogLevel.INFO)
30 | val policy2: LoggingPolicy = SimpleLoggingPolicy(false, LogLevel.ERROR)
31 |
32 | Assert.assertTrue(policy.isEnabled())
33 | Assert.assertEquals(LogLevel.INFO, policy.getMinimumLevel())
34 | Assert.assertFalse(policy2.isEnabled())
35 | Assert.assertEquals(LogLevel.ERROR, policy2.getMinimumLevel())
36 | }
37 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/features/centralconfig/CentralConfiguration.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.features.centralconfig
20 |
21 | import co.elastic.otel.android.internal.configuration.Configuration
22 | import java.util.Optional
23 |
24 | /**
25 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
26 | * any time.
27 | */
28 | internal class CentralConfiguration : Configuration() {
29 | private val recording = createBooleanOption("recording")
30 | private val sessionSampleRate = createDoubleOption("session_sample_rate")
31 |
32 | fun isRecording(): Boolean {
33 | return recording.get().orElse(true)
34 | }
35 |
36 | fun getSessionSampleRate(): Optional {
37 | return sessionSampleRate.get()
38 | }
39 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/features/clock/ElasticClockBroadcastReceiver.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.features.clock
20 |
21 | import android.content.BroadcastReceiver
22 | import android.content.Context
23 | import android.content.Intent
24 | import co.elastic.otel.android.internal.services.ServiceManager
25 |
26 | /**
27 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
28 | * any time.
29 | */
30 | class ElasticClockBroadcastReceiver : BroadcastReceiver() {
31 | override fun onReceive(context: Context, intent: Intent?) {
32 | if (intent?.action == Intent.ACTION_BOOT_COMPLETED) {
33 | RemoteTimeOffsetManager.TimeOffsetCache(
34 | ServiceManager.create(context).getPreferencesService()
35 | ).clear()
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/utilities/cache/PreferencesLongCacheHandler.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.utilities.cache
20 |
21 | import co.elastic.otel.android.internal.services.preferences.PreferencesService
22 |
23 | /**
24 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
25 | * any time.
26 | */
27 | internal class PreferencesLongCacheHandler(
28 | private val key: String,
29 | private val preferencesService: PreferencesService
30 | ) : CacheHandler {
31 |
32 | override fun retrieve(): Long {
33 | return preferencesService.retrieveLong(key, 0)
34 | }
35 |
36 | override fun clear() {
37 | preferencesService.remove(key)
38 | }
39 |
40 | override fun store(value: Long) {
41 | preferencesService.store(key, value)
42 | }
43 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/utilities/cache/PreferencesStringCacheHandler.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.utilities.cache
20 |
21 | import co.elastic.otel.android.internal.services.preferences.PreferencesService
22 |
23 | /**
24 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
25 | * any time.
26 | */
27 | internal class PreferencesStringCacheHandler(
28 | private val key: String,
29 | private val preferencesService: PreferencesService
30 | ) : CacheHandler {
31 |
32 | override fun retrieve(): String? {
33 | return preferencesService.retrieveString(key)
34 | }
35 |
36 | override fun clear() {
37 | preferencesService.remove(key)
38 | }
39 |
40 | override fun store(value: String) {
41 | preferencesService.store(key, value)
42 | }
43 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/utilities/AttributesOverrideSpanData.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.utilities
20 |
21 | import io.opentelemetry.api.common.Attributes
22 | import io.opentelemetry.sdk.trace.data.DelegatingSpanData
23 | import io.opentelemetry.sdk.trace.data.SpanData
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | internal open class AttributesOverrideSpanData(
30 | delegate: SpanData,
31 | private val attributes: Attributes,
32 | private val totalAttributeCount: Int = attributes.size()
33 | ) : DelegatingSpanData(delegate) {
34 |
35 | override fun getAttributes(): Attributes {
36 | return attributes
37 | }
38 |
39 | override fun getTotalAttributeCount(): Int {
40 | return totalAttributeCount
41 | }
42 | }
--------------------------------------------------------------------------------
/agent-plugin/src/main/java/co/elastic/otel/android/plugin/internal/InstrumentationPlugin.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.plugin.internal
20 |
21 | import co.elastic.otel.android.plugin.ElasticAgentPlugin
22 | import org.gradle.api.Plugin
23 | import org.gradle.api.Project
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | abstract class InstrumentationPlugin : Plugin {
30 |
31 | final override fun apply(target: Project) {
32 | with(target.plugins) {
33 | if (!hasPlugin(ElasticAgentPlugin::class.java)) {
34 | apply(ElasticAgentPlugin::class.java)
35 | }
36 | }
37 | onApply(target, target.plugins.getPlugin(ElasticAgentPlugin::class.java))
38 | }
39 |
40 | abstract fun onApply(target: Project, agentPlugin: ElasticAgentPlugin)
41 | }
--------------------------------------------------------------------------------
/agent-common/src/main/java/co/elastic/otel/android/common/internal/logging/ELoggerFactory.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.common.internal.logging
20 |
21 | import org.slf4j.ILoggerFactory
22 | import org.slf4j.Logger
23 | import org.slf4j.helpers.NOPLogger
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | abstract class ELoggerFactory : ILoggerFactory {
30 |
31 | fun getLogger(type: Class<*>): Logger {
32 | return getLogger(id + " - " + type.simpleName)
33 | }
34 |
35 | val defaultLogger: Logger
36 | get() = getLogger(id)
37 |
38 | protected val id: String
39 | get() = "ELASTIC_AGENT"
40 |
41 | internal class Noop : ELoggerFactory() {
42 | override fun getLogger(name: String): Logger {
43 | return NOPLogger.NOP_LOGGER
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/opentelemetry/processors/logs/LogRecordAttributesProcessor.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.opentelemetry.processors.logs
20 |
21 | import co.elastic.otel.android.interceptor.Interceptor
22 | import io.opentelemetry.api.common.Attributes
23 | import io.opentelemetry.context.Context
24 | import io.opentelemetry.sdk.logs.LogRecordProcessor
25 | import io.opentelemetry.sdk.logs.ReadWriteLogRecord
26 |
27 | /**
28 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
29 | * any time.
30 | */
31 | internal class LogRecordAttributesProcessor(private val interceptor: Interceptor) :
32 | LogRecordProcessor {
33 |
34 | override fun onEmit(context: Context, logRecord: ReadWriteLogRecord) {
35 | logRecord.setAllAttributes(interceptor.intercept(logRecord.toLogRecordData().attributes))
36 | }
37 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/utilities/cache/PreferencesIntegerCacheHandler.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.utilities.cache
20 |
21 | import co.elastic.otel.android.internal.services.preferences.PreferencesService
22 |
23 | /**
24 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
25 | * any time.
26 | */
27 | internal class PreferencesIntegerCacheHandler(
28 | private val key: String,
29 | private val preferencesService: PreferencesService,
30 | private val defaultValue: Int = 0
31 | ) : CacheHandler {
32 |
33 | override fun retrieve(): Int {
34 | return preferencesService.retrieveInt(key, defaultValue)
35 | }
36 |
37 | override fun clear() {
38 | preferencesService.remove(key)
39 | }
40 |
41 | override fun store(value: Int) {
42 | preferencesService.store(key, value)
43 | }
44 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/features/diskbuffering/DiskBufferingConfiguration.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.features.diskbuffering
20 |
21 | /**
22 | * Defines the disk-buffering behavior.
23 | */
24 | sealed class DiskBufferingConfiguration {
25 |
26 | internal data class Enabled(
27 | val maxCacheFileSize: Int = 1024 * 1024,
28 | val maxCacheSize: Int = 15 * 1024 * 1024,
29 | val maxFileAgeForWrite: Long? = null,
30 | val minFileAgeForRead: Long? = null
31 | ) : DiskBufferingConfiguration()
32 |
33 | internal data object Disabled : DiskBufferingConfiguration()
34 |
35 | companion object {
36 | @JvmStatic
37 | fun enabled(): DiskBufferingConfiguration {
38 | return Enabled()
39 | }
40 |
41 | @JvmStatic
42 | fun disabled(): DiskBufferingConfiguration {
43 | return Disabled
44 | }
45 | }
46 | }
--------------------------------------------------------------------------------
/agent-common/src/main/java/co/elastic/otel/android/common/internal/logging/Elog.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.common.internal.logging
20 |
21 | import androidx.annotation.GuardedBy
22 | import java.util.concurrent.atomic.AtomicReference
23 | import org.slf4j.Logger
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | object Elog {
30 | private val loggerFactory = AtomicReference(ELoggerFactory.Noop())
31 |
32 | @GuardedBy("this")
33 | private var initialized = false
34 |
35 | fun init(factory: ELoggerFactory) {
36 | if (initialized) {
37 | return
38 | }
39 | loggerFactory.set(factory)
40 | initialized = true
41 | }
42 |
43 | fun getLogger(name: String): Logger {
44 | return loggerFactory.get().getLogger(name)
45 | }
46 |
47 | fun getLogger(): Logger = loggerFactory.get().defaultLogger
48 | }
49 |
--------------------------------------------------------------------------------
/instrumentation/okhttp/plugin/src/main/java/co/elastic/otel/android/okhttp/OkHttpInstrumentationPlugin.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.okhttp
20 |
21 | import co.elastic.otel.android.instrumentation.generated.okhttp.BuildConfig
22 | import co.elastic.otel.android.plugin.ElasticAgentPlugin
23 | import co.elastic.otel.android.plugin.internal.ByteBuddyDependencyAttacher
24 | import co.elastic.otel.android.plugin.internal.InstrumentationPlugin
25 | import org.gradle.api.Project
26 |
27 | class OkHttpInstrumentationPlugin : InstrumentationPlugin() {
28 |
29 | override fun onApply(target: Project, agentPlugin: ElasticAgentPlugin) {
30 | target.dependencies.add(
31 | "implementation",
32 | target.dependencies.create(BuildConfig.LIBRARY_URI)
33 | )
34 | agentPlugin.addBuildVariantListener(
35 | ByteBuddyDependencyAttacher(
36 | target,
37 | BuildConfig.BYTEBUDDY_PLUGIN_URI
38 | )
39 | )
40 | }
41 | }
--------------------------------------------------------------------------------
/.ci/release.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | ## This script runs the release given the different environment variables
3 | ## branch_specifier
4 | ## target_specifier
5 | ## dry_run
6 | ##
7 | ## NOTE: *_SECRET env variables are masked, hence if you'd like to avoid any
8 | ## surprises please use the suffix _SECRET for those values that contain
9 | ## any sensitive data. Buildkite can mask those values automatically
10 |
11 | set -e
12 |
13 | echo "--- Prepare release context"
14 | # Avoid detached HEAD since the release plugin requires to be on a branch
15 | git checkout -f "${branch_specifier}"
16 |
17 | set +x
18 | # Setting up common deploy params in env var
19 | export COMMON_GRADLE_DEPLOY_PARAMS="-Prelease=true --stacktrace"
20 |
21 | if [[ "$target_specifier" == "all" || "$target_specifier" == "mavenCentral" ]]; then
22 | if [[ "$dry_run" == "false" ]] ; then
23 | echo "--- Release the binaries to Maven Central"
24 | ./gradlew publishAndReleaseElasticToMavenCentral $COMMON_GRADLE_DEPLOY_PARAMS
25 | else
26 | echo "--- Release the binaries to Maven Central :package: (dry-run)"
27 | ./gradlew assemble
28 | fi
29 | fi
30 |
31 | if [[ "$target_specifier" == "all" || "$target_specifier" == "pluginPortal" ]]; then
32 | if [[ "$dry_run" == "false" ]] ; then
33 | echo "--- Release the binaries to the Gradle Plugin portal"
34 | ./gradlew publishPlugins -Pgradle.publish.key=$PLUGIN_PORTAL_KEY -Pgradle.publish.secret=$PLUGIN_PORTAL_SECRET $COMMON_GRADLE_DEPLOY_PARAMS
35 | else
36 | echo "--- Release the binaries to Gradle Plugin portal :package: (dry-run)"
37 | ./gradlew assemble
38 | fi
39 | fi
40 |
41 | echo "--- Archive the build folders with jar/aar files"
42 | find . -type d -name build -exec find {} \( -name '*.jar' -o -name '*.aar' \) -print0 \; | xargs -0 tar -cvf "${TARBALL_FILE:-dist.tar}"
43 |
44 | set -x
45 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/features/exportergate/GateSpanExporter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.features.exportergate
20 |
21 | import io.opentelemetry.sdk.common.CompletableResultCode
22 | import io.opentelemetry.sdk.trace.data.SpanData
23 | import io.opentelemetry.sdk.trace.export.SpanExporter
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | internal class GateSpanExporter(
30 | private val delegate: SpanExporter,
31 | private val spanQueue: ExporterGateQueue
32 | ) : SpanExporter {
33 |
34 | override fun export(spans: MutableCollection): CompletableResultCode {
35 | return spanQueue.enqueue(spans)
36 | }
37 |
38 | override fun flush(): CompletableResultCode {
39 | return delegate.flush()
40 | }
41 |
42 | override fun shutdown(): CompletableResultCode {
43 | return delegate.shutdown()
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/integration-test/app/src/main/res/drawable/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
9 |
10 |
16 |
19 |
22 |
23 |
24 |
25 |
31 |
--------------------------------------------------------------------------------
/instrumentation/okhttp/bytebuddy/src/main/java/co/elastic/otel/android/okhttp/internal/callback/OkHttpCallbackAdvice.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.okhttp.internal.callback;
20 |
21 | import net.bytebuddy.asm.Advice;
22 |
23 | import co.elastic.otel.android.okhttp.internal.plugin.OkHttpCallbackAdviceHelper;
24 | import co.elastic.otel.android.okhttp.internal.plugin.TracingCallback;
25 | import io.opentelemetry.context.Context;
26 | import okhttp3.Call;
27 | import okhttp3.Callback;
28 |
29 | /**
30 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
31 | * any time.
32 | */
33 | public class OkHttpCallbackAdvice {
34 |
35 | @Advice.OnMethodEnter
36 | public static void enter(
37 | @Advice.This Call call,
38 | @Advice.Argument(value = 0, readOnly = false) Callback callback) {
39 | if (OkHttpCallbackAdviceHelper.propagateContext(call)) {
40 | callback = new TracingCallback(callback, Context.current());
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/connectivity/Authentication.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.connectivity
20 |
21 | /**
22 | * Authentication strategies to connect to Elastic.
23 | */
24 | sealed class Authentication {
25 | /**
26 | * Represents an [API Key](https://www.elastic.co/guide/en/observability/current/apm-api-key.html) auth method.
27 | */
28 | data class ApiKey(val key: String) : Authentication() {
29 | override fun toString(): String {
30 | return "ApiKey(key.length=${key.length})"
31 | }
32 | }
33 |
34 | /**
35 | * Represent a [Secret token](https://www.elastic.co/guide/en/observability/current/apm-secret-token.html) auth method.
36 | */
37 | data class SecretToken(val token: String) : Authentication() {
38 | override fun toString(): String {
39 | return "SecretToken(token.length=${token.length})"
40 | }
41 | }
42 |
43 | /**
44 | * No auth method.
45 | */
46 | data object None : Authentication()
47 | }
--------------------------------------------------------------------------------
/instrumentation-test/buildSrc/src/main/kotlin/elastic.instrumentation-test-app.gradle.kts:
--------------------------------------------------------------------------------
1 | import java.util.Properties
2 | import org.jetbrains.kotlin.gradle.dsl.JvmTarget
3 |
4 | plugins {
5 | id("com.android.application")
6 | id("org.jetbrains.kotlin.android")
7 | }
8 |
9 | val properties = Properties()
10 | val propertiesFile = File(rootDir, "../gradle.properties")
11 | propertiesFile.inputStream().use {
12 | properties.load(it)
13 | }
14 |
15 | val javaVersionStr = properties.getProperty("elastic.java.compatibility") as String
16 | android {
17 | compileSdk = (properties.getProperty("elastic.android.compileSdk") as String).toInt()
18 |
19 | defaultConfig {
20 | minSdk = 26
21 | testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
22 | }
23 |
24 | testOptions {
25 | unitTests {
26 | isIncludeAndroidResources = true
27 | }
28 | animationsDisabled = true
29 | }
30 |
31 | val javaVersionStr = properties.getProperty("elastic.java.compatibility") as String
32 | val javaVersion = JavaVersion.toVersion(javaVersionStr)
33 | compileOptions {
34 | sourceCompatibility = javaVersion
35 | targetCompatibility = javaVersion
36 | }
37 | packaging.resources {
38 | excludes += "META-INF/LICENSE*"
39 | }
40 | }
41 |
42 | kotlin {
43 | compilerOptions {
44 | jvmTarget = JvmTarget.fromTarget(javaVersionStr)
45 | }
46 | }
47 |
48 | val libs = extensions.getByType().named("libs")
49 | dependencies {
50 | testImplementation(libs.findBundle("mocking").get())
51 | testImplementation(libs.findLibrary("junit4").get())
52 | testImplementation(libs.findLibrary("assertj").get())
53 | androidTestImplementation("co.elastic.otel.android:test-common")
54 | androidTestImplementation("co.elastic.otel.android:androidtest-agent-rule")
55 | }
--------------------------------------------------------------------------------
/instrumentation/oteladapter/library/src/main/java/co/elastic/otel/android/oteladapter/internal/delegate/meter/MeterProviderDelegator.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.oteladapter.internal.delegate.meter
20 |
21 | import co.elastic.otel.android.oteladapter.internal.delegate.tools.Delegator
22 | import io.opentelemetry.api.metrics.MeterBuilder
23 | import io.opentelemetry.api.metrics.MeterProvider
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | class MeterProviderDelegator(initialValue: MeterProvider) : Delegator(initialValue),
30 | MeterProvider {
31 |
32 | override fun meterBuilder(instrumentationScopeName: String): MeterBuilder? {
33 | return getDelegate().meterBuilder(instrumentationScopeName)
34 | }
35 |
36 | override fun getNoopValue(): MeterProvider {
37 | return NOOP_INSTANCE
38 | }
39 |
40 | companion object {
41 | val NOOP_INSTANCE: MeterProvider = MeterProvider.noop()
42 | }
43 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/features/exportergate/GateLogRecordExporter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.features.exportergate
20 |
21 | import io.opentelemetry.sdk.common.CompletableResultCode
22 | import io.opentelemetry.sdk.logs.data.LogRecordData
23 | import io.opentelemetry.sdk.logs.export.LogRecordExporter
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | internal class GateLogRecordExporter(
30 | private val delegate: LogRecordExporter,
31 | private val logRecordQueue: ExporterGateQueue
32 | ) : LogRecordExporter {
33 |
34 | override fun export(logs: MutableCollection): CompletableResultCode {
35 | return logRecordQueue.enqueue(logs)
36 | }
37 |
38 | override fun flush(): CompletableResultCode {
39 | return delegate.flush()
40 | }
41 |
42 | override fun shutdown(): CompletableResultCode {
43 | return delegate.shutdown()
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/instrumentation/oteladapter/library/src/main/java/co/elastic/otel/android/oteladapter/internal/delegate/logger/noop/NoopLoggerBuilder.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.oteladapter.internal.delegate.logger.noop
20 |
21 | import co.elastic.otel.android.oteladapter.internal.delegate.logger.LoggerDelegator
22 | import io.opentelemetry.api.logs.Logger
23 | import io.opentelemetry.api.logs.LoggerBuilder
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | class NoopLoggerBuilder private constructor() : LoggerBuilder {
30 |
31 | override fun setSchemaUrl(schemaUrl: String): LoggerBuilder {
32 | return this
33 | }
34 |
35 | override fun setInstrumentationVersion(instrumentationVersion: String): LoggerBuilder {
36 | return this
37 | }
38 |
39 | override fun build(): Logger {
40 | return LoggerDelegator.Companion.NOOP_INSTANCE
41 | }
42 |
43 | companion object {
44 | val INSTANCE = NoopLoggerBuilder()
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/logging/DefaultLoggingPolicy.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.logging
20 |
21 | import co.elastic.otel.android.internal.services.ServiceManager
22 | import co.elastic.otel.android.logging.LogLevel
23 | import co.elastic.otel.android.logging.LoggingPolicy
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | internal class DefaultLoggingPolicy internal constructor(debugMode: Boolean) :
30 | LoggingPolicy {
31 |
32 | private val logLevel by lazy { if (debugMode) LogLevel.DEBUG else LogLevel.INFO }
33 |
34 | override fun isEnabled(): Boolean {
35 | return true
36 | }
37 |
38 | override fun getMinimumLevel(): LogLevel {
39 | return logLevel
40 | }
41 |
42 | companion object {
43 | fun create(serviceManager: ServiceManager): DefaultLoggingPolicy {
44 | return DefaultLoggingPolicy(serviceManager.getAppInfoService().isInDebugMode())
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/opentelemetry/processors/spans/SpanAttributesProcessor.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.opentelemetry.processors.spans
20 |
21 | import co.elastic.otel.android.interceptor.Interceptor
22 | import io.opentelemetry.api.common.Attributes
23 | import io.opentelemetry.context.Context
24 | import io.opentelemetry.sdk.trace.ReadWriteSpan
25 | import io.opentelemetry.sdk.trace.ReadableSpan
26 | import io.opentelemetry.sdk.trace.SpanProcessor
27 |
28 | /**
29 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
30 | * any time.
31 | */
32 | internal class SpanAttributesProcessor(private val interceptor: Interceptor) :
33 | SpanProcessor {
34 |
35 | override fun onStart(parentContext: Context, span: ReadWriteSpan) {
36 | span.setAllAttributes(interceptor.intercept(span.attributes))
37 | }
38 |
39 | override fun isStartRequired(): Boolean = true
40 |
41 | override fun onEnd(span: ReadableSpan) {
42 |
43 | }
44 |
45 | override fun isEndRequired(): Boolean = false
46 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/time/ntp/SntpClient.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.time.ntp
20 |
21 | import co.elastic.otel.android.internal.time.SystemTimeProvider
22 | import java.io.Closeable
23 |
24 | /**
25 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
26 | * any time.
27 | */
28 | interface SntpClient : Closeable {
29 |
30 | fun fetchTimeOffset(currentTimeMillis: Long): Response
31 |
32 | companion object {
33 | internal fun create(systemTimeProvider: SystemTimeProvider): SntpClient {
34 | return SntpClientImpl(UdpClient("time.android.com", 123, 48), systemTimeProvider)
35 | }
36 | }
37 |
38 | sealed class Response {
39 | data class Success(val offsetMillis: Long) : Response()
40 | data class Error(val type: ErrorType) : Response()
41 | }
42 |
43 | enum class ErrorType {
44 | TRY_LATER,
45 | ORIGIN_TIME_NOT_MATCHING,
46 | INVALID_VERSION,
47 | INVALID_MODE,
48 | INVALID_TRANSMIT_TIMESTAMP
49 | }
50 | }
51 |
52 |
--------------------------------------------------------------------------------
/instrumentation/oteladapter/library/src/main/java/co/elastic/otel/android/oteladapter/internal/delegate/tools/MultipleReference.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.oteladapter.internal.delegate.tools
20 |
21 | import com.blogspot.mydailyjava.weaklockfree.WeakConcurrentSet
22 |
23 | /**
24 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
25 | * any time.
26 | */
27 | class MultipleReference(
28 | private val noopValue: T,
29 | private val delegatorFactory: (T) -> Delegator
30 | ) {
31 | private val references = WeakConcurrentSet>(WeakConcurrentSet.Cleaner.INLINE)
32 |
33 | @Suppress("UNCHECKED_CAST")
34 | fun maybeAdd(value: T): T {
35 | if (value != noopValue) {
36 | val delegator = delegatorFactory.invoke(value)
37 | references.expungeStaleEntries()
38 | references.add(delegator)
39 | return delegator as T
40 | }
41 |
42 | return value
43 | }
44 |
45 | fun reset() {
46 | for (delegator in references) {
47 | delegator?.reset()
48 | }
49 | references.clear()
50 | }
51 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/features/conditionaldrop/ConditionalDropSpanExporter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.features.conditionaldrop
20 |
21 | import co.elastic.otel.android.internal.opentelemetry.SignalType
22 | import io.opentelemetry.sdk.common.CompletableResultCode
23 | import io.opentelemetry.sdk.trace.data.SpanData
24 | import io.opentelemetry.sdk.trace.export.SpanExporter
25 |
26 | /**
27 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
28 | * any time.
29 | */
30 | internal class ConditionalDropSpanExporter(
31 | private val delegate: SpanExporter,
32 | private val drop: (SignalType) -> Boolean
33 | ) : SpanExporter {
34 |
35 | override fun export(spans: MutableCollection): CompletableResultCode {
36 | if (drop(SignalType.TRACE)) {
37 | return CompletableResultCode.ofSuccess()
38 | }
39 | return delegate.export(spans)
40 | }
41 |
42 | override fun flush(): CompletableResultCode {
43 | return delegate.flush()
44 | }
45 |
46 | override fun shutdown(): CompletableResultCode {
47 | return delegate.shutdown()
48 | }
49 | }
--------------------------------------------------------------------------------
/instrumentation/okhttp/bytebuddy/src/main/java/co/elastic/otel/android/okhttp/internal/OkHttpClientAdvice.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.okhttp.internal;
20 |
21 | import net.bytebuddy.asm.Advice;
22 |
23 | import co.elastic.otel.android.okhttp.internal.plugin.OkHttp3Singletons;
24 | import okhttp3.OkHttpClient;
25 |
26 | /**
27 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
28 | * any time.
29 | */
30 | public class OkHttpClientAdvice {
31 |
32 | @Advice.OnMethodEnter
33 | public static void enter(@Advice.Argument(0) OkHttpClient.Builder builder) {
34 | if (!builder.interceptors().contains(OkHttp3Singletons.CALLBACK_CONTEXT_INTERCEPTOR)) {
35 | builder.interceptors().add(0, OkHttp3Singletons.CALLBACK_CONTEXT_INTERCEPTOR);
36 | builder.interceptors().add(1, OkHttp3Singletons.RESEND_COUNT_CONTEXT_INTERCEPTOR);
37 | builder.interceptors().add(2, OkHttp3Singletons.CONNECTION_ERROR_INTERCEPTOR);
38 | }
39 | if (!builder.networkInterceptors().contains(OkHttp3Singletons.TRACING_INTERCEPTOR)) {
40 | builder.addNetworkInterceptor(OkHttp3Singletons.TRACING_INTERCEPTOR);
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/features/conditionaldrop/ConditionalDropLogRecordExporter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.features.conditionaldrop
20 |
21 | import co.elastic.otel.android.internal.opentelemetry.SignalType
22 | import io.opentelemetry.sdk.common.CompletableResultCode
23 | import io.opentelemetry.sdk.logs.data.LogRecordData
24 | import io.opentelemetry.sdk.logs.export.LogRecordExporter
25 |
26 | /**
27 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
28 | * any time.
29 | */
30 | internal class ConditionalDropLogRecordExporter(
31 | private val delegate: LogRecordExporter,
32 | private val drop: (SignalType) -> Boolean
33 | ) : LogRecordExporter {
34 |
35 | override fun export(logs: MutableCollection): CompletableResultCode {
36 | if (drop(SignalType.LOG)) {
37 | return CompletableResultCode.ofSuccess()
38 | }
39 | return delegate.export(logs)
40 | }
41 |
42 | override fun flush(): CompletableResultCode {
43 | return delegate.flush()
44 | }
45 |
46 | override fun shutdown(): CompletableResultCode {
47 | return delegate.shutdown()
48 | }
49 | }
--------------------------------------------------------------------------------
/instrumentation/okhttp/library/src/main/java/co/elastic/otel/android/okhttp/internal/delegate/InterceptorDelegator.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.okhttp.internal.delegate
20 |
21 | import java.util.concurrent.atomic.AtomicReference
22 | import okhttp3.Interceptor
23 | import okhttp3.Response
24 |
25 | /**
26 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
27 | * any time.
28 | */
29 | class InterceptorDelegator private constructor(private val initialValue: Interceptor) :
30 | Interceptor {
31 | private val delegate: AtomicReference = AtomicReference(initialValue)
32 |
33 | override fun intercept(chain: Interceptor.Chain): Response {
34 | return delegate.get().intercept(chain)
35 | }
36 |
37 | fun setDelegate(value: Interceptor) {
38 | delegate.set(value)
39 | }
40 |
41 | fun reset() {
42 | setDelegate(initialValue)
43 | }
44 |
45 | companion object {
46 | private val NOOP_INTERCEPTOR = Interceptor { chain -> chain.proceed(chain.request()) }
47 |
48 | @JvmStatic
49 | fun create(): InterceptorDelegator {
50 | return InterceptorDelegator(NOOP_INTERCEPTOR)
51 | }
52 | }
53 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/interceptor/Interceptor.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.interceptor
20 |
21 | import co.elastic.otel.android.internal.utilities.interceptor.MultiInterceptor
22 | import co.elastic.otel.android.internal.utilities.interceptor.NoopInterceptor
23 |
24 | /**
25 | * Generic interface that allows to intercept an object.
26 | */
27 | fun interface Interceptor {
28 |
29 | companion object {
30 | @JvmStatic
31 | fun composite(interceptors: List>): Interceptor {
32 | if (interceptors.isEmpty()) {
33 | return noop()
34 | }
35 |
36 | if (interceptors.size == 1) {
37 | return interceptors.first()
38 | }
39 |
40 | return MultiInterceptor(interceptors)
41 | }
42 |
43 | @JvmStatic
44 | fun noop(): Interceptor {
45 | return NoopInterceptor()
46 | }
47 | }
48 |
49 | /**
50 | * Intercepts an object of type [T].
51 | *
52 | * @param item The intercepted object.
53 | *
54 | * @return An object of type [T], it doesn't have to be the one received as parameter.
55 | */
56 | fun intercept(item: T): T
57 | }
--------------------------------------------------------------------------------
/agent-common/src/main/java/co/elastic/otel/android/common/internal/logging/BaseELogger.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.common.internal.logging
20 |
21 | import org.slf4j.Marker
22 | import org.slf4j.event.Level
23 | import org.slf4j.helpers.LegacyAbstractLogger
24 | import org.slf4j.helpers.MessageFormatter
25 |
26 | /**
27 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
28 | * any time.
29 | */
30 | abstract class BaseELogger protected constructor(tag: String) : LegacyAbstractLogger() {
31 | init {
32 | name = tag
33 | }
34 |
35 | override fun getFullyQualifiedCallerName(): String? {
36 | return null
37 | }
38 |
39 | override fun handleNormalizedLoggingCall(
40 | level: Level,
41 | marker: Marker?,
42 | msg: String,
43 | arguments: Array?,
44 | throwable: Throwable?
45 | ) {
46 | handleLoggingCall(
47 | level,
48 | MessageFormatter.arrayFormat(msg, arguments, throwable).message,
49 | throwable
50 | )
51 | }
52 |
53 | protected abstract fun handleLoggingCall(
54 | level: Level,
55 | formattedMessage: String,
56 | throwable: Throwable?
57 | )
58 | }
--------------------------------------------------------------------------------
/agent-sdk/src/test/java/co/elastic/otel/android/testutils/TestUdpServer.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.testutils
20 |
21 | import java.net.DatagramPacket
22 | import java.net.DatagramSocket
23 | import java.net.SocketException
24 |
25 | class TestUdpServer : Thread() {
26 | private val buf = ByteArray(256)
27 | val socket = DatagramSocket()
28 |
29 | @Volatile
30 | var responseHandler: (DatagramPacket) -> Unit = { clientPacket ->
31 | val response = "Server response".toByteArray()
32 | val packet =
33 | DatagramPacket(response, response.size, clientPacket.address, clientPacket.port)
34 | socket.send(packet)
35 | }
36 |
37 | override fun run() {
38 | while (true) {
39 | if (socket.isClosed) {
40 | continue
41 | }
42 | try {
43 | val packet = DatagramPacket(buf, buf.size)
44 | socket.receive(packet)
45 |
46 | responseHandler(packet)
47 | } catch (e: SocketException) {
48 | continue
49 | }
50 | }
51 | }
52 |
53 | fun close() {
54 | socket.close()
55 | }
56 |
57 | fun getPort(): Int {
58 | return socket.localPort
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/catalog-info.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | # yaml-language-server: $schema=https://gist.githubusercontent.com/elasticmachine/988b80dae436cafea07d9a4a460a011d/raw/rre.schema.json
3 | apiVersion: backstage.io/v1alpha1
4 | kind: Resource
5 | metadata:
6 | name: buildkite-pipeline-apm-agent-android-release
7 | tags:
8 | - buildkite
9 | - gpg-sign
10 | - gradle-portal
11 | - maven-central
12 | - release
13 | spec:
14 | implementation:
15 | apiVersion: buildkite.elastic.dev/v1
16 | kind: Pipeline
17 | metadata:
18 | description: 'The APM Android Agent Release :pipeline:'
19 | name: apm-agent-android-release
20 | spec:
21 | pipeline_file: .buildkite/release.yml
22 | provider_settings:
23 | trigger_mode: none
24 | repository: elastic/apm-agent-android
25 | teams:
26 | apm-agent-android: {}
27 | everyone:
28 | access_level: READ_ONLY
29 | observablt-robots: {}
30 | observablt-robots-automation: {}
31 | owner: group:observablt-robots
32 | type: buildkite-pipeline
33 |
34 | ---
35 | # A Component for the release GitHub action
36 | #
37 | # yaml-language-server: $schema=https://json.schemastore.org/catalog-info.json
38 | apiVersion: backstage.io/v1alpha1
39 | kind: Resource
40 | metadata:
41 | name: apm-agent-android-release
42 | description: GitHub action to run the release process for the APM Agent Android
43 | annotations:
44 | backstage.io/source-location: url:https://github.com/elastic/apm-agent-android/blob/main/.github/workflows/release.yml
45 | github.com/project-slug: elastic/apm-agent-android
46 | github.com/team-slug: elastic/apm-agent-android
47 | tags:
48 | - github
49 | - gpg-sign
50 | - gradle-portal
51 | - maven-central
52 | - release
53 | - user:obltmachine
54 | links:
55 | - title: GitHub action
56 | url: https://github.com/elastic/apm-agent-android/actions/workflows/release.yml
57 | spec:
58 | type: github-actions
59 | owner: group:apm-agent-android
60 | lifecycle: production
61 | dependsOn:
62 | - "system:github-actions"
63 | - "user:obltmachine"
64 |
--------------------------------------------------------------------------------
/instrumentation/okhttp/library/src/main/java/co/elastic/otel/android/okhttp/internal/OkHttpInstrumentation.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.okhttp.internal
20 |
21 | import android.app.Application
22 | import co.elastic.otel.android.api.ElasticOtelAgent
23 | import co.elastic.otel.android.instrumentation.internal.Instrumentation
24 | import co.elastic.otel.android.instrumentation.okhttp.BuildConfig
25 | import co.elastic.otel.android.okhttp.internal.plugin.OkHttp3Singletons
26 | import com.google.auto.service.AutoService
27 |
28 | /**
29 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
30 | * any time.
31 | */
32 | @AutoService(Instrumentation::class)
33 | class OkHttpInstrumentation : Instrumentation {
34 |
35 | override fun install(
36 | application: Application,
37 | agent: ElasticOtelAgent
38 | ): Instrumentation.Installation {
39 | OkHttp3Singletons.configure(agent.getOpenTelemetry())
40 | return Instrumentation.Installation { OkHttp3Singletons.reset() }
41 | }
42 |
43 | override fun getId(): String {
44 | return BuildConfig.INSTRUMENTATION_ID
45 | }
46 |
47 | override fun getVersion(): String {
48 | return BuildConfig.INSTRUMENTATION_VERSION
49 | }
50 | }
--------------------------------------------------------------------------------
/instrumentation/okhttp/library/src/main/java/co/elastic/otel/android/okhttp/internal/plugin/TracingCallback.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.okhttp.internal.plugin;
20 |
21 | import java.io.IOException;
22 |
23 | import io.opentelemetry.context.Context;
24 | import io.opentelemetry.context.Scope;
25 | import okhttp3.Call;
26 | import okhttp3.Callback;
27 | import okhttp3.Response;
28 |
29 | /**
30 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
31 | * any time.
32 | */
33 | public final class TracingCallback implements Callback {
34 | private final Callback delegate;
35 | private final Context callingContext;
36 |
37 | public TracingCallback(Callback delegate, Context callingContext) {
38 | this.delegate = delegate;
39 | this.callingContext = callingContext;
40 | }
41 |
42 | @Override
43 | public void onFailure(Call call, IOException e) {
44 | try (Scope scope = callingContext.makeCurrent()) {
45 | delegate.onFailure(call, e);
46 | }
47 | }
48 |
49 | @Override
50 | public void onResponse(Call call, Response response) throws IOException {
51 | try (Scope scope = callingContext.makeCurrent()) {
52 | delegate.onResponse(call, response);
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/agent-sdk/src/test/java/co/elastic/otel/android/testutils/NtpUtils.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.testutils
20 |
21 | import co.elastic.otel.android.internal.time.ntp.NtpPacket
22 |
23 | object NtpUtils {
24 | private const val NTP_EPOCH_DIFF_MILLIS = 2208988800000L // According to RFC-868.
25 |
26 | internal fun createNtpPacket(
27 | clientCurrentTime: Long,
28 | expectedOffset: Long = 100L,
29 | receiveServerTime: Long = clientCurrentTime + expectedOffset,
30 | transmitServerTime: Long = receiveServerTime + 5,
31 | originateTimestamp: Long = clientCurrentTime,
32 | responseLeapIndicator: Int = 0,
33 | requestVersionNumber: Int = 4,
34 | responseVersionNumber: Int = requestVersionNumber,
35 | responseMode: Int = 4,
36 | responseStratum: Int = 1
37 | ): NtpPacket {
38 | return NtpPacket(
39 | responseLeapIndicator,
40 | responseVersionNumber,
41 | responseMode,
42 | responseStratum,
43 | toNtpTime(originateTimestamp),
44 | toNtpTime(receiveServerTime),
45 | if (transmitServerTime != 0L) toNtpTime(transmitServerTime) else 0
46 | )
47 | }
48 |
49 | fun toNtpTime(time: Long): Long {
50 | return time + NTP_EPOCH_DIFF_MILLIS
51 | }
52 | }
--------------------------------------------------------------------------------
/agent-sdk/src/main/java/co/elastic/otel/android/internal/exporters/configurable/MutableSpanExporter.kt:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed to Elasticsearch B.V. under one or more contributor
3 | * license agreements. See the NOTICE file distributed with
4 | * this work for additional information regarding copyright
5 | * ownership. Elasticsearch B.V. licenses this file to you under
6 | * the Apache License, Version 2.0 (the "License"); you may
7 | * not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * http://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing,
13 | * software distributed under the License is distributed on an
14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | * KIND, either express or implied. See the License for the
16 | * specific language governing permissions and limitations
17 | * under the License.
18 | */
19 | package co.elastic.otel.android.internal.exporters.configurable
20 |
21 | import io.opentelemetry.sdk.common.CompletableResultCode
22 | import io.opentelemetry.sdk.trace.data.SpanData
23 | import io.opentelemetry.sdk.trace.export.SpanExporter
24 | import java.util.concurrent.atomic.AtomicReference
25 |
26 | /**
27 | * This class is internal and is hence not for public use. Its APIs are unstable and can change at
28 | * any time.
29 | */
30 | internal class MutableSpanExporter : SpanExporter {
31 | private val delegate = AtomicReference()
32 |
33 | override fun export(spans: MutableCollection): CompletableResultCode {
34 | return delegate.get()?.export(spans) ?: CompletableResultCode.ofSuccess()
35 | }
36 |
37 | override fun flush(): CompletableResultCode {
38 | return delegate.get()?.flush() ?: CompletableResultCode.ofSuccess()
39 | }
40 |
41 | override fun shutdown(): CompletableResultCode {
42 | return delegate.get()?.shutdown() ?: CompletableResultCode.ofSuccess()
43 | }
44 |
45 | fun getDelegate(): SpanExporter? {
46 | return delegate.get()
47 | }
48 |
49 | fun setDelegate(value: SpanExporter?) {
50 | delegate.set(value)
51 | }
52 | }
--------------------------------------------------------------------------------