Skip to content

Commit cfadff7

Browse files
authored
Add declarative config javaagent example excluding healthcheck (#833)
1 parent 866894e commit cfadff7

File tree

14 files changed

+265
-13
lines changed

14 files changed

+265
-13
lines changed

.github/scripts/run-oats-tests.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,12 @@ pushd logging-k8s-stdout-otlp-json
66
../gradlew assemble
77
popd
88

9+
pushd javaagent-declarative-configuration
10+
../gradlew bootJar
11+
popd
12+
913
wget -q -O - https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash
1014

1115
go install github.com/grafana/[email protected]
1216
oats -timeout 5m logging-k8s-stdout-otlp-json/
17+
oats -timeout 5m javaagent-declarative-configuration/oats/

.github/workflows/oats-tests.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ on:
77
paths:
88
- .github/workflows/oats-tests.yml
99
- 'logging-k8s-stdout-otlp-json/**'
10+
- 'javaagent-declarative-configuration/oats/**'
1011
workflow_dispatch:
1112

1213
permissions:
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
opentelemetry-javaagent.jar
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Java Agent Declarative Configuration Example
2+
3+
This example demonstrates how to use [declarative configuration](https://opentelemetry.io/docs/specs/otel/configuration/#declarative-configuration) with the OpenTelemetry Java Agent to configure tracing behavior.
4+
5+
The configuration file is located at [otel-agent-config.yaml](./otel-agent-config.yaml).
6+
7+
This Spring Boot application includes two endpoints:
8+
- `/actuator/health` - A health check endpoint (from Spring Boot Actuator) that is configured to be excluded from tracing
9+
- `/api/example` - A simple API endpoint that will be traced normally
10+
11+
## End-to-End Instructions
12+
13+
### Prerequisites
14+
* Java 17 or higher
15+
* OpenTelemetry Java Agent JAR file (see next step)
16+
17+
Download the OpenTelemetry Java Agent:
18+
```bash
19+
# Download the latest OpenTelemetry Java Agent
20+
curl -L -o opentelemetry-javaagent.jar https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
21+
```
22+
23+
### Step 1: Build the Application
24+
25+
```bash
26+
# Build the JAR - Run from the javaagent-declarative-configuration directory
27+
../gradlew bootJar
28+
```
29+
30+
### Step 2: Run with OpenTelemetry Java Agent
31+
32+
```bash
33+
# From the javaagent-declarative-configuration directory
34+
35+
# Run with the OpenTelemetry Java Agent and contrib extension
36+
java -javaagent:opentelemetry-javaagent.jar \
37+
-Dotel.experimental.config.file=$(pwd)/otel-agent-config.yaml \
38+
-jar build/libs/javaagent-declarative-configuration.jar
39+
```
40+
41+
### Step 3: Test the Endpoints
42+
43+
Open a new terminal and test both endpoints:
44+
45+
```bash
46+
# This endpoint will NOT be traced (excluded by configuration)
47+
curl http://localhost:8080/actuator/health
48+
49+
# This endpoint WILL be traced normally
50+
curl http://localhost:8080/api/example
51+
```
52+
53+
### Step 4: Verify Tracing Behavior
54+
55+
Check the application logs to see:
56+
- Health check requests (`/actuator/health`) should NOT generate traces (excluded by configuration)
57+
- API requests (`/api/example`) should generate traces with console output
58+
59+
## Configuration
60+
61+
The `otel-agent-config.yaml` file demonstrates rule-based sampling using declarative configuration to exclude health checks from tracing:
62+
63+
```yaml
64+
tracer_provider:
65+
sampler:
66+
rule_based_routing:
67+
fallback_sampler:
68+
always_on:
69+
span_kind: SERVER
70+
rules:
71+
- action: DROP
72+
attribute: url.path
73+
pattern: /actuator.*
74+
```
75+
76+
This configuration:
77+
- Uses the `rule_based_routing` sampler from the OpenTelemetry contrib extension
78+
- Excludes health check endpoints (`/actuator.*`) from tracing using the `DROP` action
79+
- Samples all other requests using the `always_on` fallback sampler
80+
- Only applies to `SERVER` span kinds
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import org.springframework.boot.gradle.plugin.SpringBootPlugin
2+
import org.springframework.boot.gradle.tasks.bundling.BootJar
3+
4+
plugins {
5+
id("java")
6+
id("org.springframework.boot") version "3.5.6"
7+
}
8+
9+
description = "OpenTelemetry Java Agent Declarative Configuration Example"
10+
val moduleName by extra { "io.opentelemetry.examples.javaagent.declarative" }
11+
12+
dependencies {
13+
implementation(platform(SpringBootPlugin.BOM_COORDINATES))
14+
implementation("org.springframework.boot:spring-boot-starter-web")
15+
implementation("org.springframework.boot:spring-boot-starter-actuator")
16+
}
17+
18+
tasks.named<BootJar>("bootJar") {
19+
archiveFileName = "javaagent-declarative-configuration.jar"
20+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
FROM eclipse-temurin:21.0.8_9-jre@sha256:615497e30ae2b2654ff7bccc7cb057c27443041994593c726852f04dc99830b1
2+
3+
WORKDIR /usr/src/app/
4+
5+
# renovate: datasource=github-releases depName=opentelemetry-java-instrumentation packageName=open-telemetry/opentelemetry-java-instrumentation
6+
ENV OPENTELEMETRY_JAVA_INSTRUMENTATION_VERSION=v2.21.0
7+
8+
ADD ./build/libs/javaagent-declarative-configuration.jar ./app.jar
9+
ADD --chmod=644 https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/download/$OPENTELEMETRY_JAVA_INSTRUMENTATION_VERSION/opentelemetry-javaagent.jar ./opentelemetry-javaagent.jar
10+
ADD ./otel-agent-config.yaml ./otel-agent-config.yaml
11+
ENV JAVA_TOOL_OPTIONS=-javaagent:./opentelemetry-javaagent.jar
12+
ENV OTEL_EXPERIMENTAL_CONFIG_FILE=/usr/src/app/otel-agent-config.yaml
13+
14+
EXPOSE 8080
15+
ENTRYPOINT [ "java", "-jar", "./app.jar" ]
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
version: '3'
2+
services:
3+
app:
4+
build:
5+
context: ../
6+
dockerfile: oats/Dockerfile
7+
environment:
8+
OTEL_SERVICE_NAME: "declarative-config-example-app"
9+
OTEL_EXPORTER_OTLP_ENDPOINT: http://lgtm:4318
10+
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: http://lgtm:4318
11+
OTEL_EXPORTER_OTLP_PROTOCOL: http/protobuf
12+
ports:
13+
- "8080:8080"
14+
healthcheck:
15+
test: ["CMD", "curl", "-f", "http://localhost:8080/actuator/health"]
16+
interval: 10s
17+
timeout: 5s
18+
retries: 3
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# OATS is an acceptance testing framework for OpenTelemetry - https://github.com/grafana/oats
2+
3+
docker-compose:
4+
files:
5+
- ./docker-compose.yml
6+
app-service: app
7+
app-docker-tag: javaagent-declarative-config:latest
8+
app-docker-port: 8080
9+
10+
input:
11+
# This endpoint should be traced normally
12+
- path: /api/example
13+
# This endpoint should NOT be traced (excluded by declarative config)
14+
# We send the request but don't assert spans for it - the absence of spans
15+
# for /actuator/health demonstrates the sampling rule is working
16+
- path: /actuator/health
17+
18+
expected:
19+
traces:
20+
# Verify that /api/example creates a trace with SERVER span
21+
- traceql: '{ span.http.route = "/api/example" }'
22+
spans:
23+
- name: "GET /api/example"
24+
attributes:
25+
http.request.method: "GET"
26+
http.route: "/api/example"
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# See https://github.com/open-telemetry/opentelemetry-configuration for details on schema and examples
2+
3+
file_format: "1.0-rc.2"
4+
5+
resource:
6+
attributes:
7+
- name: service.name
8+
value: spring-boot-declarative-config-example
9+
10+
propagator:
11+
composite:
12+
- tracecontext:
13+
- baggage:
14+
15+
tracer_provider:
16+
processors:
17+
- batch:
18+
exporter:
19+
otlp_http:
20+
endpoint: ${OTEL_EXPORTER_OTLP_TRACES_ENDPOINT:-http://localhost:4318}/v1/traces
21+
22+
# Configure a console exporter for exploring without a collector/backend
23+
- batch:
24+
exporter:
25+
console:
26+
27+
# Configure sampling to exclude health check endpoints
28+
sampler:
29+
rule_based_routing:
30+
fallback_sampler:
31+
always_on:
32+
# Filter to spans of this span_kind. Must be one of: SERVER, CLIENT, INTERNAL, CONSUMER, PRODUCER.
33+
span_kind: SERVER # only apply to server spans
34+
# List of rules describing spans to drop. Spans are dropped if they match one of the rules.
35+
rules:
36+
# The action to take when the rule is matches. Must be of: DROP, RECORD_AND_SAMPLE.
37+
- action: DROP
38+
# The span attribute to match against.
39+
attribute: url.path
40+
# The pattern to compare the span attribute to.
41+
pattern: /actuator.*
42+
43+
meter_provider:
44+
readers:
45+
- periodic:
46+
exporter:
47+
otlp_http:
48+
endpoint: ${OTEL_EXPORTER_OTLP_METRICS_ENDPOINT:-http://localhost:4318}/v1/metrics
49+
50+
logger_provider:
51+
processors:
52+
- batch:
53+
exporter:
54+
otlp_http:
55+
endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT:-http://localhost:4318}/v1/logs
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.examples.fileconfig;
7+
8+
import org.springframework.http.ResponseEntity;
9+
import org.springframework.web.bind.annotation.GetMapping;
10+
import org.springframework.web.bind.annotation.RequestMapping;
11+
import org.springframework.web.bind.annotation.RestController;
12+
13+
@RestController
14+
@RequestMapping("/api")
15+
public class ApiController {
16+
17+
@GetMapping("/example")
18+
public ResponseEntity<String> example() {
19+
return ResponseEntity.ok("Hello from OpenTelemetry example API!");
20+
}
21+
}

0 commit comments

Comments
 (0)