Skip to content
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

Add w3c trace context propagation example #78

Merged
merged 15 commits into from
Mar 27, 2024
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ The repository includes example applications and configurations for Datadog user
| [Span Links][12] | Distributed app with Kafka messages, OTel Go and Java instrumentations | OTel span links |
| [W3C Trace Context][13] | Java and Python app to demonstrate W3C trace context propagation between OTel and DD instrumented apps | W3C trace context, runtime metrics |
| [Kubernetes (Datadog Operator and Helm) with Express][15] | An Express sample app configured with Kubernetes | Kubernetes |
| [Python and Javascript trace context propagation][17] | An Express controller server calling two Flask servers | Standalone Host |


[1]: https://opentelemetry.io/
Expand All @@ -35,7 +36,8 @@ The repository includes example applications and configurations for Datadog user
[10]: ./apps/rest-services/py/
[11]: ./apps/rpc/
[12]: ./apps/span-links/
[13]: ./apps/w3-trace-context/
[13]: ./apps/w3c-trace-context/
[14]: ./guides/common-mistakes.md
[15]: ./configurations/
[16]: ./apps/kubernetes-express-otel/
[16]: ./apps/kubernetes-express-otel/
[17]: ./apps/w3c-trace-context-ex2/
27 changes: 27 additions & 0 deletions apps/w3c-trace-context-ex2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Standalone host Otel Example
This project consists of two Flask servers and one Express server instrumented with Opentelemetry on a standalone host. (This is not using k8s or containers)

There are a few required steps to get this example working.
1. Install and set up the OpenTelemetry Collector on the host of your choice. https://opentelemetry.io/docs/collector/installation/
2. Set up the Collector configuration. An example collector configuration can be found at [Config File](./config.yaml).
* The config.yaml is set up to send traces and metrics from OTLP Collector to the Datadog Exporter.
* Update the DATADOG_API_KEY as well.
3. Run this collector ~ `./otelcol-contrib --config=config.yaml`
4. Once the collector is up and running. Set up the 3 servers. (Can be found in each of the servers README)
5. To trigger the service call

### Success
```bash
curl -X POST http://localhost:5001/update_score \
-H "Content-Type: application/json" \
-d '{"player": "John Doe"}'
```
### Error
``` bash
curl -X POST http://localhost:5001/update_score \
-H "Content-Type: application/json" \
-d '{}'
```


View traces & standalone host in app.datadoghq.com
41 changes: 41 additions & 0 deletions apps/w3c-trace-context-ex2/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
hostmetrics:
# collect metrics every 10 seconds.
collection_interval: 10s
scrapers:
cpu:
disk:
filesystem:
memory:
network:
load:
paging:
processes:

exporters:
# NOTE: Prior to v0.86.0 use `logging` instead of `debug`.
debug:
verbosity: detailed
datadog:
api:
site: datadoghq.com
key: <DATADOG_API_KEY>

processors:
batch:
service:
pipelines:
traces:
receivers: [otlp]
exporters: [datadog]
processors: [batch]
metrics:
receivers: [otlp]
exporters: [datadog]
processors: [batch]
SaravShah marked this conversation as resolved.
Show resolved Hide resolved
19 changes: 19 additions & 0 deletions apps/w3c-trace-context-ex2/game_controller/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Game Controller
This project is a simple Express.js application that uses the OpenTelemetry API for tracing and axios for HTTP requests.


## Installation
* Node.js (v12 or later)
* npm (v6 or later)


```bash
npm install
```

## Run the server

```bash
opentelemetry-instrument --service_name controller --logs_exporter otlp node game_controller.js
```

47 changes: 47 additions & 0 deletions apps/w3c-trace-context-ex2/game_controller/controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
const express = require('express');
const axios = require('axios');
const { context, trace, propagation } = require('@opentelemetry/api');
const { NodeSDK } = require('@opentelemetry/sdk-node');
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');

const sdk = new NodeSDK({
instrumentations: [getNodeAutoInstrumentations()],
});

sdk.start();
const app = express();
app.use(express.json());

app.post('/play_game', async (req, res) => {
const tracer = trace.getTracer('express-game-controller');
const span = tracer.startSpan('play_game');

const ctx = trace.setSpan(context.active(), span);

context.with(ctx, async () => {
try {
const player = req.body.player;
const headers = {};
propagation.inject(context.active(), headers);
const diceRollResult = await axios.get(`http://localhost:8080/rolldice?player=${player}`, { headers });
const updateScoreResult = await axios.post('http://localhost:5001/update_score', {
player: player,
result: diceRollResult.data
}, { headers });

span.addEvent('score_updated');
span.end();
res.json(updateScoreResult.data);
} catch (error) {
span.recordException(error);
span.end();
console.error(error);
res.status(500).send('An error occurred');
}
});
});

const PORT = process.env.PORT || 5002;
app.listen(PORT, () => {
console.log(`Game Controller service listening at http://localhost:${PORT}`);
});
Loading
Loading