Instrumentation
Sampling - Virex Docs
Instrument Java applications using OpenTelemetry and export metrics, traces, and logs via OTLP to the OpenTelemetry Collector.
Java Instrumentation with OpenTelemetry (OTLP Collector)
This guide explains how to instrument Java applications using OpenTelemetry and export metrics, traces, and logs to an OpenTelemetry Collector via OTLP.
The approach is:
- Zero or minimal code changes
- Vendor-neutral
- Production-ready
Architecture Overview
Java Application
└─ OpenTelemetry Java Agent
└─ OTLP (gRPC / HTTP)
└─ OpenTelemetry Collector
├─ Prometheus (metrics)
├─ Tempo / Jaeger (traces)
├─ Loki / Elastic (logs)
└─ Grafana (visualization)
Supported Java Runtimes
- Java 8+
- Spring Boot
- Jakarta EE
- Tomcat / Jetty
- Micronaut
- Quarkus
Instrumentation Options
Option 1: Java Auto-Instrumentation (Recommended)
The OpenTelemetry Java Agent automatically instruments:
OTLP (gRPC / HTTP)
└─ OpenTelemetry Collector
├─ HTTP servers & clients
├─ LDBC
├─ JVM Metrics
├─ Thread Pools
├─ Frameworks (Spring, Servlet, etc)
No code changes required.
Step 1: Download OpenTelemetry Java Agent
curl -LO https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
Step 2: Configure Environment Variables
Required Variables
export OTEL_SERVICE_NAME=orders-service
export OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
Recommended Production Settings
export OTEL_RESOURCE_ATTRIBUTES=service.namespace=payments,service.version=1.2.0
export OTEL_METRICS_EXPORTER=otlp
export OTEL_TRACES_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlp
Sampling (Reduce Cost)
export OTEL_TRACES_SAMPLER=parentbased_traceidratio
export OTEL_TRACES_SAMPLER_ARG=0.1
Step 3: Start the Java Application
java \
-javaagent:/opt/otel/opentelemetry-javaagent.jar \
-jar app.jar
Step 4: OpenTelemetry Collector Configuration
Minimal Collector (otel-collector.yaml)
receivers:
otlp:
protocols:
grpc:
http:
processors:
batch:
memory_limiter:
check_interval: 5s
limit_mib: 400
exporters:
prometheus:
endpoint: "0.0.0.0:8889"
otlp/tempo:
endpoint: tempo:4317
tls:
insecure: true
loki:
endpoint: http://loki:3100/loki/api/v1/push
service:
pipelines:
metrics:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [prometheus]
traces:
receivers: [otlp]
processors: [memory_limiter, batch]
exporters: [otlp/tempo]
logs:
receivers: [otlp]
processors: [batch]
exporters: [loki]
Step 5: Verify Telemetry
Metrics
JVM memory
GC pauses
HTTP request rate & latency
Traces
End-to-end request traces
Database spans
External calls
Logs
Structured logs with trace/span IDs
Correlated logs in Grafana
Secure OTLP (mTLS)
Java Agent (TLS)
export OTEL_EXPORTER_OTLP_CERTIFICATE=/certs/ca.pem
export OTEL_EXPORTER_OTLP_CLIENT_KEY=/certs/client.key
export OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE=/certs/client.crt
Collector (TLS Receiver)
receivers:
otlp:
protocols:
grpc:
tls:
cert_file: /certs/server.crt
key_file: /certs/server.key
Common Troubleshooting
No Data in Grafana
- Check Collector logs
- Validate OTLP endpoint & protocol
- Ensure ports 4317 / 4318 are reachable
High Memory Usage
- Reduce sampling rate
- Enable memory_limiter
- Tune batch processor
Best Practices
- Use service.name consistently
- Define service.namespace for teams
- Start with 10% sampling
- Use SLO-based alerting, not raw metrics
- Keep collectors stateless