Skip to content

Commit c357ae1

Browse files
Copilottrask
andcommitted
Add comprehensive OpenTelemetry Java Reference Application
Co-authored-by: trask <[email protected]>
1 parent 0e30eef commit c357ae1

File tree

16 files changed

+999
-0
lines changed

16 files changed

+999
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ of them assume you have docker running on your local machine.
66

77
## Example modules:
88

9+
- [OpenTelemetry Reference Application](reference-application)
10+
- A comprehensive reference application demonstrating OpenTelemetry usage following the
11+
[Getting Started Reference Application Specification](https://opentelemetry.io/docs/getting-started/reference-application-specification/).
12+
- Includes traces, metrics, logs, manual instrumentation, Docker setup with collector, and multiple configuration approaches.
913
- [Using the SDK AutoConfiguration module](autoconfigure)
1014
- This module contains a fully-functional example of using the autoconfigure
1115
SDK extension module to configure the SDK using only environment

reference-application/Dockerfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FROM openjdk:17-jdk-slim
2+
3+
WORKDIR /app
4+
5+
# Copy the JAR file
6+
COPY build/libs/*.jar app.jar
7+
8+
# Expose the port
9+
EXPOSE 8080
10+
11+
# Run the application
12+
ENTRYPOINT ["java", "-jar", "app.jar"]

reference-application/README.md

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
# OpenTelemetry Java Reference Application
2+
3+
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/).
4+
5+
## Features
6+
7+
This application showcases:
8+
9+
- **Traces**: Manual and automatic span creation, distributed tracing
10+
- **Metrics**: Custom metrics, performance monitoring
11+
- **Logs**: Structured logging with trace correlation
12+
- **Multiple exporters**: Console, OTLP, file-based exports
13+
- **Configuration**: Environment variables, programmatic setup, and declarative configuration
14+
- **Docker support**: Complete setup with OpenTelemetry Collector
15+
16+
## Application Overview
17+
18+
The reference application is a dice rolling service that simulates various scenarios to demonstrate OpenTelemetry capabilities:
19+
20+
### Endpoints
21+
22+
- `GET /rolldice` - Basic dice roll (returns random 1-6)
23+
- `GET /rolldice?player=<name>` - Dice roll for a specific player
24+
- `GET /rolldice?rolls=<n>` - Roll multiple dice
25+
- `GET /fibonacci?n=<number>` - Calculate fibonacci (demonstrates computation tracing)
26+
- `GET /health` - Health check endpoint
27+
- `GET /metrics` - Prometheus metrics endpoint (when enabled)
28+
29+
### Scenarios Demonstrated
30+
31+
1. **Basic HTTP instrumentation**: Automatic span creation for HTTP requests
32+
2. **Manual instrumentation**: Custom spans for business logic
33+
3. **Error handling**: Error span recording and exception tracking
34+
4. **Custom metrics**: Performance counters, histograms, gauges
35+
5. **Baggage propagation**: Cross-cutting concerns
36+
6. **Resource detection**: Automatic resource attribute detection
37+
38+
## Quick Start
39+
40+
### Prerequisites
41+
42+
- Java 17 or later
43+
- Docker and Docker Compose (for collector setup)
44+
45+
### Running with Console Output
46+
47+
```shell
48+
# Build and run with console logging
49+
../gradlew bootRun
50+
```
51+
52+
Then test the endpoints:
53+
```shell
54+
curl http://localhost:8080/rolldice
55+
curl http://localhost:8080/rolldice?player=alice
56+
curl http://localhost:8080/fibonacci?n=10
57+
```
58+
59+
### Running with OpenTelemetry Collector
60+
61+
```shell
62+
# Start the collector and application
63+
docker-compose up --build
64+
```
65+
66+
This will:
67+
- Start the reference application on port 8080
68+
- Start OpenTelemetry Collector on port 4317/4318
69+
- Export telemetry data to the collector
70+
- Output structured telemetry data to console
71+
72+
## Configuration
73+
74+
The application supports multiple configuration approaches:
75+
76+
### Environment Variables
77+
78+
```shell
79+
export OTEL_SERVICE_NAME=dice-server
80+
export OTEL_SERVICE_VERSION=1.0.0
81+
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
82+
export OTEL_TRACES_EXPORTER=otlp
83+
export OTEL_METRICS_EXPORTER=otlp
84+
export OTEL_LOGS_EXPORTER=otlp
85+
```
86+
87+
### Programmatic Configuration
88+
89+
See `src/main/java/io/opentelemetry/example/config/` for examples of:
90+
- Manual SDK initialization
91+
- Custom span processors and exporters
92+
- Resource configuration
93+
- Sampling configuration
94+
95+
### Declarative Configuration
96+
97+
Use the included `otel-config.yaml` for file-based configuration:
98+
99+
```shell
100+
export OTEL_EXPERIMENTAL_CONFIG_FILE=otel-config.yaml
101+
```
102+
103+
## Understanding the Output
104+
105+
### Traces
106+
107+
The application creates spans for:
108+
- HTTP requests (automatic)
109+
- Business logic operations (manual)
110+
- External calls and computations
111+
- Error scenarios
112+
113+
### Metrics
114+
115+
The application reports:
116+
- Request duration histograms
117+
- Request counters by endpoint
118+
- Error rates
119+
- Custom business metrics (dice roll distributions)
120+
121+
### Logs
122+
123+
All logs include:
124+
- Trace ID and Span ID for correlation
125+
- Structured fields
126+
- Different log levels
127+
- Business context
128+
129+
## Development
130+
131+
### Building
132+
133+
```shell
134+
../gradlew build
135+
```
136+
137+
### Testing
138+
139+
```shell
140+
../gradlew test
141+
```
142+
143+
### Running locally
144+
145+
```shell
146+
../gradlew bootRun
147+
```
148+
149+
## Docker Images
150+
151+
The application can be built as a Docker image:
152+
153+
```shell
154+
../gradlew bootBuildImage
155+
```
156+
157+
## Troubleshooting
158+
159+
### Common Issues
160+
161+
1. **No telemetry data**: Check OTEL_* environment variables
162+
2. **Connection issues**: Verify collector endpoint configuration
163+
3. **Missing traces**: Ensure sampling is configured correctly
164+
165+
### Debugging
166+
167+
Enable debug logging:
168+
```shell
169+
export OTEL_JAVAAGENT_DEBUG=true
170+
```
171+
172+
Or set logging level:
173+
```shell
174+
export LOGGING_LEVEL_IO_OPENTELEMETRY=DEBUG
175+
```
176+
177+
## Learn More
178+
179+
- [OpenTelemetry Java Documentation](https://opentelemetry.io/docs/languages/java/)
180+
- [OpenTelemetry Specification](https://opentelemetry.io/docs/specs/otel/)
181+
- [Semantic Conventions](https://opentelemetry.io/docs/specs/semconv/)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import org.springframework.boot.gradle.plugin.SpringBootPlugin
2+
3+
plugins {
4+
id("java")
5+
id("org.springframework.boot") version "3.5.6"
6+
id("io.spring.dependency-management") version "1.1.6"
7+
}
8+
9+
val moduleName by extra { "io.opentelemetry.examples.reference-application" }
10+
11+
repositories {
12+
mavenCentral()
13+
}
14+
15+
dependencies {
16+
implementation(platform(SpringBootPlugin.BOM_COORDINATES))
17+
implementation(platform("io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom:2.20.1"))
18+
19+
// Spring Boot
20+
implementation("org.springframework.boot:spring-boot-starter-web")
21+
implementation("org.springframework.boot:spring-boot-starter-actuator")
22+
23+
// OpenTelemetry SDK and API
24+
implementation("io.opentelemetry:opentelemetry-api")
25+
implementation("io.opentelemetry:opentelemetry-sdk")
26+
implementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
27+
28+
// OpenTelemetry Exporters
29+
implementation("io.opentelemetry:opentelemetry-exporter-otlp")
30+
implementation("io.opentelemetry:opentelemetry-exporter-logging")
31+
implementation("io.opentelemetry:opentelemetry-exporter-prometheus")
32+
33+
// OpenTelemetry Instrumentation - use manual configuration instead of starter
34+
implementation("io.opentelemetry.instrumentation:opentelemetry-logback-appender-1.0")
35+
36+
// Micrometer for additional metrics
37+
implementation("io.micrometer:micrometer-registry-prometheus")
38+
39+
// Testing
40+
testImplementation("org.springframework.boot:spring-boot-starter-test")
41+
testImplementation("io.opentelemetry:opentelemetry-sdk-testing")
42+
}
43+
44+
tasks.withType<Test> {
45+
useJUnitPlatform()
46+
}
47+
48+
java {
49+
toolchain {
50+
languageVersion.set(JavaLanguageVersion.of(17))
51+
}
52+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
services:
2+
dice-server:
3+
build: .
4+
ports:
5+
- "8080:8080"
6+
environment:
7+
- OTEL_SERVICE_NAME=dice-server
8+
- OTEL_SERVICE_VERSION=1.0.0
9+
- OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4318
10+
- OTEL_TRACES_EXPORTER=otlp
11+
- OTEL_METRICS_EXPORTER=otlp
12+
- OTEL_LOGS_EXPORTER=otlp
13+
- OTEL_EXPORTER_OTLP_PROTOCOL=http/protobuf
14+
depends_on:
15+
- otel-collector
16+
17+
otel-collector:
18+
image: otel/opentelemetry-collector-contrib:latest
19+
ports:
20+
- "4317:4317" # OTLP gRPC
21+
- "4318:4318" # OTLP HTTP
22+
- "8889:8889" # Prometheus metrics
23+
volumes:
24+
- ./otel-collector-config.yaml:/etc/otelcol-contrib/otel-collector-config.yaml
25+
command: ["--config=/etc/otelcol-contrib/otel-collector-config.yaml"]
26+
27+
prometheus:
28+
image: prom/prometheus:latest
29+
ports:
30+
- "9090:9090"
31+
volumes:
32+
- ./prometheus.yml:/etc/prometheus/prometheus.yml
33+
command:
34+
- '--config.file=/etc/prometheus/prometheus.yml'
35+
- '--storage.tsdb.path=/prometheus'
36+
- '--web.console.libraries=/etc/prometheus/console_libraries'
37+
- '--web.console.templates=/etc/prometheus/consoles'
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
receivers:
2+
otlp:
3+
protocols:
4+
grpc:
5+
endpoint: 0.0.0.0:4317
6+
http:
7+
endpoint: 0.0.0.0:4318
8+
9+
processors:
10+
batch:
11+
memory_limiter:
12+
limit_mib: 512
13+
14+
exporters:
15+
logging:
16+
loglevel: info
17+
sampling_initial: 5
18+
sampling_thereafter: 200
19+
20+
prometheus:
21+
endpoint: "0.0.0.0:8889"
22+
metric_expiration: 180m
23+
enable_open_metrics: true
24+
25+
extensions:
26+
health_check:
27+
endpoint: 0.0.0.0:13133
28+
pprof:
29+
endpoint: 0.0.0.0:1777
30+
zpages:
31+
endpoint: 0.0.0.0:55679
32+
33+
service:
34+
extensions: [health_check, pprof, zpages]
35+
pipelines:
36+
traces:
37+
receivers: [otlp]
38+
processors: [memory_limiter, batch]
39+
exporters: [logging]
40+
metrics:
41+
receivers: [otlp]
42+
processors: [memory_limiter, batch]
43+
exporters: [logging, prometheus]
44+
logs:
45+
receivers: [otlp]
46+
processors: [memory_limiter, batch]
47+
exporters: [logging]
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
file_format: 0.3
2+
3+
# Service configuration
4+
resource:
5+
attributes:
6+
service.name: dice-server
7+
service.version: 1.0.0
8+
deployment.environment: local
9+
10+
# Tracer provider configuration
11+
tracer_provider:
12+
processors:
13+
- batch:
14+
exporter:
15+
console: {}
16+
sampler:
17+
parent_based:
18+
root:
19+
always_on: {}
20+
21+
# Meter provider configuration
22+
meter_provider:
23+
readers:
24+
- periodic:
25+
exporter:
26+
console: {}
27+
interval: 30000
28+
29+
# Logger provider configuration
30+
logger_provider:
31+
processors:
32+
- batch:
33+
exporter:
34+
console: {}
35+
36+
# Propagators
37+
propagators:
38+
- tracecontext
39+
- baggage

0 commit comments

Comments
 (0)