Skip to content

Commit db97899

Browse files
committed
chore(instrumentation-undici): add example
1 parent 7d69f4a commit db97899

File tree

7 files changed

+263
-2
lines changed

7 files changed

+263
-2
lines changed

examples/undici/README.md

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Overview
2+
3+
OpenTelemetry Undici Instrumentation allows the user to automatically collect trace data and export them to the backend of choice (we can use Zipkin or Jaeger for this example), to give observability to distributed systems.
4+
5+
This is a simple example that demonstrates tracing HTTP request from client to server. The example
6+
shows key aspects of tracing such as
7+
8+
- Root Span (on Client)
9+
- Child Span (on Client)
10+
- Child Span from a Remote Parent (on Server)
11+
- SpanContext Propagation (from Client to Server)
12+
- Span Events
13+
- Span Attributes
14+
15+
## Installation
16+
17+
```sh
18+
# from this directory
19+
npm install
20+
```
21+
22+
Setup [Zipkin Tracing](https://zipkin.io/pages/quickstart.html)
23+
or
24+
Setup [Jaeger Tracing](https://www.jaegertracing.io/docs/latest/getting-started/#all-in-one)
25+
26+
## Run the Application
27+
28+
### Zipkin
29+
30+
- Run the server
31+
32+
```sh
33+
# from this directory
34+
npm run zipkin:server
35+
```
36+
37+
- Run the client
38+
39+
```sh
40+
# from this directory
41+
npm run zipkin:client
42+
```
43+
44+
#### Zipkin UI
45+
46+
`zipkin:server` script should output the `traceid` in the terminal (e.g `traceid: 4815c3d576d930189725f1f1d1bdfcc6`).
47+
Go to Zipkin with your browser <http://localhost:9411/zipkin/traces/(your-trace-id)> (e.g <http://localhost:9411/zipkin/traces/4815c3d576d930189725f1f1d1bdfcc6>)
48+
49+
<p align="center"><img src="./images/zipkin-ui.png?raw=true"/></p>
50+
51+
### Jaeger
52+
53+
- Run the server
54+
55+
```sh
56+
# from this directory
57+
npm run jaeger:server
58+
```
59+
60+
- Run the client
61+
62+
```sh
63+
# from this directory
64+
npm run jaeger:client
65+
```
66+
67+
#### Jaeger UI
68+
69+
`jaeger:server` script should output the `traceid` in the terminal (e.g `traceid: 4815c3d576d930189725f1f1d1bdfcc6`).
70+
Go to Jaeger with your browser <http://localhost:16686/trace/(your-trace-id)> (e.g <http://localhost:16686/trace/4815c3d576d930189725f1f1d1bdfcc6>)
71+
72+
<p align="center"><img src="images/jaeger-ui.png?raw=true"/></p>
73+
74+
## Useful links
75+
76+
- For more information on OpenTelemetry, visit: <https://opentelemetry.io/>
77+
- For more information on OpenTelemetry for Node.js, visit: <https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node>
78+
79+
## LICENSE
80+
81+
Apache License 2.0

examples/undici/client.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
const undici = require('undici');
4+
const tracer = require('./tracer')('example-undici-client');
5+
6+
/** A function which makes requests and handles response. */
7+
async function makeRequests(type) {
8+
tracer.startActiveSpan('makeRequests with global fetch', async (span) => {
9+
const fetchResponse = await fetch('localhost:8080/helloworld');
10+
console.log('response with global fetch: ' + await fetchResponse.text());
11+
12+
const undiciResponse = await undici.fetch('localhost:8080/helloworld');
13+
console.log('response with undici fetch: ' + await undiciResponse.text());
14+
span.end();
15+
});
16+
17+
// The process must live for at least the interval past any traces that
18+
// must be exported, or some risk being lost if they are recorded after the
19+
// last export.
20+
console.log('Sleeping 5 seconds before shutdown to ensure all records are flushed.');
21+
setTimeout(() => { console.log('Completed.'); }, 5000);
22+
}
23+
24+
makeRequests();

examples/undici/docker-compose.yml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
version: '3.7'
2+
3+
services:
4+
jaeger:
5+
image: jaegertracing/all-in-one
6+
ports:
7+
- "16686:16686"
8+
- "4318:4318"
9+
environment:
10+
- LOG_LEVEL=debug
11+
networks:
12+
- undici-example
13+
zipkin:
14+
image: openzipkin/zipkin
15+
container_name: zipkin
16+
ports:
17+
# Port used for the Zipkin UI and HTTP Api
18+
- 9411:9411
19+
20+
networks:
21+
undici-example:

examples/undici/package.json

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
{
2+
"name": "undici-example",
3+
"private": true,
4+
"version": "0.46.0",
5+
"description": "Example of Undici integration with OpenTelemetry",
6+
"main": "index.js",
7+
"scripts": {
8+
"docker:start": "docker compose -f .docker-compose.yml up -d",
9+
"docker:stop": "docker compose -f ./docker-compose.yml down",
10+
"zipkin:server": "cross-env EXPORTER=zipkin node ./server.js",
11+
"zipkin:client": "cross-env EXPORTER=zipkin node ./client.js",
12+
"jaeger:server": "cross-env EXPORTER=jaeger node ./server.js",
13+
"jaeger:client": "cross-env EXPORTER=jaeger node ./client.js"
14+
},
15+
"repository": {
16+
"type": "git",
17+
"url": "git+ssh://[email protected]/open-telemetry/opentelemetry-js.git"
18+
},
19+
"keywords": [
20+
"opentelemetry",
21+
"undici",
22+
"fetch",
23+
"tracing"
24+
],
25+
"engines": {
26+
"node": ">=14"
27+
},
28+
"author": "OpenTelemetry Authors",
29+
"license": "Apache-2.0",
30+
"bugs": {
31+
"url": "https://github.com/open-telemetry/opentelemetry-js/issues"
32+
},
33+
"dependencies": {
34+
"@opentelemetry/api": "^1.3.0",
35+
"@opentelemetry/exporter-zipkin": "1.19.0",
36+
"@opentelemetry/instrumentation": "0.46.0",
37+
"@opentelemetry/instrumentation-undici": "0.46.0",
38+
"@opentelemetry/exporter-trace-otlp-proto": "0.46.0",
39+
"@opentelemetry/resources": "1.19.0",
40+
"@opentelemetry/sdk-trace-base": "1.19.0",
41+
"@opentelemetry/sdk-trace-node": "1.19.0",
42+
"@opentelemetry/semantic-conventions": "1.19.0"
43+
},
44+
"homepage": "https://github.com/open-telemetry/opentelemetry-js/tree/main/examples/undici",
45+
"devDependencies": {
46+
"cross-env": "^6.0.0"
47+
}
48+
}

examples/undici/server.js

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
'use strict';
2+
3+
const api = require('@opentelemetry/api');
4+
const tracer = require('./tracer')('example-undici-server');
5+
const http = require('http');
6+
7+
/** Starts a HTTP server that receives requests on sample server port. */
8+
function startServer(port) {
9+
// Creates a server
10+
const server = http.createServer(handleRequest);
11+
// Starts the server
12+
server.listen(port, (err) => {
13+
if (err) {
14+
throw err;
15+
}
16+
console.log(`Node HTTP listening on ${port}`);
17+
});
18+
}
19+
20+
/** A function which handles requests and send response. */
21+
function handleRequest(request, response) {
22+
const currentSpan = api.trace.getActiveSpan();
23+
// display traceid in the terminal
24+
const traceId = currentSpan.spanContext().traceId;
25+
console.log(`traceId: ${traceId}`);
26+
const span = tracer.startSpan('handleRequest', {
27+
kind: 1, // server
28+
attributes: { key: 'value' },
29+
});
30+
// Annotate our span to capture metadata about the operation
31+
span.addEvent('invoking handleRequest');
32+
33+
const body = [];
34+
request.on('error', (err) => console.log(err));
35+
request.on('data', (chunk) => body.push(chunk));
36+
request.on('end', () => {
37+
// deliberately sleeping to mock some action.
38+
setTimeout(() => {
39+
span.end();
40+
response.end('Hello World!');
41+
}, 2000);
42+
});
43+
}
44+
45+
startServer(8080);

examples/undici/tracer.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict';
2+
3+
const opentelemetry = require('@opentelemetry/api');
4+
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
5+
const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
6+
const { Resource } = require('@opentelemetry/resources');
7+
const { SemanticResourceAttributes } = require('@opentelemetry/semantic-conventions');
8+
const { SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-base');
9+
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-proto');
10+
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
11+
const { UndiciInstrumentation } = require('@opentelemetry/instrumentation-undici');
12+
13+
const EXPORTER = process.env.EXPORTER || '';
14+
15+
module.exports = (serviceName) => {
16+
const provider = new NodeTracerProvider({
17+
resource: new Resource({
18+
[SemanticResourceAttributes.SERVICE_NAME]: serviceName,
19+
}),
20+
});
21+
22+
let exporter;
23+
if (EXPORTER.toLowerCase().startsWith('z')) {
24+
exporter = new ZipkinExporter();
25+
} else {
26+
exporter = new OTLPTraceExporter();
27+
}
28+
29+
provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
30+
31+
// Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings
32+
provider.register();
33+
34+
registerInstrumentations({
35+
// // when boostraping with lerna for testing purposes
36+
instrumentations: [
37+
new UndiciInstrumentation(),
38+
],
39+
});
40+
41+
return opentelemetry.trace.getTracer('undici-example');
42+
};

experimental/packages/opentelemetry-instrumentation-undici/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ npm install --save @opentelemetry/instrumentation-undici
1515

1616
## Usage
1717

18-
OpenTelemetry HTTP Instrumentation allows the user to automatically collect trace data and export them to their backend of choice, to give observability to distributed systems.
18+
OpenTelemetry Undici/fetch Instrumentation allows the user to automatically collect trace data and export them to their backend of choice, to give observability to distributed systems.
1919

2020
To load a specific instrumentation (Undici in this case), specify it in the Node Tracer's configuration.
2121

@@ -42,7 +42,7 @@ registerInstrumentations({
4242
<!-- TODO: -->
4343
See [examples/http](https://github.com/open-telemetry/opentelemetry-js/tree/main/examples/fetch) for a short example.
4444

45-
### Fetch instrumentation Options
45+
### Undici/Fetch instrumentation Options
4646

4747
<!-- TODO: check PR description about config -->
4848

0 commit comments

Comments
 (0)