/opentelemetry-java-sampleapp

Example of application tracing based on Opentelemetry

Primary LanguageJava

Opentelemetry Tracing example in Java

Instructions

A detailed step-by-step tutorial showing how tracing can be implemented for a simple java application issuing http calls to a http server. Both layers use the opentelemetry sdk and in this particular use case we will show how context propagation is handled.

Preliminary tasks and first time steps

Project structure
Let's first create our project structure

pejman@macosx:~ $ mkdir -p otel/opentelemetrylab otel/opentelemetry-collector-contrib
pejman@macosx:~ $ cd otel
pejman@macosx:~ otel $ ls -lrt
drwxr-xr-x   8 pejman  staff     256 Apr 23 18:48 opentelemetrylab
drwxr-xr-x   5 pejman  staff     160 Apr 23 18:48 opentelemetry-collector-contrib

Clone this repository

pejman@macosx:~ otel $ cd opentelemetrylab
pejman@macosx:~ opentelemetrylab $ git clone https://github.com/ptabasso2/opentelemetry-java-sampleapp.git

Initial directory structure

pejman@macosx:~ opentelemetrylab $ tree
.
├── README.md
├── build.gradle
├── gradle
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew
├── img
│   ├── OtelArch.png
│   ├── OtelDDexample1.png
│   └── OtelJaegerexample1.png
├── pom.xml
├── settings.gradle
├── src
    ├── main
    │   ├── java
    │   │   └── io
    │   │       └── opentelemetry
    │   │           └── otlp
    │   │               ├── ExampleConfiguration.java
    │   │               ├── HttpClient.java
    │   │               └── HttpServer.java
    │   └── resources
    └── test
        ├── java
        └── resources

Download and install the collector binaries

pejman@macosx:~ opentelemetrylab $ cd ../opentelemetry-collector-contrib
pejman@macosx:~ opentelemetry-collector-contrib $ curl --output otelcontribcol_darwin_amd64 -O -L https://github.com/open-telemetry/opentelemetry-collector-contrib/releases/download/v0.27.0/otelcontribcol_darwin_amd64
pejman@macosx:~ opentelemetry-collector-contrib $ chmod +x opentelemetry-collector-contrib

For a linux environment you will want to download the following binary (instead of the one above): https://github.com/open-telemetry/opentelemetry-collector-contrib/releases/download/v0.27.0/otelcontribcol_linux_amd64

Configure the collector

pejman@macosx:~ opentelemetry-collector-contrib $ mkdir bin && cd bin
pejman@macosx:~ bin $ vi conf.yaml

Below an example of conf.yaml file.
Please make sure you are using your API key. The one below is redacted.
Copy paste the following lines to the conf.yaml file, save and exit.

receivers:
  otlp:
    protocols:
      grpc:
      http:

exporters:
  prometheus:
    endpoint: "0.0.0.0:8889"
    namespace: promexample
    const_labels:
      label1: value1
  
  logging:

  jaeger:
    endpoint: localhost:14250
    insecure: true
    
  datadog/api:
    hostname: customhostname
    env: prod
    service: myservice
    version: myversion
    tags:
      - example:tag
    api:
      key: 9847ecd1xxxxxxxx2064xxxxxxxdd3c2
      site: datadoghq.com

processors:
  batch:
    timeout: 10s

extensions:
  health_check:
  pprof:
    endpoint: :1888
  zpages:
    endpoint: :55679

service:
  extensions: [pprof, zpages, health_check]
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [datadog/api, jaeger]
    metrics:
      receivers: [otlp]
      processors: [batch]
      exporters: [logging,prometheus]

Spin up the opentelemetry collector

pejman@macosx:~ bin $ nohup ./otelcontribcol_darwin_amd64 --config=./conf.yaml &

Spin up the Jaeger Backend

pejman@macosx:~ bin $ docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
-p 5775:5775/udp \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 14268:14268 \
-p 14250:14250 \
-p 9411:9411 \
jaegertracing/all-in-one:1.22

Build the application

1. Using gradle

Gradle will by default create and produce the build folder and the artifact (jar) will be placed into the lib folder.
To execute the build, run the following command. Or in your IDE you can edit your build configurations and create one that relies on this command.

pejman@macosx:~ bin $ cd ../../opentelemetrylab
pejman@macosx:~ opentelemetrylab $
pejman@macosx:~ opentelemetrylab $ ./gradlew shadowJar

This build the final artifact otel-0.1.0.jar placed under $HOME/otel/opentelemetrylab/build/libs

Also the default main class specified in this jar refers to HttpClient, therefore the client can be run on the command line using this syntax:

pejman@macosx:~ opentelemetrylab $ java -jar build/libs/otel-0.1.0.jar

Instead of

pejman@macosx:~ opentelemetrylab $ java -cp build/libs/otel-0.1.0.jar io.opentelemetry.otlp.HttpClient
2. Using Maven

Maven will by default create and produce the target folder and the classes and the artifact (jar) will be placed at the root of this folder. To execute the build, run the following command. Or in your IDE you can edit your build configurations and create one that relies on this command.

pejman@macosx:~ opentelemetrylab $
pejman@macosx:~ opentelemetrylab $ mvn clean compile assembly:single

or

pejman@macosx:~ opentelemetrylab $
pejman@macosx:~ opentelemetrylab $ mvn clean assembly:assembly

Running and testing the app

1. Starting the Http server first.
pejman@macosx:~ opentelemetrylab $ java -cp build/libs/otel-0.1.0.jar io.opentelemetry.otlp.HttpServer &
[1] 602
pejman@macosx:~ opentelemetrylab $ Server ready on http://127.0.0.1:8080
2. Starting the Http client
pejman@macosx:~ opentelemetrylab $ java -cp build/libs/otel-0.1.0.jar io.opentelemetry.otlp.HttpClient
Served Client: /127.0.0.1:58434
Response Code: 200
Response Msg: Hello World!

Checking the results

You can then navigate to http://localhost:16686 to access the Jaeger UI.

1. Checking the results in Datadog:

2. Checking the results in Jaeger: