Pull requests for bug fixes are welcome, but before submitting new features or changes to current functionality open an issue and discuss your ideas or propose the changes you wish to make. After a resolution is reached a PR can be submitted for review.
In order to build and test this whole repository you need JDK 11+. Some instrumentations and tests may put constraints on which java versions they support. See [Executing tests with specific java version](#Executing tests with specific java version) below.
OpenTelemetry Auto Instrumentation java agent's jar can logically be divided into 3 parts.
This module consists of single class
io.opentelemetry.auto.bootstrap.AgentBootstrap
which implements Java
instrumentation
agent.
This class is loaded during application startup by application classloader.
Its sole responsibility is to push agent's classes into JVM's bootstrap
classloader and immediately delegate to
io.opentelemetry.auto.bootstrap.Agent
(now in the bootstrap class loader)
class from there.
This module contains support classes for actual instrumentations to be loaded
later and separately. These classes should be available from all possible
classloaders in the running application. For this reason java-agent
puts
all these classes into JVM's bootstrap classloader. For the same reason this
module should be as small as possible and have as few dependencies as
possible. Otherwise, there is a risk of accidentally exposing this classes to
the actual application.
Contains everything necessary to make instrumentation machinery work, including integration with ByteBuddy and actual library-specific instrumentations. As these classes depend on many classes from different libraries, it is paramount to hide all these classes from the host application. This is achieved in the following way:
- When
java-agent
module builds the final agent, it moves all classes frominstrumentation
submodules andagent-tooling
module into a separate folder inside final jar file, calledauto-tooling-and-instrumentation.isolated
. In addition, the extension of all class files is changed fromclass
toclassdata
. This ensures that general classloaders cannot find nor load these classes. - When
io.opentelemetry.auto.bootstrap.Agent
starts up, it creates an instance ofio.opentelemetry.auto.bootstrap.AgentClassLoader
, loads anio.opentelemetry.auto.tooling.AgentInstaller
from thatAgentClassLoader
and then passes control on to theAgentInstaller
(now in theAgentClassLoader
). TheAgentInstaller
then installs all of the instrumentations with the help of ByteBuddy.
The complicated process above ensures that the majority of auto-instrumentation agent's classes are totally isolated from application classes, and an instrumented class from arbitrary classloader in JVM can still access helper classes from bootstrap classloader.
If you now look inside
java-agent/build/libs/opentelemetry-auto-<version>.jar
, you will see the
following "clusters" of classes:
auto-tooling-and-instrumentation.isolated/
- containsagent-tooling
module andinstrumentation
submodules, loaded and isolated insideAgentClassLoader
. Including OpenTelemetry SDK (and the built-in exporters when using the-all
artifact).io/opentelemetry/auto/bootstrap/
- containsagent-bootstrap
module and available in bootstrap classloader.io/opentelemetry/auto/shaded/
- contains OpenTelemetry API and its dependencies. Shaded during creation ofjava-agent
jar file by Shadow Gradle plugin.
For developers testing code changes before a release is complete, there are
snapshot builds of the master
branch. They are available from
JFrog OSS repository
Build using Java 11:
gradle assemble
and then you can find the java agent artifact at
java-agent/build/lib/opentelemetry-auto-<version>-all.jar
.
Open Telemetry Auto Instrumentation's minimal supported version is java 7. All jar files that we produce, unless noted otherwise, have bytecode compatible with java 7 runtime. In addition to that we test our code with all later java versions as well: from 8 to 14.
Some libraries that we auto-instrument may have higher minimal requirements. In this case we compile and test corresponding auto-instrumentation with higher java version as required by library. The resulting classes will have higher bytecode level, but as it matches library's java version, no runtime problem arise.
Executing ./gradlew instrumentation:test
will run tests for all supported
auto-instrumentations using that java version which runs the Gradle build
itself. These tests usually use the minimal supported version of the
instrumented library.
In addition to that each instrumentation has a separate test set called
latestDepTest
. It was created by Gradle test sets
plugin. It uses the
very same tests as before, but declares a dynamic dependency on the latest
available version of this library. You can run them all by executing
./gradlew latestDepTest
.
In order to run tests on a specific java version, just execute ./gradlew testJava7
(or testJava11
or latestDepTestJava14
etc). Then Gradle task
rule will kick in and do the following:
- check, if Gradle already runs on a java with required version
- if not, look for an environment variable named
JAVA_N_HOME
, whereN
is the requested java version - if Gradle could not found requested java version, then build will fail
- Gradle will now find all corresponding test tasks and configure them to use java executable of the requested version.
This works both for tasks named test
and latestDepTest
. But currently
does not work for other custom test tasks, such as those created by test sets
plugin.
We follow the Google Java Style Guide. Our build will fail if source code is not formatted according to that style.
The main goal is to avoid extensive reformatting caused by different IDEs having different opinion about how things should be formatted by establishing.
Running
./gradlew spotlessApply
reformats all the files that need reformatting.
Running
./gradlew spotlessCheck
runs formatting verify task only.
To completely delegate code style formatting to the machine, there is a pre-commit hook setup to verify formatting before committing. It can be activated with this command:
git config core.hooksPath .githooks
As additional convenience for IntelliJ Idea users, we provide .editorconfig
file. Idea will automatically use it to adjust its code formatting settings.
It does not support all required rules, so you still have to run
googleJavaFormat
from time to time.
Required plugins:
Suggested plugins and settings:
- Editor > Code Style > Java/Groovy > Imports
- Google Java Format
- Save Actions
Approvers:
- Anuraag Agrawal, AWS
- John Watson, New Relic
Maintainers:
- Nikita Salnikov-Tarnovski, Splunk
- Trask Stalnaker, Microsoft
- Tyler Benson, DataDog
See the community membership document in OpenTelemetry community repo.