Skip to content

Java

The OpenTelemetry Java agent is a jar you attach to the JVM. It instruments Spring, servlet containers, JDBC, HTTP clients, Kafka and many more libraries without code changes.

Use this page when you run a Java, Kotlin or Scala service on the JVM and want it in FuseScope.

Signal Status What the agent sends
Traces Stable Spans for incoming and outgoing requests, database calls, messaging.
Metrics Stable JVM (memory, GC, threads) and HTTP server/client metrics.
Logs Stable Logback, Log4j 2 and java.util.logging records, with trace IDs.
  • Java 8 or later.
  • A FuseScope collector you can reach on port 4317 or 4318. See OTLP.
  1. Download the agent:

    Terminal window
    curl -L -o opentelemetry-javaagent.jar \
    https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar

    In production, pin a version from the releases page instead of latest.

  2. Configure it:

    Terminal window
    export OTEL_SERVICE_NAME=checkout
    export OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production,service.version=1.4.2
    export OTEL_EXPORTER_OTLP_ENDPOINT=http://fusescope-collector.example.com:4318
    export OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
  3. Start the JVM with the agent:

    Terminal window
    java -javaagent:./opentelemetry-javaagent.jar -jar app.jar

    If you can’t change the command line, set JAVA_TOOL_OPTIONS=-javaagent:/path/to/opentelemetry-javaagent.jar instead.

Traces, metrics and logs are all exported over OTLP by default.

Every variable also works as a system property: OTEL_SERVICE_NAME becomes -Dotel.service.name=checkout. See the agent configuration.

Terminal window
OTEL_EXPORTER_OTLP_ENDPOINT=http://fusescope-collector.example.com:4317
OTEL_EXPORTER_OTLP_PROTOCOL=grpc

Add the agent to the image and turn it on with JAVA_TOOL_OPTIONS:

Dockerfile
FROM eclipse-temurin:21-jre
WORKDIR /app
COPY target/app.jar app.jar
ADD https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar /otel/opentelemetry-javaagent.jar
ENV JAVA_TOOL_OPTIONS="-javaagent:/otel/opentelemetry-javaagent.jar"
CMD ["java", "-jar", "app.jar"]
Terminal window
docker run \
-e OTEL_SERVICE_NAME=checkout \
-e OTEL_RESOURCE_ATTRIBUTES=deployment.environment.name=production \
-e OTEL_EXPORTER_OTLP_ENDPOINT=http://fusescope-collector.example.com:4318 \
-e OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf \
checkout:latest

Set the variables in the pod spec. The downward API adds the pod name and namespace:

deployment.yaml
env:
- name: JAVA_TOOL_OPTIONS
value: -javaagent:/otel/opentelemetry-javaagent.jar
- name: OTEL_SERVICE_NAME
value: checkout
- name: OTEL_EXPORTER_OTLP_ENDPOINT
value: http://fusescope-otel-collector.fusescope.svc.cluster.local:4318
- name: OTEL_EXPORTER_OTLP_PROTOCOL
value: http/protobuf
- name: K8S_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: K8S_NAMESPACE_NAME
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: OTEL_RESOURCE_ATTRIBUTES
value: deployment.environment.name=production,k8s.pod.name=$(K8S_POD_NAME),k8s.namespace.name=$(K8S_NAMESPACE_NAME)

$(VAR) only expands variables defined earlier in the list, so keep OTEL_RESOURCE_ATTRIBUTES last.

The agent captures records from Logback (1.0+), Log4j 2 (2.11+), Log4j 1 and java.util.logging, and exports them over OTLP with trace_id and span_id attached. You change nothing in your logging config.

It also puts trace_id and span_id in the Logback MDC and Log4j context, so you can print them in your log pattern, for example %X{trace_id}.

  1. Send a few requests to the service.
  2. Open Services. The service appears under its OTEL_SERVICE_NAME within a minute.
  3. Open the Traces explorer and filter by service.name.

Nothing arrives? Start the JVM with OTEL_JAVAAGENT_DEBUG=true to print what the agent does, and check the endpoint and protocol match (4318 with http/protobuf, 4317 with grpc).