A Complete Guide to OpenTelemetry Java Agent: JVM Flags You Should Know

OpenTelemetry (OTel) has become the industry standard for collecting and exporting telemetry data (traces, metrics, and logs) from applications. One of the simplest ways to instrument your Java application is by using the OpenTelemetry Java Agent.

But what truly unlocks its potential is configuring it through the right JVM flags. In this article, I’ll walk through a comprehensive list of JVM options that help you control service metadata, exporters, instrumentation, sampling, and more.


Getting Started: Attach the Agent

At the heart of instrumentation is the agent itself:

-javaagent:/path/to/opentelemetry-javaagent.jar

This flag attaches the OpenTelemetry Java Agent to your running JVM process.


Define Your Service and Attributes

You can tag telemetry data with service-specific metadata:

-Dotel.service.name=my-service
-Dotel.resource.attributes=env=prod,region=us-west,team=observability

Use this to enrich traces, metrics, and logs with context.


Exporters: Where Your Telemetry Goes

OpenTelemetry supports multiple exporters. You can configure them like this:

General Exporter Configuration

-Dotel.traces.exporter=otlp
-Dotel.metrics.exporter=otlp
-Dotel.logs.exporter=otlp

-Dotel.exporter.otlp.endpoint=http://otel-collector:4317
-Dotel.exporter.otlp.traces.endpoint=http://otel-collector:4317/v1/traces
-Dotel.exporter.otlp.metrics.endpoint=http://otel-collector:4317/v1/metrics
-Dotel.exporter.otlp.logs.endpoint=http://otel-collector:4317/v1/logs
-Dotel.exporter.otlp.protocol=grpc
-Dotel.exporter.otlp.headers=x-tenant-id=mytenant,x-api-key=abc123
-Dotel.exporter.otlp.timeout=10s
-Dotel.exporter.otlp.certificate=/path/to/cert.pem

Jaeger Exporter (Optional)

-Dotel.traces.exporter=jaeger
-Dotel.exporter.jaeger.endpoint=http://localhost:14250
-Dotel.exporter.jaeger.timeout=10s

Zipkin Exporter (Optional)

-Dotel.traces.exporter=zipkin
-Dotel.exporter.zipkin.endpoint=http://localhost:9411/api/v2/spans
-Dotel.exporter.zipkin.timeout=10s

Context Propagation

Control how context (trace, baggage) is propagated across services:

-Dotel.propagators=b3,baggage,tracecontext

Sampling: Control the Volume of Data

Sampling policies define how many traces are collected:

-Dotel.traces.sampler=traceidratio
-Dotel.traces.sampler.arg=0.25

Other samplers include:

  • always_on

  • always_off

  • parentbased_always_on


Fine-Grained Instrumentation Control

Enable or disable specific instrumentations:

-Dotel.instrumentation.spring-web.enabled=true
-Dotel.instrumentation.jdbc.enabled=true
-Dotel.instrumentation.kafka.enabled=false
-Dotel.instrumentation.reactor.enabled=false
-Dotel.instrumentation.common.default-enabled=true

Experimental Features

These are cutting-edge flags, useful in specific use cases:

-Dotel.experimental.span.attributes=true
-Dotel.experimental.suppress-nested-client-span=true
-Dotel.instrumentation.runtime-metrics.enabled=true
-Dotel.instrumentation.micrometer.enabled=true
-Dotel.javaagent.experimental.thread-propagation.enabled=true

Debugging and Logging

To debug agent behavior or get verbose logging:

-Dotel.javaagent.debug=true
-Dio.opentelemetry.javaagent.slf4j.simpleLogger.defaultLogLevel=debug
-Dio.opentelemetry.context.enableStrictContext=true

Miscellaneous Options

Some additional flags that control agent lifecycle and SDK behavior:

-Dotel.javaagent.bootstrap.enabled=true
-Dotel.sdk.disabled=false

How to Use These in Practice

Here’s how all this comes together in a Java application startup:

java -javaagent:/opt/otel/opentelemetry-javaagent.jar \
  -Dotel.service.name=order-service \
  -Dotel.resource.attributes=env=prod,region=us-east \
  -Dotel.traces.exporter=otlp \
  -Dotel.exporter.otlp.endpoint=http://otel-collector:4317 \
  -Dotel.traces.sampler=traceidratio \
  -Dotel.traces.sampler.arg=0.2 \
  -Dotel.javaagent.debug=true \
  -jar app.jar

Configuring with Environment Variables

In certain environments, configuring settings through environment variables is often preferred. Any setting that can be configured using a system property can also be set using an environment variable. While many of the settings below provide examples for both formats, for those that do not, use the following steps to determine the correct name mapping for the desired system property:

  • Convert the system property name to uppercase.

  • Replace all . and - characters with _.

For example otel.instrumentation.common.default-enabled would convert to OTEL_INSTRUMENTATION_COMMON_DEFAULT_ENABLED


Conclusion

The OpenTelemetry Java Agent is a powerful plug-and-play tool that can be fine-tuned with the right JVM flags. Whether you're sending data to OTLP, Jaeger, or Zipkin, or disabling noisy instrumentation — these flags offer full control over what gets collected and how.

By customizing your startup flags, you ensure your telemetry pipeline is efficient, secure, and insightful — just as it should be.

0
Subscribe to my newsletter

Read articles from Venu Madhav Emmadi directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Venu Madhav Emmadi
Venu Madhav Emmadi