Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apps/w3c-trace-context/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Required: Your Datadog API key
DD_API_KEY=your_api_key_here

# Optional: Datadog site (default: datadoghq.com)
# DD_SITE=datadoghq.com
22 changes: 14 additions & 8 deletions apps/w3c-trace-context/Dockerfile.calendar.java.dd
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
# Unless explicitly stated otherwise all files in this repository are licensed
# under the Apache 2.0 License.
#
FROM openjdk:17-buster
FROM eclipse-temurin:17-jdk AS builder

RUN apt-get update -y; apt-get install curl -y
RUN apt-get update -y && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/*

WORKDIR /home/otel
RUN curl -Lo dd-java-agent.jar https://dtdg.co/latest-java-tracer

RUN curl -Lo dd-java-agent.jar https://dtdg.co/latest-java-tracer


COPY java/calendar calendar/
COPY java/calendar calendar/

WORKDIR /home/otel/calendar

#Compile with gradle
# Compile with gradle
RUN ./gradlew build

ENTRYPOINT ["java","-javaagent:../dd-java-agent.jar", "-jar" , "build/libs/calendar-0.0.1-SNAPSHOT.jar"]
FROM eclipse-temurin:17-jre

WORKDIR /app
COPY --from=builder /home/otel/dd-java-agent.jar /app/dd-java-agent.jar
COPY --from=builder /home/otel/calendar/build/libs/calendar-0.0.1-SNAPSHOT.jar /app/calendar.jar

STOPSIGNAL SIGTERM

ENTRYPOINT ["java", "-javaagent:/app/dd-java-agent.jar", "-jar", "/app/calendar.jar"]
EXPOSE 8080
18 changes: 13 additions & 5 deletions apps/w3c-trace-context/Dockerfile.calendar.java.otel
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
# Unless explicitly stated otherwise all files in this repository are licensed
# under the Apache 2.0 License.
#
FROM openjdk:17-buster
FROM eclipse-temurin:17-jdk AS builder

RUN apt-get update -y; apt-get install curl -y
RUN apt-get update -y && apt-get install -y --no-install-recommends curl && rm -rf /var/lib/apt/lists/*

WORKDIR /home/otel
RUN curl -Lo opentelemetry-javaagent.jar https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar

COPY java/calendar calendar/
COPY java/calendar calendar/

WORKDIR /home/otel/calendar

#Compile with gradle
# Compile with gradle
RUN ./gradlew build

ENTRYPOINT ["java","-javaagent:../opentelemetry-javaagent.jar", "-jar" , "build/libs/calendar-0.0.1-SNAPSHOT.jar"]
FROM eclipse-temurin:17-jre

WORKDIR /app
COPY --from=builder /home/otel/opentelemetry-javaagent.jar /app/opentelemetry-javaagent.jar
COPY --from=builder /home/otel/calendar/build/libs/calendar-0.0.1-SNAPSHOT.jar /app/calendar.jar

STOPSIGNAL SIGTERM

ENTRYPOINT ["java", "-javaagent:/app/opentelemetry-javaagent.jar", "-jar", "/app/calendar.jar"]
EXPOSE 8080
11 changes: 6 additions & 5 deletions apps/w3c-trace-context/Dockerfile.calendar.py.dd
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
# Unless explicitly stated otherwise all files in this repository are dual-licensed
# under the Apache 2.0 or BSD3 Licenses.
FROM python:3

FROM python:3.12-slim

WORKDIR /home

COPY py /home/py
WORKDIR /home/py

RUN pip install -r requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

STOPSIGNAL SIGTERM

# Run the application with Datadog
CMD ["ddtrace-run", "python", "-m", "calendar_app.app"]
# Run the application with Datadog auto-instrumentation
CMD ["ddtrace-run", "python", "-m", "calendar_app.app"]
18 changes: 10 additions & 8 deletions apps/w3c-trace-context/Dockerfile.calendar.py.otel
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
# Unless explicitly stated otherwise all files in this repository are dual-licensed
# under the Apache 2.0 or BSD3 Licenses.
FROM python:3
FROM python:3.12-slim

WORKDIR /home

COPY py /home/py
WORKDIR /home/py

RUN pip install -r requirements.txt
RUN pip install opentelemetry-distro
RUN pip install opentelemetry-instrumentation-flask
RUN pip install opentelemetry-exporter-otlp
RUN pip install opentelemetry-instrumentation-system-metrics
RUN pip install --no-cache-dir -r requirements.txt && \
pip install --no-cache-dir \
opentelemetry-distro==0.60b1 \
opentelemetry-instrumentation-flask==0.60b1 \
opentelemetry-exporter-otlp==1.39.1 \
opentelemetry-instrumentation-requests==0.60b1

STOPSIGNAL SIGTERM

# Run the application with OTel
CMD ["opentelemetry-instrument", "python", "-m", "calendar_app.app"]
# Run the application with OTel auto-instrumentation
CMD ["opentelemetry-instrument", "python", "-m", "calendar_app.app"]
115 changes: 97 additions & 18 deletions apps/w3c-trace-context/README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,117 @@
## Calendar Application
## W3C Trace Context Propagation Example

Demonstrates [W3C Trace Context](https://www.w3.org/TR/trace-context/) propagation
between OpenTelemetry-instrumented and Datadog-instrumented services. A Java
(Spring Boot) "frontend" calendar service calls a Python (Flask) "backend"
calendar service. Both agents -- OTel and Datadog -- inject and extract
`traceparent` and `tracestate` HTTP headers automatically so that a single
distributed trace spans both services regardless of which instrumentation
library each one uses.

### API

```
GET /calendar
Returns a random date in 2022.
GET /calendar -> returns a random date in 2022
GET /health -> health check endpoint
```

Request
curl 'http://localhost:8080/calendar'
Request:
```bash
curl http://localhost:8080/calendar
```

Response
Response:
```json
{"date":"3/22/2022"}
```

### Prerequisites

## Docker Compose

Retrieve API_KEY from datadoghq, and expose same on Shell
Set your Datadog API key:

```
export DD_API_KEY=xx
```bash
export DD_API_KEY=<your-api-key>
```

Bring up java & py services with DD agent. Java service is instrumented with otel, py service is instrumented with datadog
Optionally copy `.env.example` to `.env` and fill in the values.

```
### Deployment Modes

The example ships three docker-compose files, each showing a different
combination of OTel and Datadog instrumentation. All three use the Datadog
Agent as the backend for both OTLP and DD trace intake.

#### Mode 1 -- OTel Java, DD Python

Java service instrumented with the OTel Java agent sends traces via OTLP.
Python service instrumented with ddtrace sends traces via the DD trace API.
W3C `traceparent`/`tracestate` headers link the two.

```bash
docker compose -f docker-compose-otel-java-dd-py.yaml up
```

Bring up java & py services with DD agent. Java service is instrumented with dd-trace, py service is instrumented with otel
| Service | Port | Instrumentation |
|---------|------|-----------------|
| calendar-java-otel | 8080 | OpenTelemetry Java agent |
| calendar-py-dd | 9090 | ddtrace |

```
#### Mode 2 -- DD Java, OTel Python

Java service instrumented with dd-java-agent; Python service instrumented
with the OTel Python SDK. `DD_TRACE_PROPAGATION_STYLE=tracecontext` on the
Java side ensures W3C headers are emitted.

```bash
docker compose -f docker-compose-dd-java-otel-py.yaml up
```

Bring up two sets of java and py services with DD agent. One set is instrumented with dd-trace, the other set is instrumented with otel
| Service | Port | Instrumentation |
|---------|------|-----------------|
| calendar-java-dd | 8080 | dd-java-agent |
| calendar-py-otel | 9090 | OpenTelemetry Python |

```
#### Mode 3 -- Both side by side

Two parallel request chains through a single Datadog Agent, proving
cross-instrumentation interoperability in both directions.

```bash
docker compose -f docker-compose-dd-otel-both.yaml up
```
```

| Service | Port | Instrumentation |
|---------|------|-----------------|
| calendar-java-dd (chain A) | 8080 | dd-java-agent |
| calendar-py-otel (chain A) | 9091 | OpenTelemetry Python |
| calendar-java-otel (chain B) | 8081 | OpenTelemetry Java agent |
| calendar-py-dd (chain B) | 9090 | ddtrace |

### How W3C Trace Context works here

Both the OpenTelemetry agents and the Datadog agents handle `traceparent`
and `tracestate` injection/extraction automatically:

- **OTel services** use `OTEL_PROPAGATORS=tracecontext,baggage` (the default)
to propagate W3C headers.
- **DD services** use `DD_TRACE_PROPAGATION_STYLE=tracecontext` to switch
from the Datadog-native propagation format to W3C Trace Context.
- **128-bit trace IDs** are enabled on DD services via
`DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED=true` so that trace IDs are
compatible with the 32-hex-character trace-id field in the `traceparent`
header.

The Datadog Agent accepts both OTLP (ports 4317/4318) and DD APM traces
(port 8126), correlating them into unified traces in the Datadog UI.

### Configuration reference

| Variable | Used by | Purpose |
|----------|---------|---------|
| `DD_API_KEY` | DD Agent | Datadog API key |
| `DD_SITE` | DD Agent | Datadog site (default `datadoghq.com`) |
| `DD_TRACE_PROPAGATION_STYLE` | DD services | Set to `tracecontext` for W3C |
| `DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED` | DD services | Full 128-bit trace IDs |
| `OTEL_PROPAGATORS` | OTel services | Propagator chain (`tracecontext,baggage`) |
| `OTEL_EXPORTER_OTLP_ENDPOINT` | OTel services | OTLP endpoint on the DD Agent |
| `OTEL_EXPORTER_OTLP_PROTOCOL` | OTel services | `grpc` or `http/protobuf` |
59 changes: 55 additions & 4 deletions apps/w3c-trace-context/docker-compose-dd-java-otel-py.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
version: "3.9"
# Mode 2: DD-instrumented Java service -> OTel-instrumented Python service
#
# Demonstrates W3C Trace Context propagation from a Datadog-instrumented
# Java service to an OpenTelemetry-instrumented Python service. The DD Java
# agent injects traceparent/tracestate headers (when DD_TRACE_PROPAGATION_STYLE
# is set to tracecontext); the OTel Python agent extracts them to continue
# the distributed trace.
#
# Usage:
# export DD_API_KEY=<your-api-key>
# docker compose -f docker-compose-dd-java-otel-py.yaml up
services:
calendar-java-dd:
depends_on:
- datadog-agent
- calendar-py-otel
datadog-agent:
condition: service_healthy
calendar-py-otel:
condition: service_healthy
container_name: calendar-java-dd
build:
context: .
Expand All @@ -18,8 +30,23 @@ services:
- SERVER_PORT=8080
ports:
- "8080:8080"
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8080/health || exit 1"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
deploy:
resources:
limits:
memory: 512M
cpus: "1.0"
stop_grace_period: 15s

calendar-py-otel:
depends_on:
datadog-agent:
condition: service_healthy
container_name: calendar-py-otel
build:
context: .
Expand All @@ -28,12 +55,25 @@ services:
- OTEL_SERVICE_NAME=calendar-py-otel
- OTEL_EXPORTER_OTLP_ENDPOINT=http://datadog-agent:4317
- OTEL_EXPORTER_OTLP_PROTOCOL=grpc
- OTEL_PROPAGATORS=tracecontext,baggage
- OTEL_RESOURCE_ATTRIBUTES=deployment.environment=docker,host.name=otelcol-docker
- OTEL_TRACES_EXPORTER=otlp
- OTEL_METRICS_EXPORTER=otlp
- SERVER_PORT=9090
ports:
- "9090:9090"
healthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:9090/health || exit 1"]
interval: 10s
timeout: 5s
retries: 5
start_period: 15s
deploy:
resources:
limits:
memory: 256M
cpus: "0.5"
stop_grace_period: 15s

datadog-agent:
container_name: datadog-agent
Expand All @@ -46,7 +86,7 @@ services:
- 4318:4318
environment:
- DD_API_KEY
- DD_SITE=datadoghq.com
- DD_SITE=${DD_SITE:-datadoghq.com}
- DD_APM_NON_LOCAL_TRAFFIC=true
- DD_DOGSTATSD_NON_LOCAL_TRAFFIC=true
- DD_OTLP_CONFIG_RECEIVER_PROTOCOLS_GRPC_ENDPOINT=0.0.0.0:4317
Expand All @@ -55,3 +95,14 @@ services:
- /var/run/docker.sock:/var/run/docker.sock
- /proc/:/host/proc/:ro
- /sys/fs/cgroup:/host/sys/fs/cgroup:ro
healthcheck:
test: ["CMD-SHELL", "agent health"]
interval: 10s
timeout: 5s
retries: 5
start_period: 15s
deploy:
resources:
limits:
memory: 512M
cpus: "1.0"
Loading