Welcome to OpenTelemetry Android repository!
Before you start - see OpenTelemetry general contributor guide requirements and recommendations.
Make sure to review the projects license and sign the CNCF CLA. A signed CLA will be enforced by an automatic check once you submit a PR, but you can also sign it after opening your PR.
Java 17 or higher is required to build the projects in this repository. The built artifacts can be used with Android API Level 23 and higher. API levels 23 to 25 require desugaring of the core library.
- Clone the repository
git clone https://github.com/open-telemetry/opentelemetry-android.git
cd opentelemetry-android
- To build the android artifact, run the gradle wrapper with
assemble:
./gradlew assemble
The output artifacts will be in instrumentation/build/outputs/.
- To run the tests and code checks:
./gradlew check
Pull requests are welcome! As an open source community project, OpenTelemetry Android relies on code submissions from its contributors. There are a few things to consider before submitting a pull request.
- Before starting work, check the open issues list to see if an issue already exists. If it does, you may comment on the issue and ask to be assigned. Assignments communicate to other contributors that the work has already been started and is in progress.
- Issues are NOT required for every PR. You may readily submit a PR without an issue.
- Keep your PRs small! This cannot be emphasized enough. There is no formal upper bound on size, but PRs that are thousands of lines long take a very long time and lots of effort to review. Find ways of decomposing the work into smaller units to keep the size of your PRs down. Incremental changes are favored over widespread/far-reaching refactors.
- Keep your PRs single-purpose! This is subjective, but PRs should usually have a single purpose/idea/goal and make one clear change. Contributors should avoid making unrelated changes to separate code areas in the same PR. Keeping PRs single-purpose will also help to keep them small.
- If an issue exists, mention it in the PR description. If the PR is the final effort
for a given issue, please add
Resolves #nnn(where nnn is the issue number) somewhere in the PR description, so that the issue can be automatically closed when the PR is merged. This also leaves a nice audit trail for future developers.
The process for merging pull requests after review approval differs depending on its tier. PRs are classified into the following tiers based on the scope and risk of the change:
PRs generated by Renovate or similar bots that bump dependency versions, as well as minor
maintenance updates (e.g. fixing a typo in a comment, updating .gitignore).
- Approvals required: 1
- Waiting period: None — may be merged immediately after approval.
Bug fixes, test improvements, documentation updates, internal refactors that do not affect the public API surface, and new instrumentation additions that follow established patterns.
- Approvals required: 1
- Waiting period: None — may be merged immediately after approval, though the author should use good judgment and wait for additional feedback if the change is non-trivial.
New features, large refactors, changes to build infrastructure or convention plugins, and any change that is wide in scope or touches multiple modules.
- Approvals required: 2
- Waiting period: At least 1 day after the last significant update to give other maintainers time to review.
Any change that modifies the public API surface (detected by apiCheck), including additions,
modifications, or removals of public types, methods, or fields.
- Approvals required: 2
- Waiting period: At least 2 days after the last significant update so that all maintainers have a chance to review and provide feedback. Discussing API changes in the SIG meeting is always encouraged.
- When a PR spans multiple tiers, apply the rules of the highest applicable tier.
- The waiting period is counted from the last push that materially changes the PR (not from review-only updates like rebasing or fixing CI).
- Maintainers may shorten the waiting period when there is broad consensus or urgency (e.g. a security fix), but should document the reason in the PR.
We use spotless to enforce a consistent code style throughout the project. This includes reformatting (linting) of both source code and markdown.
Before submitting a PR, you should ensure that your code is linted. We use the spotless gradle plugin to make this easy. You should run it like this:
./gradlew spotlessApply
By default we use JUnit 5, with some exceptions:
- When writing Android tests.
- When writing Robolectric tests.
For both, Android and Robolectric tests, we use JUnit 4 as they currently don't support JUnit 5.
This project has standardized on
AssertJ
for fluent test assertions, rather than the default JUnit assertions. Please
use AssertJ when writing tests. For example, instead of assertEquals(that, thiz)
you should write assertThat(thiz).isEqualTo(that).
For clarity, assert methods should be brought in via static import.
OpenTelemetry Android has standardized on MockK as the preferred Kotlin mocking framework for tests. When writing test code, please use MockK instead of Mockito.
For instrumentations that require bytecode weaving we create a test application with Android tests as those are the only kind of tests that support library bytecode weaving. Ideally we should be able to validate bytecode weaving only by creating tests using Robolectric, but that's not supported for now (for more info on the matter take a look at this google issue about it).
The test application module should be placed in the same directory as the instrumentation agent and
library modules and should be named testing, as shown below:
instrumentation/
├─ my-instrumentation/
│ ├─ agent/
│ ├─ library/
│ ├─ testing/
You can take a look at how it's done for the OkHttp instrumentation here for reference.
This project leverages the kotlin binary compatibility validator to detect and make explicit/intentional any changes to the public api surface. If you have made changes locally and wish to see if there are api changes, you can use the following:
$ ./gradlew apiCheck
Note that apiCheck is run as part of the check task as well, so if there are unresolved
api changes, the check will fail.
If you have an intentional changes, you can regenerate the api file(s) with the following:
$ ./gradlew apiDump