Skip to content

Commit

Permalink
Improve extension sample documentation and add it to the README file (#…
Browse files Browse the repository at this point in the history
…3656)

* First commit

* Update examples/extension/README.md

Co-authored-by: John Watson <jkwatson@gmail.com>

* Update README.md

Co-authored-by: Nikita Salnikov-Tarnovski <gnikem@gmail.com>

* Update docs/agent-config.md

Co-authored-by: Nikita Salnikov-Tarnovski <gnikem@gmail.com>

* Update examples/extension/README.md

Co-authored-by: Nikita Salnikov-Tarnovski <gnikem@gmail.com>

* Update examples/extension/README.md

Co-authored-by: Nikita Salnikov-Tarnovski <gnikem@gmail.com>

* Update examples/extension/README.md

Co-authored-by: Nikita Salnikov-Tarnovski <gnikem@gmail.com>

* Edits

* Readme update

Co-authored-by: John Watson <jkwatson@gmail.com>
Co-authored-by: Nikita Salnikov-Tarnovski <gnikem@gmail.com>
  • Loading branch information
3 people committed Jul 26, 2021
1 parent 3555c25 commit c24da7b
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 69 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
* [Getting Started](#getting-started)
* [Configuring the Agent](#configuring-the-agent)
* [Supported libraries, frameworks, and application servers](#supported-libraries-frameworks-and-application-servers)
* [Creating agent extensions](#creating-agent-extensions)
* [Manually instrumenting](#manually-instrumenting)
* [Logger MDC auto-instrumentation](#logger-mdc-mapped-diagnostic-context-auto-instrumentation)
* [Troubleshooting](#troubleshooting)
Expand Down Expand Up @@ -108,6 +109,10 @@ a majority of the most popular [application servers](docs/supported-libraries.md
[disabled instrumentation](docs/supported-libraries.md#disabled-instrumentations)
and how to [suppress unwanted instrumentation](docs/suppressing-instrumentation.md).

## Creating agent extensions

[Extensions](examples/extension/README.md) add new features and capabilities to the agent without having to create a separate distribution or to fork this repository. For example, you can create custom samplers or span exporters, set new defaults, and embed it all in the agent to obtain a single jar file.

## Manually instrumenting

For most users, the out-of-the-box instrumentation is completely sufficient and nothing more has to
Expand Down
7 changes: 7 additions & 0 deletions docs/agent-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ You can provide a path to agent configuration file by setting the corresponding
|--------------------------------------|--------------------------------------|----------------------------------------------------------------------------------|
| `otel.javaagent.configuration-file` | `OTEL_JAVAAGENT_CONFIGURATION_FILE` | Path to valid Java properties file which contains the javaagent configuration.|

### Extensions

You can enable [extensions](../examples/extension/README.md) by setting the corresponding property.

| System property | Environment variable | Description |
|--------------------------------------|--------------------------------------|----------------------------------------------------------------------------------|
| `otel.javaagent.experimental.extensions` | `OTEL_JAVAAGENT_EXPERIMENTAL_EXTENSIONS` | Path to a an extension jar file or folder, containing jar files. If pointing to a folder, every jar file in that folder will be treated as separate, independent extension|

## Peer service name

Expand Down
118 changes: 49 additions & 69 deletions examples/extension/README.md
Original file line number Diff line number Diff line change
@@ -1,84 +1,64 @@
## Introduction

This repository demonstrates how to create an extension archive to use with `otel.javaagent.experimental.extensions`
configuration option of the OpenTelemetry Java instrumentation agent.

For every extension point provided by OpenTelemetry Java instrumentation, this repository contains an example of
its usage.

Please carefully read both the source code and Gradle build script file `build.gradle`.
They contain a lot of documentation and comments explaining the purpose of all major pieces.

## How to use extension archive

When you build this project by running `./gradlew build` you will get a jar file in
`build/libs/opentelemetry-java-instrumentation-extension-demo-1.0-all.jar`.
Copy this jar file to a machine running the application that you are monitoring with
OpenTelemetry Java instrumentation agent.

Assuming that your command line looks similar to this:
```
java -javaagent:path/to/opentelemetry-javaagent-all.jar \
-jar myapp.jar
```
change it to this:
```
java -javaagent:path/to/opentelemetry-javaagent-all.jar \
-Dotel.javaagent.experimental.extensions=path/to/extension.jar
-jar myapp.jar
```
specifying the full path and the correct name of your extensions jar.

## Embedded extensions

It is also possible to embedded you extension archive right inside OpenTelemetry Java Agent.
This produces a single jar file thus simplifying deployment.
Please consult `extendedAgent` task in [build.gradle](build.gradle) file for more information.
When using Java Agent with embedded extension, the `-Dotel.javaagent.experimental.extensions`
command line option is not needed anymore.
Just `-javaagent` is sufficient.
Extensions add new features and capabilities to the agent without having to create a separate distribution (for examples and ideas, see [Use cases for extensions](#use-cases-for-extensions)).

The contents in this folder demonstrate how to create an extension for the OpenTelemetry Java instrumentation agent, with examples for every extension point.

> Read both the source code and the Gradle build script, as they contain documentation that explains the purpose of all the major components.
## Build and add extensions

To build this extension project, run `./gradlew build`. You can find the resulting jar file in `build/libs/`.

To add the extension to the instrumentation agent:

1. Copy the jar file to a host that is running an application to which you've attached the OpenTelemetry Java instrumentation.
2. Modify the startup command to add the full path to the extension file. For example:

```bash
java -javaagent:path/to/opentelemetry-javaagent-all.jar \
-Dotel.javaagent.experimental.extensions=build/libs/opentelemetry-java-instrumentation-extension-demo-1.0-all.jar
-jar myapp.jar
```
## Embed extensions in the OpenTelemetry Agent

To simplify deployment, you can embed extensions into the OpenTelemetry Java Agent to produce a single jar file. With an integrated extension, you no longer need the `-Dotel.javaagent.experimental.extensions` command line option.

For more information, see the `extendedAgent` task in [build.gradle](build.gradle).
## Extensions examples

* [DemoIdGenerator](src/main/java/com/example/javaagent/DemoIdGenerator.java) - custom `IdGenerator`
* [DemoPropagator](src/main/java/com/example/javaagent/DemoPropagator.java) - custom `TextMapPropagator`
* [DemoPropertySource](src/main/java/com/example/javaagent/DemoPropertySource.java) - default configuration
* [DemoSampler](src/main/java/com/example/javaagent/DemoSampler.java) - custom `Sampler`
* [DemoSpanProcessor](src/main/java/com/example/javaagent/DemoSpanProcessor.java) - custom `SpanProcessor`
* [DemoSpanExporter](src/main/java/com/example/javaagent/DemoSpanExporter.java) - custom `SpanExporter`
* [DemoServlet3InstrumentationModule](src/main/java/com/example/javaagent/instrumentation/DemoServlet3InstrumentationModule.java) - additional instrumentation
* Custom `IdGenerator`: [DemoIdGenerator](src/main/java/com/example/javaagent/DemoIdGenerator.java)
* Custom `TextMapPropagator`: [DemoPropagator](src/main/java/com/example/javaagent/DemoPropagator.java)
* New default configuration: [DemoPropertySource](src/main/java/com/example/javaagent/DemoPropertySource.java)
* Custom `Sampler`: [DemoSampler](src/main/java/com/example/javaagent/DemoSampler.java)
* Custom `SpanProcessor`: [DemoSpanProcessor](src/main/java/com/example/javaagent/DemoSpanProcessor.java)
* Custom `SpanExporter`: [DemoSpanExporter](src/main/java/com/example/javaagent/DemoSpanExporter.java)
* Additional instrumentation: [DemoServlet3InstrumentationModule](src/main/java/com/example/javaagent/instrumentation/DemoServlet3InstrumentationModule.java)

## Sample use cases

Extensions are designed to override or customize the instrumentation provided by the upstream agent without having to create a new OpenTelemetry distribution or alter the agent code in any way.

Consider an instrumented database client that creates a span per database call and extracts data from the database connection to provide span attributes. The following are sample use cases for that scenario that can be solved by using extensions.

### "I don't want this span at all"

## Instrumentation customisation
Create an extension to disable selected instrumentation by providing new default settings.

There are several options to override or customise instrumentation provided by the upstream agent.
The following description follows one specific use-case:
### "I want to edit some attributes that don't depend on any db connection instance"

> Instrumentation X from OpenTelemetry distribution creates span that I don't like and I want to change it.
Create an extension that provide a custom `SpanProcessor`.

As an example, let us take some database client instrumentation that creates a span for database call
and extracts data from db connection to provide attributes for that span.
### "I want to edit some attributes and their values depend on a specific db connection instance"

### I don't want this span at all
The easiest case. You can just pre-configure the agent in your extension and disable given instrumentation.
Create an extension with new instrumentation which injects its own advice into the same method as the original one. You can use the `order` method to ensure it runs after the original instrumentation and augment the current span with new information.

### I want to add/modify some attributes and their values does NOT depend on a specific db connection instance.
E.g. you want to add some data from call stack as span attribute.
In this case just provide your custom `SpanProcessor`.
No need for touching instrumentation itself.
For example, see [DemoServlet3InstrumentationModule](src/main/java/com/example/javaagent/instrumentation/DemoServlet3InstrumentationModule.java).

### I want to add/modify some attributes and their values depend on a specific db connection instance.
Write a _new_ instrumentation which injects its own advice into the same method as the original one.
Use `order` method to ensure it is run after the original instrumentation.
Now you can augment current span with new information.
### "I want to remove some attributes"

See [DemoServlet3InstrumentationModule](src/main/java/com/example/javaagent/instrumentation/DemoServlet3InstrumentationModule.java).
Create an extension with a custom exporter or use the attribute filtering functionality in the OpenTelemetry Collector.

### I want to remove some attributes
Write custom exporter or use attribute filtering functionality in Collector.
### "I don't like the OTel spans. I want to modify them and their lifecycle"

### I don't like Otel span at all. I want to significantly modify it and its lifecycle
Disable existing instrumentation.
Write a new one, which injects `Advice` into the same (or better) method as the original instrumentation.
Write your own `Advice` for this.
Use existing `Tracer` directly or extend it.
As you have your own `Advice`, you can control which `Tracer` you use.
Create an extension that disables existing instrumentation and replace it with new one that injects `Advice` into the same (or a better) method as the original instrumentation. You can write your `Advice` for this and use the existing `Tracer` directly or extend it. As you have your own `Advice`, you can control which `Tracer` you use.

0 comments on commit c24da7b

Please sign in to comment.