Skip to content

Commit

Permalink
Rebase otel-java snapshot branch (#461)
Browse files Browse the repository at this point in the history
* Define packages in exporter class loader (#409)

* Update docs about needing java 11 to build (#412)

* Update version to 0.3.0 (#413)

* Update the README (#414)

* Move build and configure to top as getting started section
* Add manual instrumentation section
* Document `@WithSpan` annotation
* Move developer specific information to CONTRIBUTING.md
* Cleanup formatting and use consistent spacing

* Update version to 0.4.0-SNAPSHOT (#415)

* Update CONTRIBUTING.md back to Java 11 (#419)

* Add Zipkin exporter support  (#411)

* #375 Add Zipkin exporter support

Signed-off-by: Sergei Malafeev <[email protected]>

* #375 use OkHttpSender for Zipkin exporter

Signed-off-by: Sergei Malafeev <[email protected]>

* #375 add Zipkin exporter to README

Signed-off-by: Sergei Malafeev <[email protected]>

Co-authored-by: Trask Stalnaker <[email protected]>

* Remove inactive maintainer (#420)

* Fix brolen anchor link (#422)

* Fix khttp instrumentation in case of absent or read-only headers map (#416)

* Add new approver (#429)

* Fix sqlNormalizerEnabled initialization (#432)

* Remove unused config (#424)

* Change names of servlet based server spans (#428)

* Add documentation describing non-obvious points of Servlet instrumentations

* Change names of servlet based server spans

* Fix java google format (#439)

* Remove deprecated usage from internal instrumentation (DataDog/dd-trace-java#1441)

* Update gradle to 6.4 (DataDog/dd-trace-java#1443)

* Migrate lettuce instrumentation away from deprecated finishSpanOnClose (DataDog/dd-trace-java#1445)

* Make Retrys consistent (DataDog/dd-trace-java#1442)

* Rename java packages for lettuce 4 and 5 to not have collisions (DataDog/dd-trace-java#1450)

* Adding an option to manually disable Kafka headers (DataDog/dd-trace-java#1448)

* Add version specific names to allow disabling only a specific version (DataDog/dd-trace-java#1456)

* Attempt to improve muzzle time by randomly ignoring versions until 10 remain (DataDog/dd-trace-java#1451)

* Save circle cache with name matching restore patterns (DataDog/dd-trace-java#1457)

* Wrap log statements using varargs to avoid object allocation (DataDog/dd-trace-java#1466)

* Grizzly-http and grizzly-client instrumentation (DataDog/dd-trace-java#1365)

* More refactoring for ScopeManager (DataDog/dd-trace-java#1467)

* Remove Java 9 and 10 from the build (DataDog/dd-trace-java#1473)

* Disable CI cache for muzzle (DataDog/dd-trace-java#1479)

* Separate out core instrumentation for AWS SDK to allow manual setup o… (#421)

* Separate out core instrumentation for AWS SDK to allow manual setup of instrumentation.

* Instrumentation core test

* Fix sporadic Elasticsearch test failures (#444)

* Fix sporadic grizzly test failure (#448)

* Fixes integration with latest version of Finatra (#450)

* #425 allow only one propagator per concern (#451)

* Updates to reflect new repo name (#454)

* Remove printlns that were accidentally committed (#459)

* Remove unnecessary version constant (#455)

Co-authored-by: Trask Stalnaker <[email protected]>
Co-authored-by: Steve Flanders <[email protected]>
Co-authored-by: Sergei Malafeev <[email protected]>
Co-authored-by: Tyler Benson <[email protected]>
Co-authored-by: Nikolay Martynov <[email protected]>
Co-authored-by: Brian Devins-Suresh <[email protected]>
Co-authored-by: Richard Startin <[email protected]>
Co-authored-by: Anuraag Agrawal <[email protected]>
  • Loading branch information
9 people authored May 31, 2020
1 parent f6e16c8 commit 72c9224
Show file tree
Hide file tree
Showing 147 changed files with 3,430 additions and 493 deletions.
48 changes: 8 additions & 40 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ defaults: &defaults
JAVA_HOME: /usr/local/openjdk-11

cache_keys: &cache_keys
# Reset the cache approx every release
keys:
- trace-java-{{ checksum "trace-java.gradle" }}-{{ .Branch }}-{{ .Revision }}
- trace-java-{{ checksum "trace-java.gradle" }}-{{ .Branch }}
- trace-java-{{ checksum "trace-java.gradle" }}
# Rev the version when the cache gets too big
- trace-java-v1-{{ .Branch }}-{{ .Revision }}
- trace-java-v1-{{ .Branch }}
# - dd-trace-java-v1-

jobs:
build:
Expand All @@ -27,7 +27,7 @@ jobs:

- run:
name: Build Project
command: GRADLE_OPTS="-Dorg.gradle.jvmargs='-Xmx1G -Xms64M' -Dota.forkedMaxHeapSize=1G -Dota.forkedMinHeapSize=64M" ./gradlew clean compileTestGroovy compileLatestDepTestGroovy compileTestScala compileLatestDepTestScala compileTestJava compileLatestDepTestJava :opentelemetry-auto:shadowJar :auto-exporters:opentelemetry-auto-exporters-jaeger:shadowJar :auto-exporters:opentelemetry-auto-exporters-otlp:shadowJar :auto-exporters:opentelemetry-auto-exporters-logging:shadowJar --build-cache --parallel --stacktrace --no-daemon --max-workers=8
command: GRADLE_OPTS="-Dorg.gradle.jvmargs='-Xmx1G -Xms64M' -Dota.forkedMaxHeapSize=1G -Dota.forkedMinHeapSize=64M" ./gradlew clean compileTestGroovy compileLatestDepTestGroovy compileTestScala compileLatestDepTestScala compileTestJava compileLatestDepTestJava :opentelemetry-auto:shadowJar :auto-exporters:opentelemetry-auto-exporters-jaeger:shadowJar :auto-exporters:opentelemetry-auto-exporters-otlp:shadowJar :auto-exporters:opentelemetry-auto-exporters-logging:shadowJar :auto-exporters:opentelemetry-auto-exporters-zipkin:shadowJar --build-cache --parallel --stacktrace --no-daemon --max-workers=8

- run:
name: Collect Libs
Expand All @@ -44,7 +44,7 @@ jobs:
- workspace

- save_cache:
key: trace-java-{{ checksum "trace-java.gradle" }}-{{ .Branch }}-{{ .Revision }}
key: trace-java-v1-{{ .Branch }}-{{ .Revision }}
paths: ~/.gradle


Expand Down Expand Up @@ -114,16 +114,6 @@ jobs:
environment:
- TEST_TASK: testJavaZULU8

test_9:
<<: *default_test_job
environment:
- TEST_TASK: testJava9

test_10:
<<: *default_test_job
environment:
- TEST_TASK: testJava10

test_11:
<<: *default_test_job
environment:
Expand Down Expand Up @@ -188,19 +178,13 @@ jobs:
steps:
- checkout

- restore_cache:
# Reset the cache approx every release
keys:
- trace-java-muzzle-{{ checksum "trace-java.gradle" }}
# We are not running with a cache here because it gets very big and ends up taking more time
# restoring/saving than the actual increase in time it takes just downloading the artifacts each time.

- run:
name: Verify Muzzle
command: SKIP_BUILDSCAN="true" GRADLE_OPTS="-Dorg.gradle.jvmargs='-Xmx4G -Xms64M' -Dota.forkedMaxHeapSize=4G -Dota.forkedMinHeapSize=64M" ./gradlew muzzle --parallel --stacktrace --no-daemon --max-workers=16

- save_cache:
key: trace-java-muzzle-{{ checksum "trace-java.gradle" }}
paths: ~/.gradle

publish: &publish
<<: *defaults
steps:
Expand Down Expand Up @@ -265,18 +249,6 @@ workflows:
# filters:
# tags:
# only: /.*/
# - test_9:
# requires:
# - build
# filters:
# tags:
# only: /.*/
# - test_10:
# requires:
# - build
# filters:
# tags:
# only: /.*/
- test_11:
requires:
- build
Expand Down Expand Up @@ -341,8 +313,6 @@ workflows:
- test_latest
# - test_ibm8
# - test_zulu8
# - test_9
# - test_10
- test_11
# - test_zulu11
# - test_12
Expand All @@ -364,8 +334,6 @@ workflows:
- test_latest
# - test_ibm8
# - test_zulu8
# - test_9
# - test_10
- test_11
# - test_zulu11
# - test_12
Expand Down
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@
# https://help.github.com/en/articles/about-code-owners
#

* @jkwatson @safris @trask @tylerbenson
* @iNikem @jkwatson @trask @tylerbenson
224 changes: 146 additions & 78 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,108 +1,173 @@
## Contributing

Pull requests for bug fixes are welcome, but before submitting new features or changes to current functionality [open an issue](https://github.com/open-telemetry/opentelemetry-auto-instr-java/issues/new)
and discuss your ideas or propose the changes you wish to make. After a resolution is reached a PR can be submitted for review.
Pull requests for bug fixes are welcome, but before submitting new features
or changes to current functionality [open an
issue](https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/new)
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 fully build and test this whole repository you need the following:
* Installed both JDK 8 and 9.
* Java 8 should be set as default: `java -version` should give you version 8.
* Defined environment variables `JAVA_8_HOME` and `JAVA_9_HOME` which point to the corresponding java homes.
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.

### Plugin structure
OpenTelemetry Auto Instrumentation java agent's jar can logically be divided into 3 parts.

OpenTelemetry Auto Instrumentation java agent's jar can logically be divided
into 3 parts.

#### `java-agent` module
This module consists of single class `io.opentelemetry.auto.bootstrap.AgentBootstrap`
which implements [Java instrumentation agent](https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/package-summary.html).
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 consists of single class
`io.opentelemetry.auto.bootstrap.AgentBootstrap` which implements [Java
instrumentation
agent](https://docs.oracle.com/javase/7/docs/api/java/lang/instrument/package-summary.html).
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.

#### `agent-bootstrap` module
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.

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.

#### `agent-tooling` module and `instrumentation` submodules
Contains everything necessary to make instrumentation machinery work,
including integration with [ByteBuddy](https://bytebuddy.net/) 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 from `instrumentation` submodules
and `agent-tooling` module into a separate folder inside final jar file, called `auto-tooling-and-instrumentation.isolated`.
In addition, the extension of all class files is changed from `class` to `classdata`.
This ensures that general classloaders cannot find nor load these classes.
* When `io.opentelemetry.auto.bootstrap.Agent` starts up,
it creates an instance of `io.opentelemetry.auto.bootstrap.AgentClassLoader`,
loads an `io.opentelemetry.auto.tooling.AgentInstaller` from that `AgentClassLoader`
and then passes control on to the `AgentInstaller` (now in the `AgentClassLoader`). The `AgentInstaller` 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.

Contains everything necessary to make instrumentation machinery work,
including integration with [ByteBuddy](https://bytebuddy.net/) 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 from
`instrumentation` submodules and `agent-tooling` module into a separate
folder inside final jar file, called
`auto-tooling-and-instrumentation.isolated`. In addition, the extension of
all class files is changed from `class` to `classdata`. This ensures that
general classloaders cannot find nor load these classes.
- When `io.opentelemetry.auto.bootstrap.Agent` starts up, it creates an
instance of `io.opentelemetry.auto.bootstrap.AgentClassLoader`, loads an
`io.opentelemetry.auto.tooling.AgentInstaller` from that `AgentClassLoader`
and then passes control on to the `AgentInstaller` (now in the
`AgentClassLoader`). The `AgentInstaller` 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.

#### Agent jar structure
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/` - contains `agent-tooling` module and
`instrumentation` submodules, loaded and isolated inside `AgentClassLoader`.
Including OpenTelemetry SDK.
* `io/opentelemetry/auto/bootstrap/` - contains `agent-bootstrap` module and available in
bootstrap classloader.
* `io/opentelemetry/auto/shaded/` - contains OpenTelemetry API and its dependencies.
Shaded during creation of `java-agent` jar file by Shadow Gradle plugin.

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/` - contains `agent-tooling`
module and `instrumentation` submodules, loaded and isolated inside
`AgentClassLoader`. Including OpenTelemetry SDK.
- `io/opentelemetry/auto/bootstrap/` - contains `agent-bootstrap` module and
available in bootstrap classloader.
- `io/opentelemetry/auto/shaded/` - contains OpenTelemetry API and its
dependencies. Shaded during creation of `java-agent` jar file by Shadow
Gradle plugin.

### Building

#### Snapshot builds

For developers testing code changes before a release is complete, there are
snapshot builds of the `master` branch. When a PR is merged to `master`, a
circleci build is kicked off as a github action which shows up as a github
check on the git commit on `master` branch, i.e. a green checkmark. Clicking
on the green checkmark you can view the `build_test_deploy` workflow and the
`build` job shows the artifacts hosted on circleci. The artifacts will be
named like:

```
libs/exporter-support-<version>-SNAPSHOT.jar
libs/opentelemetry-auto-<version>-SNAPSHOT.jar
libs/opentelemetry-auto-exporters-jaeger-<version>-SNAPSHOT.jar
libs/opentelemetry-auto-exporters-logging-<version>-SNAPSHOT.jar
libs/opentelemetry-auto-exporters-otlp-<version>-SNAPSHOT.jar
```

#### Building from source

Build using Java 11:

```gradle assemble```

and then you can find the java agent artifact at
`java-agent/build/lib/opentelemetry-auto-<version>.jar`.

### Testing

#### Java versions

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.
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.
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.

#### Instrumentation tests
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](https://github.com/unbroken-dome/gradle-testsets-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`.
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](https://github.com/unbroken-dome/gradle-testsets-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`.

#### Executing tests with specific java version
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`, where `N` 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.
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`, where `N` 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.

### Style guideline

We follow the [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html).
Our build will fail if source code is not formatted according to that style.
We follow the [Google Java Style
Guide](https://google.github.io/styleguide/javaguide.html). Our build will
fail if source code is not formatted according to that style.

To verify code style manually run the following command,
which uses [google-java-format](https://github.com/google/google-java-format) library:
To verify code style manually run the following command, which uses
[google-java-format](https://github.com/google/google-java-format) library:

`./gradlew verifyGoogleJavaFormat`

or on Windows

`gradlew.bat verifyGoogleJavaFormat`

Instead of fixing style inconsistencies by hand, you can run gradle task `googleJavaFormat`
to automatically fix all found issues:
Instead of fixing style inconsistencies by hand, you can run gradle task
`googleJavaFormat` to automatically fix all found issues:

`./gradlew googleJavaFormat`

Expand All @@ -111,16 +176,19 @@ or on Windows
`gradlew.bat googleJavaFormat`

#### Pre-commit hook
To completely delegate code style formatting to the machine,
you can add [git pre-commit hook](https://git-scm.com/docs/githooks).
We provide an example script in `buildscripts/pre-commit` file.
Just copy or symlink it into `.git/hooks` folder.

To completely delegate code style formatting to the machine, you can add [git
pre-commit hook](https://git-scm.com/docs/githooks). We provide an example
script in `buildscripts/pre-commit` file. Just copy or symlink it into
`.git/hooks` folder.


#### Editorconfig

#### Editorconfig
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.
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.

### Intellij IDEA

Expand All @@ -136,4 +204,4 @@ Suggested plugins and settings:
![import layout](https://user-images.githubusercontent.com/734411/43430811-28442636-94ae-11e8-86f1-f270ddcba023.png)
* [Google Java Format](https://plugins.jetbrains.com/plugin/8527-google-java-format)
* [Save Actions](https://plugins.jetbrains.com/plugin/7642-save-actions)
![Recommended Settings](https://user-images.githubusercontent.com/734411/43430944-db84bf8a-94ae-11e8-8cec-0daa064937c4.png)
![Recommended Settings](https://user-images.githubusercontent.com/734411/43430944-db84bf8a-94ae-11e8-8cec-0daa064937c4.png)
Loading

0 comments on commit 72c9224

Please sign in to comment.