This reference application demonstrates comprehensive OpenTelemetry usage in Java, following the OpenTelemetry Getting Started Reference Application Specification.
This application showcases:
- Traces: Manual and automatic span creation, distributed tracing
- Metrics: Custom metrics, performance monitoring
- Logs: Structured logging with trace correlation
- Multiple exporters: Console, OTLP, file-based exports
- Configuration: Environment variables, programmatic setup, and declarative configuration
- Docker support: Complete setup with OpenTelemetry Collector
The reference application is a dice rolling service that demonstrates OpenTelemetry capabilities using the OpenTelemetry Java Agent for automatic instrumentation and manual instrumentation examples:
GET /rolldice- Basic dice roll (returns random 1-6)GET /rolldice?player=<name>- Dice roll for a specific playerGET /rolldice?rolls=<n>- Roll multiple diceGET /fibonacci?n=<number>- Calculate fibonacci (demonstrates computation tracing)GET /health- Health check endpointGET /metrics- Prometheus metrics endpoint (when enabled)
- Basic HTTP instrumentation: Automatic span creation for HTTP requests
- Manual instrumentation: Custom spans for business logic
- Error handling: Error span recording and exception tracking
- Custom metrics: Performance counters, histograms, gauges
- Baggage propagation: Cross-cutting concerns
- Resource detection: Automatic resource attribute detection
- Java 17 or later
- Docker and Docker Compose (for collector setup)
# Build the application with the Java agent
../gradlew bootJar
# Run with the Java agent for automatic instrumentation
java -javaagent:build/agent/opentelemetry-javaagent.jar -jar build/libs/app.jarThen test the endpoints:
curl http://localhost:8080/rolldice
curl http://localhost:8080/rolldice?player=alice
curl http://localhost:8080/fibonacci?n=10# Build the application
../gradlew bootJar
# Start the collector and application
docker-compose up --buildThis will:
- Start the reference application on port 8080
- Start OpenTelemetry Collector on port 4317/4318
- Export telemetry data to the collector
- Output structured telemetry data to console
The application supports multiple configuration approaches:
export OTEL_SERVICE_NAME=dice-server
export OTEL_SERVICE_VERSION=1.0.0
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
export OTEL_TRACES_EXPORTER=otlp
export OTEL_METRICS_EXPORTER=otlp
export OTEL_LOGS_EXPORTER=otlpThe application uses the OpenTelemetry Java Agent which automatically configures instrumentation based on environment variables and system properties. All standard OpenTelemetry configuration options are supported.
Use the included otel-config.yaml for file-based configuration:
export OTEL_EXPERIMENTAL_CONFIG_FILE=otel-config.yamlThe application creates spans for:
- HTTP requests (automatic)
- Business logic operations (manual)
- External calls and computations
- Error scenarios
The application reports:
- Request duration histograms
- Request counters by endpoint
- Error rates
- Custom business metrics (dice roll distributions)
All logs include:
- Trace ID and Span ID for correlation
- Structured fields
- Different log levels
- Business context
../gradlew build../gradlew testRun the comprehensive end-to-end test that verifies the complete OpenTelemetry stack:
# Run via Gradle
../gradlew e2eTest
# Or run directly
./test-e2e.shThis test:
- Builds and starts all services using
docker-compose up --build - Waits for services to be ready (application, collector, Prometheus)
- Tests all application endpoints
- Verifies OpenTelemetry data collection and export
- Validates Prometheus metric scraping
- Cleans up resources automatically
For detailed information about the end-to-end test, see E2E-TEST.md.
../gradlew bootRunThe application can be built as a Docker image:
../gradlew bootBuildImage- No telemetry data: Check OTEL_* environment variables
- Connection issues: Verify collector endpoint configuration
- Missing traces: Ensure sampling is configured correctly
Enable debug logging:
export OTEL_JAVAAGENT_DEBUG=trueOr set logging level:
export LOGGING_LEVEL_IO_OPENTELEMETRY=DEBUG