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
OTLP Exporter Settings (Recommended Default)
-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.
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
