-
Couldn't load subscription status.
- Fork 153
Add Minimal OpenTelemetry Java Reference Application for Getting Started Guide #824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from 4 commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
0e30eef
Initial plan
Copilot c357ae1
Add comprehensive OpenTelemetry Java Reference Application
Copilot 0a199d7
Convert reference application to use OpenTelemetry Java agent instead…
Copilot 96e5af9
Remove manual logback appender configuration since Java Agent automat…
Copilot a046413
Add comprehensive end-to-end test using docker-compose up --build
Copilot a756f00
Add comprehensive telemetry testing using MockServer and OTLP validation
Copilot b055e7e
Fix build failures in reference application
Copilot a4a9fd5
Remove micrometer dependency and replace with OpenTelemetry metrics
Copilot 69d6220
Remove fibonacci endpoint per specification - keep implementation min…
Copilot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| FROM openjdk:17-jdk-slim | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| # Copy the JAR file and agent | ||
| COPY build/libs/app.jar /app.jar | ||
| COPY build/agent/opentelemetry-javaagent.jar /opentelemetry-javaagent.jar | ||
|
|
||
| # Expose the port | ||
| EXPOSE 8080 | ||
|
|
||
| # Run the application with the Java agent | ||
| ENTRYPOINT ["java", "-javaagent:/opentelemetry-javaagent.jar", "-jar", "/app.jar"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,183 @@ | ||
| # OpenTelemetry Java Reference Application | ||
|
|
||
| This reference application demonstrates comprehensive OpenTelemetry usage in Java, following the [OpenTelemetry Getting Started Reference Application Specification](https://opentelemetry.io/docs/getting-started/reference-application-specification/). | ||
|
|
||
| ## Features | ||
|
|
||
| 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 | ||
|
|
||
| ## Application Overview | ||
|
|
||
| The reference application is a dice rolling service that demonstrates OpenTelemetry capabilities using the **OpenTelemetry Java Agent** for automatic instrumentation and manual instrumentation examples: | ||
|
|
||
| ### Endpoints | ||
|
|
||
| - `GET /rolldice` - Basic dice roll (returns random 1-6) | ||
| - `GET /rolldice?player=<name>` - Dice roll for a specific player | ||
| - `GET /rolldice?rolls=<n>` - Roll multiple dice | ||
| - `GET /fibonacci?n=<number>` - Calculate fibonacci (demonstrates computation tracing) | ||
| - `GET /health` - Health check endpoint | ||
| - `GET /metrics` - Prometheus metrics endpoint (when enabled) | ||
|
|
||
| ### Scenarios Demonstrated | ||
|
|
||
| 1. **Basic HTTP instrumentation**: Automatic span creation for HTTP requests | ||
| 2. **Manual instrumentation**: Custom spans for business logic | ||
| 3. **Error handling**: Error span recording and exception tracking | ||
| 4. **Custom metrics**: Performance counters, histograms, gauges | ||
| 5. **Baggage propagation**: Cross-cutting concerns | ||
| 6. **Resource detection**: Automatic resource attribute detection | ||
|
|
||
| ## Quick Start | ||
|
|
||
| ### Prerequisites | ||
|
|
||
| - Java 17 or later | ||
| - Docker and Docker Compose (for collector setup) | ||
|
|
||
| ### Running with Console Output | ||
|
|
||
| ```shell | ||
| # 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.jar | ||
| ``` | ||
|
|
||
| Then test the endpoints: | ||
| ```shell | ||
| curl http://localhost:8080/rolldice | ||
| curl http://localhost:8080/rolldice?player=alice | ||
| curl http://localhost:8080/fibonacci?n=10 | ||
| ``` | ||
|
|
||
| ### Running with OpenTelemetry Collector | ||
|
|
||
| ```shell | ||
| # Build the application | ||
| ../gradlew bootJar | ||
|
|
||
| # Start the collector and application | ||
| docker-compose up --build | ||
| ``` | ||
|
|
||
| This 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 | ||
|
|
||
| ## Configuration | ||
|
|
||
| The application supports multiple configuration approaches: | ||
|
|
||
| ### Environment Variables | ||
|
|
||
| ```shell | ||
| 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=otlp | ||
| ``` | ||
|
|
||
| ### Java Agent Configuration | ||
|
|
||
| The application uses the OpenTelemetry Java Agent which automatically configures instrumentation based on environment variables and system properties. All standard OpenTelemetry configuration options are supported. | ||
|
|
||
| ### Declarative Configuration | ||
|
|
||
| Use the included `otel-config.yaml` for file-based configuration: | ||
|
|
||
| ```shell | ||
| export OTEL_EXPERIMENTAL_CONFIG_FILE=otel-config.yaml | ||
| ``` | ||
|
|
||
| ## Understanding the Output | ||
|
|
||
| ### Traces | ||
|
|
||
| The application creates spans for: | ||
| - HTTP requests (automatic) | ||
| - Business logic operations (manual) | ||
| - External calls and computations | ||
| - Error scenarios | ||
|
|
||
| ### Metrics | ||
|
|
||
| The application reports: | ||
| - Request duration histograms | ||
| - Request counters by endpoint | ||
| - Error rates | ||
| - Custom business metrics (dice roll distributions) | ||
|
|
||
| ### Logs | ||
|
|
||
| All logs include: | ||
| - Trace ID and Span ID for correlation | ||
| - Structured fields | ||
| - Different log levels | ||
| - Business context | ||
|
|
||
| ## Development | ||
|
|
||
| ### Building | ||
|
|
||
| ```shell | ||
| ../gradlew build | ||
| ``` | ||
|
|
||
| ### Testing | ||
|
|
||
| ```shell | ||
| ../gradlew test | ||
| ``` | ||
|
|
||
| ### Running locally | ||
|
|
||
| ```shell | ||
| ../gradlew bootRun | ||
| ``` | ||
|
|
||
| ## Docker Images | ||
|
|
||
| The application can be built as a Docker image: | ||
|
|
||
| ```shell | ||
| ../gradlew bootBuildImage | ||
| ``` | ||
|
|
||
| ## Troubleshooting | ||
|
|
||
| ### Common Issues | ||
|
|
||
| 1. **No telemetry data**: Check OTEL_* environment variables | ||
| 2. **Connection issues**: Verify collector endpoint configuration | ||
| 3. **Missing traces**: Ensure sampling is configured correctly | ||
|
|
||
| ### Debugging | ||
|
|
||
| Enable debug logging: | ||
| ```shell | ||
| export OTEL_JAVAAGENT_DEBUG=true | ||
| ``` | ||
|
|
||
| Or set logging level: | ||
| ```shell | ||
| export LOGGING_LEVEL_IO_OPENTELEMETRY=DEBUG | ||
| ``` | ||
|
|
||
| ## Learn More | ||
|
|
||
| - [OpenTelemetry Java Documentation](https://opentelemetry.io/docs/languages/java/) | ||
| - [OpenTelemetry Specification](https://opentelemetry.io/docs/specs/otel/) | ||
| - [Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| import org.springframework.boot.gradle.plugin.SpringBootPlugin | ||
| import org.springframework.boot.gradle.tasks.bundling.BootJar | ||
|
|
||
| plugins { | ||
| id("java") | ||
| id("org.springframework.boot") version "3.5.6" | ||
| } | ||
|
|
||
| val moduleName by extra { "io.opentelemetry.examples.reference-application" } | ||
|
|
||
| repositories { | ||
| mavenCentral() | ||
| } | ||
|
|
||
| val agent = configurations.create("agent") | ||
|
|
||
| dependencies { | ||
| implementation(platform(SpringBootPlugin.BOM_COORDINATES)) | ||
| implementation("io.opentelemetry:opentelemetry-api") | ||
|
|
||
| // Spring Boot | ||
| implementation("org.springframework.boot:spring-boot-starter-web") | ||
| implementation("org.springframework.boot:spring-boot-starter-actuator") | ||
|
|
||
| // Micrometer for additional metrics | ||
| implementation("io.micrometer:micrometer-registry-prometheus") | ||
|
|
||
| // Java agent | ||
| agent("io.opentelemetry.javaagent:opentelemetry-javaagent:2.20.1") | ||
|
|
||
| // Testing | ||
| testImplementation("org.springframework.boot:spring-boot-starter-test") | ||
| testImplementation("io.opentelemetry:opentelemetry-sdk-testing") | ||
| } | ||
|
|
||
| val copyAgent = tasks.register<Copy>("copyAgent") { | ||
| from(agent.singleFile) | ||
| into(layout.buildDirectory.dir("agent")) | ||
| rename("opentelemetry-javaagent-.*\\.jar", "opentelemetry-javaagent.jar") | ||
| } | ||
|
|
||
| tasks.named<BootJar>("bootJar") { | ||
| dependsOn(copyAgent) | ||
| archiveFileName = "app.jar" | ||
| } | ||
|
|
||
| tasks.withType<Test> { | ||
| useJUnitPlatform() | ||
| } | ||
|
|
||
| java { | ||
| toolchain { | ||
| languageVersion.set(JavaLanguageVersion.of(17)) | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| services: | ||
| dice-server: | ||
| build: . | ||
| ports: | ||
| - "8080:8080" | ||
| environment: | ||
| - OTEL_SERVICE_NAME=dice-server | ||
| - OTEL_SERVICE_VERSION=1.0.0 | ||
| - OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318 | ||
| - OTEL_TRACES_EXPORTER=otlp | ||
| - OTEL_METRICS_EXPORTER=otlp | ||
| - OTEL_LOGS_EXPORTER=otlp | ||
| - OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf | ||
| depends_on: | ||
| - otel-collector | ||
|
|
||
| otel-collector: | ||
| image: otel/opentelemetry-collector-contrib:latest | ||
| ports: | ||
| - "4317:4317" # OTLP gRPC | ||
| - "4318:4318" # OTLP HTTP | ||
| - "8889:8889" # Prometheus metrics | ||
| volumes: | ||
| - ./otel-collector-config.yaml:/etc/otelcol-contrib/otel-collector-config.yaml | ||
| command: ["--config=/etc/otelcol-contrib/otel-collector-config.yaml"] | ||
|
|
||
| prometheus: | ||
| image: prom/prometheus:latest | ||
| ports: | ||
| - "9090:9090" | ||
| volumes: | ||
| - ./prometheus.yml:/etc/prometheus/prometheus.yml | ||
| command: | ||
| - '--config.file=/etc/prometheus/prometheus.yml' | ||
| - '--storage.tsdb.path=/prometheus' | ||
| - '--web.console.libraries=/etc/prometheus/console_libraries' | ||
| - '--web.console.templates=/etc/prometheus/consoles' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| receivers: | ||
| otlp: | ||
| protocols: | ||
| grpc: | ||
| endpoint: 0.0.0.0:4317 | ||
| http: | ||
| endpoint: 0.0.0.0:4318 | ||
|
|
||
| processors: | ||
| batch: | ||
| memory_limiter: | ||
| limit_mib: 512 | ||
|
|
||
| exporters: | ||
| logging: | ||
| loglevel: info | ||
| sampling_initial: 5 | ||
| sampling_thereafter: 200 | ||
|
|
||
| prometheus: | ||
| endpoint: "0.0.0.0:8889" | ||
| metric_expiration: 180m | ||
| enable_open_metrics: true | ||
|
|
||
| extensions: | ||
| health_check: | ||
| endpoint: 0.0.0.0:13133 | ||
| pprof: | ||
| endpoint: 0.0.0.0:1777 | ||
| zpages: | ||
| endpoint: 0.0.0.0:55679 | ||
|
|
||
| service: | ||
| extensions: [health_check, pprof, zpages] | ||
| pipelines: | ||
| traces: | ||
| receivers: [otlp] | ||
| processors: [memory_limiter, batch] | ||
| exporters: [logging] | ||
| metrics: | ||
| receivers: [otlp] | ||
| processors: [memory_limiter, batch] | ||
| exporters: [logging, prometheus] | ||
| logs: | ||
| receivers: [otlp] | ||
| processors: [memory_limiter, batch] | ||
| exporters: [logging] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| file_format: 0.3 | ||
|
|
||
| # Service configuration | ||
| resource: | ||
| attributes: | ||
| service.name: dice-server | ||
| service.version: 1.0.0 | ||
| deployment.environment: local | ||
|
|
||
| # Tracer provider configuration | ||
| tracer_provider: | ||
| processors: | ||
| - batch: | ||
| exporter: | ||
| console: {} | ||
| sampler: | ||
| parent_based: | ||
| root: | ||
| always_on: {} | ||
|
|
||
| # Meter provider configuration | ||
| meter_provider: | ||
| readers: | ||
| - periodic: | ||
| exporter: | ||
| console: {} | ||
| interval: 30000 | ||
|
|
||
| # Logger provider configuration | ||
| logger_provider: | ||
| processors: | ||
| - batch: | ||
| exporter: | ||
| console: {} | ||
|
|
||
| # Propagators | ||
| propagators: | ||
| - tracecontext | ||
| - baggage |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@copilot also add a test of the telemetry that is exported from the difference scenarios using https://github.com/open-telemetry/opentelemetry-java-examples/tree/main/telemetry-testing as an example
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added comprehensive telemetry testing based on the telemetry-testing example. The implementation includes:
New telemetry test class (
TelemetryTest):Test scenarios covered:
roll-dice,fibonacci-calculation, etc.)dice_rolls_total,fibonacci_duration_seconds)Configuration:
ExportTraceServiceRequestandExportMetricsServiceRequestDocumentation:
TELEMETRY-TESTING.mdwith detailed implementation guideThe tests provide comprehensive validation that the reference application correctly generates and exports OpenTelemetry data for all scenarios.
Commit: a756f00