Instrument a Java App
The OpenTelemetry Java agent instruments a Java application at launch time, with no code change. It attaches to the JVM, traces the frameworks and libraries your application uses, and sends traces, metrics, and logs to KloudMate. You configure it with environment variables.
Instrument a Java application
Section titled “Instrument a Java application”1. Download the agent JAR. It contains the agent and every automatic instrumentation:
Earlier versions are on the releases page.
2. Set the variables that attach the agent and send its data to KloudMate:
Replace /path/to with the folder you downloaded the JAR to, and my-java-app with the name you want the service to have in KloudMate.
3. Start your application as usual, from the same shell:
You can also attach the agent on the command line instead of through JAVA_TOOL_OPTIONS: java -javaagent:/path/to/opentelemetry-javaagent.jar -jar my-app.jar.
4. Check that the agent loaded. The startup output shows lines from otel.javaagent, including the agent version. Send a few requests to your application, and the service appears in KloudMate within a minute.
Instrument an app on Apache Tomcat
Section titled “Instrument an app on Apache Tomcat”The Java agent works the same way for an application that runs inside Tomcat, with no code change. The difference is where you attach it: Tomcat starts the JVM, so you add the agent to Tomcat’s startup options instead of to a java -jar command. The agent then traces every request the server handles. OpenTelemetry tests it on Tomcat 7.0 to 10.1 and TomEE 7.0 to 9.1.
1. Download the agent to a path that Tomcat can read, for example /opt/opentelemetry:
2. Add the agent and the KloudMate settings to Tomcat’s startup options. Where they go depends on how Tomcat was installed:
Create or edit <tomcat>/bin/setenv.sh. Tomcat reads it on every start.
For a Tomcat installed from a package, add the agent to JAVA_OPTS in /etc/tomcat*/tomcat*.conf, with the settings as -D system properties on the same line.
Create or edit <tomcat>\bin\setenv.bat:
If Tomcat runs as a Windows service, open <tomcat>\bin\tomcat*w.exe, go to the Java tab, and add these lines to Java Options, one per line:
Replace my-tomcat-app with the name you want the service to have in KloudMate.
3. Restart Tomcat. On Linux, for a downloaded install:
For a package install, restart the service instead, for example sudo systemctl restart tomcat.
4. Check that the agent loaded. Tomcat’s log (<tomcat>/logs/catalina.out on Linux) shows lines from otel.javaagent, including the agent version, when the server starts. Send a few requests to your application, and the service appears in KloudMate within a minute.
Instrument a Java app in Docker
Section titled “Instrument a Java app in Docker”For a containerized application, add the agent to the image and set the service name and endpoint when the container starts, so the same image works in every environment.
Add the agent to your Dockerfile and attach it with JAVA_TOOL_OPTIONS, which every JVM reads at startup:
Start from the official Tomcat image, deploy your WAR, and attach the agent through CATALINA_OPTS:
Build the image, then set the service name and endpoint when you run it:
Inside a container, localhost is the container itself. --network host puts the container on the host’s network, so localhost:4318 reaches the KloudMate agent on the host, and the application’s ports open directly on the host without -p. On Docker Desktop for Mac or Windows, use http://host.docker.internal:4318 as the endpoint instead.
With Docker Compose, set network_mode: host on the service and the same two variables under its environment: key.
If the KloudMate agent is installed on the host or in your Kubernetes cluster, it can attach the Java agent to your services for you. See Java auto-instrumentation with the KloudMate agent.
Configure the agent
Section titled “Configure the agent”Every setting can be given in three ways. If the same setting is given more than once, the first one in this list wins:
-
A system property on the JVM command line, for example
-Dotel.service.name=my-service. -
An environment variable, for example
OTEL_SERVICE_NAME=my-service. To get a variable’s name from a property name, uppercase it and replace every.and-with_. -
A properties file, whose path you give in
-Dotel.javaagent.configuration-fileorOTEL_JAVAAGENT_CONFIGURATION_FILE. This keeps the settings out of the startup script:
The agent sends traces, metrics, and logs over OTLP with http/protobuf by default, so the endpoint above is all it needs to reach the KloudMate agent. For every other option, see the OpenTelemetry agent configuration reference, and check which frameworks and libraries are traced on the supported libraries page.
Java Metrics
Section titled “Java Metrics”| ### Name | ### Description |
|---|---|
| jvm_classes_loaded | The number of loaded classes |
| jvm_gc_collections_count | The total number of garbage collections that have occurred |
| jvm_gc_collections_elapsed | The approximate accumulated collection elapsed time |
| jvm_memory_heap_init | The initial amount of memory that the JVM requests from the operating system for the heap |
| jvm_memory_heap_max | The maximum amount of memory can be used for the heap |
| jvm_memory_heap_used | The current heap memory usage |
| jvm_memory_heap_committed | The amount of memory that is guaranteed to be available for the heap |
| jvm_memory_nonheap_init | The initial amount of memory that the JVM requests from the operating system for non-heap purposes |
| jvm_memory_nonheap_max | The maximum amount of memory can be used for non-heap purposes |
| jvm_memory_nonheap_used | The current non-heap memory usage |
| jvm_memory_nonheap_committed | The amount of memory that is guaranteed to be available for non-heap purposes |
| jvm_memory_pool_init | The initial amount of memory that the JVM requests from the operating system for the memory pool |
| jvm_memory_pool_max | The maximum amount of memory can be used for the memory pool |
| jvm_memory_pool_used | The current memory pool memory usage |
| jvm_memory_pool_committed | The amount of memory that is guaranteed to be available for the memory pool |
| jvm_threads_count | The current number of threads |