This project was built in order to easily spin up a handful of services that encapsulate a basic OpenTelemetry pipeline. There are two app services that are spun up, and they are already instrumented.
otel-java-basic
is instrumented with the OpenTelemetry Java Instrumentation JARappd-java-basic
is instrumented with AppDynamics Java Instrumentation JAR.
Both app services send OpenTelemetry Spans to the OpenTelemetry Dev Collector.
The OpenTelemetry Collector sends Spans to
- Jaeger All-In-One backend
- AppDynamics backend
The full stack of services consists of:
- Jaeger
- OpenTelemetry Collector (no agent)
- Spring PetClinic with OpenTelemetry Java Instrumentation JAR
- Spring PetClinic with AppDynamics Java Instrumentation JAR
More information about the Compose Services can be found below.
Note: This project was built/tested only on Docker for Mac, and uses Docker-Compose
It's not necessary to build anything in this project. All images can be pulled from Docker Hub when you run with Docker Compose.
In order to run this project, you'll need:
-
Docker for Mac
-
Docker Compose
Note: The Docker versions must support Docker Compose File version 3.2+
- Clone this repository to your local machine.
-
Copy the
.env_public
file to a file named.env
in the root project directory, and configure it for your AppDynamics backend. Detailed notes on specific requirements is down below.IMPORTANT: The
.env
file MUST be configured for this project to work with the AppDynamics backend!
- Edit the
OTEL_RESOURCE_ATTRIBUTES
environment variables in thedocker-comopose.yml
file for both app services below by appending your initials using the same value as in Step 2
otel-java-basic
appd-java-basic
Before
OTEL_RESOURCE_ATTRIBUTES: "service.name=otel-java-basic,service.namespace=otel-java-basic-<YOUR_INITIALS_HERE>"
After
OTEL_RESOURCE_ATTRIBUTES: "service.name=otel-java-basic,service.namespace=otel-java-basic-kjt"
IMPORTANT: The
service.namespace
value should now match theAPPDYNAMICS_AGENT_APPLICATION_NAME
in the.env
file
- Configure the
otel-collector-config.yaml
file in the root project directory by configuring theprocessors.resource.attributes
section toward your AppDynamics backend. More detailed notes on specific requirements is down below.
- Use Docker Compose to start
$ docker-compose up -d
- Open the OTel-Instrumented Spring PetClinic app on
http://$DOCKER_HOSTNAME:8080
($DOCKER_HOSTNAME
is generallylocalhost
), and click around for a bit.
- Open the AppD-Instrumented Spring PetClinic app on
http://$DOCKER_HOSTNAME:8081
($DOCKER_HOSTNAME
is generallylocalhost
), and click around for a bit.
- Then, open Jaeger on
http://$DOCKER_HOSTNAME:16686
, chooseotel-java-basic
orappd-java-basic
from the services drop-down menu, click the "Find Traces" button, and then choose a trace!
- Tear down the Compose Services
$ docker-compose down
Jaeger tracing backend.
Jaeger "all-in-one" Image, pulled from jaegertracing/all-in-one:latest
.
By default, accessible on http://$DOCKER_HOSTNAME:16686
.
OpenTelemetry Collector.
OpenTelemetry development Image, pulled from otel/opentelemetry-collector-dev:latest
.
There is no UI, merely a pipeline that is configured via appd-otel-collector-config.yaml
.
Spring PetClinic app.
Spring PetClinic Image, pulled from kjtully/otel-java-basic:latest
Image built from the otel-trainig
fork of the Spring PetClinic Repo.
By default, accessible on http://$DOCKER_HOSTNAME:8080
.
Spring PetClinic app.
Spring PetClinic Image, pulled from kjtully/appd-java-basic:latest
Image built from the otel-trainig
fork of the Spring PetClinic Repo.
By default, accessible on http://$DOCKER_HOSTNAME:8081
.
This file is located in the project root and manages building and running the Docker containers. It uses the .env
file to populate environment variables for the project to work properly.
This file contains all of the environment variables that need to be populated in order for the project to run, and for the performance tools to operate. Items that must be tailored to your environment are:
This configuration is used by the AppD Hybrid Java Agent to connect to the AppD Controller of your choice. Replace all values in <angle_brackets>
with the actual values per your AppDynamics backend.
IMPORTANT: The
<YOUR_INITIALS_HERE>
in the env varAPPDYNAMICS_AGENT_APPLICATION_NAME
is free-form, but ends up as part of the Application name in AppDynamics, so it should be meaningful. Also, make note of the value that you use for<YOUR_INITIALS_HERE>
- you'll use it again in the next step during the configuration of thedocker-compose.yml
file.
# AppD Agent
APPDYNAMICS_AGENT_ACCOUNT_ACCESS_KEY=<access_key>
APPDYNAMICS_AGENT_ACCOUNT_NAME=<appd_account>
APPDYNAMICS_CONTROLLER_HOST_NAME=<appd_controller_url>
APPDYNAMICS_CONTROLLER_PORT=<app_controller_port>
APPDYNAMICS_CONTROLLER_SSL_ENABLED=<false_or_true>
APPDYNAMICS_AGENT_APPLICATION_NAME=otel-java-basic-<YOUR_INITIALS_HERE>
# Tier and Node names are set in docker-compose.yml individually
API Key for the AppDynamics OpenTelemetry Ingestion Service. Replace the value <my_x_api_key>
with the OpenTelemetry API Key for the AppDynamics backend.
# AppD OTel Ingest API Key
X_API_KEY=<my_x_api_key>
The value:
sections of the below should be configured by replacing all values in <angle_brackets>
with the actual values per your AppDynamics backend - you'd reuse values that you've already configured in the .env
file.
.env file value |
otel-collector.yaml file value |
---|---|
APPDYNAMICS_AGENT_ACCOUNT_NAME |
appdynamics.controller.account |
APPDYNAMICS_CONTROLLER_HOST_NAME |
appdynamics.controller.host |
APPDYNAMICS_CONTROLLER_PORT |
appdynamics.controller.port |
processors:
resource:
attributes:
- key: appdynamics.controller.account
action: upsert
value: "<appd_account>"
# example: "customer1"
- key: appdynamics.controller.host
action: upsert
value: "<appd_controller_url>"
# example: "my-appd-controller.saas.appdynamics.com"
- key: appdynamics.controller.port
action: upsert
value: <appd_controller_port>
# example: 443
batch:
The endpoint
section of the below should be configured by replacing <your_appd_otel_endpoint>
with the proper AppDynamics API endpoint defined in the docs - example for US endpoint below.
Note, the x-api-key
header is already defined in the .env
file, so there is no need to define it here.
exporters:
...
otlphttp:
endpoint: <your_appd_otel_endpoint>
# example: https://pdx-sls-agent-api.saas.appdynamics.com
headers: {"x-api-key": "${X_API_KEY}"}
The pipelines
section within the services
section does not need to be changed, although it should be understood that both the above processors
and exporters
have been defined in order to complete the pipeline.
pipelines:
traces:
receivers: [otlp]
processors: [resource, batch]
exporters: [logging, jaeger, otlphttp]