Skip to content

Commit df225e0

Browse files
authored
docs: add example for express plugin open-telemetry#800 (open-telemetry#810)
* docs: add example for express plugin open-telemetry#800 * chore: add link to express example in plugin's readme * chore: addres PR's comments
1 parent 1171938 commit df225e0

File tree

8 files changed

+252
-0
lines changed

8 files changed

+252
-0
lines changed

examples/express/README.md

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Overview
2+
3+
OpenTelemetry Express 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 calls made to Express API. The example
6+
shows key aspects of tracing such as
7+
- Root Span (on Client)
8+
- Child Span (on Client)
9+
- Span Events
10+
- Span Attributes
11+
12+
## Installation
13+
14+
```sh
15+
$ # from this directory
16+
$ npm install
17+
```
18+
19+
Setup [Zipkin Tracing](https://zipkin.io/pages/quickstart.html)
20+
or
21+
Setup [Jaeger Tracing](https://www.jaegertracing.io/docs/latest/getting-started/#all-in-one)
22+
23+
## Run the Application
24+
25+
### Zipkin
26+
27+
- Run the server
28+
29+
```sh
30+
# from this directory
31+
$ npm run zipkin:server
32+
```
33+
34+
- Run the client
35+
36+
```sh
37+
# from this directory
38+
npm run zipkin:client
39+
```
40+
41+
#### Zipkin UI
42+
`zipkin:server` script should output the `traceid` in the terminal (e.g `traceid: 4815c3d576d930189725f1f1d1bdfcc6`).
43+
Go to Zipkin with your browser [http://localhost:9411/zipkin/traces/(your-trace-id)]() (e.g http://localhost:9411/zipkin/traces/4815c3d576d930189725f1f1d1bdfcc6)
44+
45+
<p align="center"><img src="./images/zipkin.jpg?raw=true"/></p>
46+
47+
### Jaeger
48+
49+
- Run the server
50+
51+
```sh
52+
# from this directory
53+
$ npm run jaeger:server
54+
```
55+
56+
- Run the client
57+
58+
```sh
59+
# from this directory
60+
npm run jaeger:client
61+
```
62+
63+
#### Jaeger UI
64+
65+
`jaeger:server` script should output the `traceid` in the terminal (e.g `traceid: 4815c3d576d930189725f1f1d1bdfcc6`).
66+
Go to Jaeger with your browser [http://localhost:16686/trace/(your-trace-id)]() (e.g http://localhost:16686/trace/4815c3d576d930189725f1f1d1bdfcc6)
67+
68+
<p align="center"><img src="images/jaeger.jpg?raw=true"/></p>
69+
70+
## Useful links
71+
- For more information on OpenTelemetry, visit: <https://opentelemetry.io/>
72+
- For more information on OpenTelemetry for Node.js, visit: <https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-node>
73+
74+
## LICENSE
75+
76+
Apache License 2.0

examples/express/client.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
'use strict';
2+
3+
// eslint-disable-next-line import/order
4+
const tracer = require('./tracer')('example-express-client');
5+
const api = require('@opentelemetry/api');
6+
const axios = require('axios').default;
7+
8+
function makeRequest() {
9+
const span = tracer.startSpan('client.makeRequest()', {
10+
parent: tracer.getCurrentSpan(),
11+
kind: api.SpanKind.CLIENT,
12+
});
13+
14+
tracer.withSpan(span, async () => {
15+
try {
16+
const res = await axios.get('http://localhost:8080/run_test');
17+
span.setStatus({ code: api.CanonicalCode.OK });
18+
console.log(res.statusText);
19+
} catch (e) {
20+
span.setStatus({ code: api.CanonicalCode.UNKNOWN, message: e.message });
21+
}
22+
span.end();
23+
console.log('Sleeping 5 seconds before shutdown to ensure all records are flushed.');
24+
setTimeout(() => { console.log('Completed.'); }, 5000);
25+
});
26+
}
27+
28+
makeRequest();

examples/express/images/jaeger.jpg

89.7 KB
Loading

examples/express/images/zipkin.jpg

102 KB
Loading

examples/express/package.json

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"name": "express-example",
3+
"private": true,
4+
"version": "0.4.0",
5+
"description": "Example of Express integration with OpenTelemetry",
6+
"main": "index.js",
7+
"scripts": {
8+
"zipkin:server": "cross-env EXPORTER=zipkin node ./server.js",
9+
"zipkin:client": "cross-env EXPORTER=zipkin node ./client.js",
10+
"jaeger:server": "cross-env EXPORTER=jaeger node ./server.js",
11+
"jaeger:client": "cross-env EXPORTER=jaeger node ./client.js"
12+
},
13+
"repository": {
14+
"type": "git",
15+
"url": "git+ssh://[email protected]/open-telemetry/opentelemetry-js.git"
16+
},
17+
"keywords": [
18+
"opentelemetry",
19+
"express",
20+
"tracing"
21+
],
22+
"engines": {
23+
"node": ">=8"
24+
},
25+
"author": "OpenTelemetry Authors",
26+
"license": "Apache-2.0",
27+
"bugs": {
28+
"url": "https://github.com/open-telemetry/opentelemetry-js/issues"
29+
},
30+
"dependencies": {
31+
"@opentelemetry/api": "^0.4.0",
32+
"@opentelemetry/exporter-jaeger": "^0.4.0",
33+
"@opentelemetry/exporter-zipkin": "^0.4.0",
34+
"@opentelemetry/node": "^0.4.0",
35+
"@opentelemetry/plugin-http": "^0.4.0",
36+
"@opentelemetry/plugin-express": "^0.4.0",
37+
"@opentelemetry/tracing": "^0.4.0",
38+
"axios": "^0.19.0",
39+
"express": "^4.17.1"
40+
},
41+
"homepage": "https://github.com/open-telemetry/opentelemetry-js#readme",
42+
"devDependencies": {
43+
"cross-env": "^6.0.0"
44+
}
45+
}

examples/express/server.js

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
'use strict';
2+
3+
// eslint-disable-next-line
4+
const tracer = require('./tracer')('example-express-server');
5+
6+
// Require in rest of modules
7+
const express = require('express');
8+
const axios = require('axios').default;
9+
10+
// Setup express
11+
const app = express();
12+
const PORT = 8080;
13+
14+
15+
const getCrudController = () => {
16+
const router = express.Router();
17+
const resources = [];
18+
router.get('/', (req, res) => res.send(resources));
19+
router.post('/', (req, res) => {
20+
resources.push(req.body);
21+
return res.status(201).send(req.body);
22+
});
23+
return router;
24+
};
25+
26+
const authMiddleware = (req, res, next) => {
27+
const { authorization } = req.headers;
28+
if (authorization && authorization.includes('secret_token')) {
29+
next();
30+
} else {
31+
res.sendStatus(401);
32+
}
33+
};
34+
35+
async function setupRoutes() {
36+
app.use(express.json());
37+
38+
app.get('/run_test', async (req, res) => {
39+
const createdCat = await axios.post(`http://localhost:${PORT}/cats`, {
40+
name: 'Tom',
41+
friends: [
42+
'Jerry',
43+
],
44+
}, {
45+
headers: {
46+
Authorization: 'secret_token',
47+
},
48+
});
49+
50+
return res.status(201).send(createdCat.data);
51+
});
52+
app.use('/cats', authMiddleware, getCrudController());
53+
}
54+
55+
setupRoutes().then(() => {
56+
app.listen(PORT);
57+
console.log(`Listening on http://localhost:${PORT}`);
58+
});

examples/express/tracer.js

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
'use strict';
2+
3+
const opentelemetry = require('@opentelemetry/api');
4+
const { NodeTracerProvider } = require('@opentelemetry/node');
5+
const { SimpleSpanProcessor } = require('@opentelemetry/tracing');
6+
const { JaegerExporter } = require('@opentelemetry/exporter-jaeger');
7+
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');
8+
9+
const EXPORTER = process.env.EXPORTER || '';
10+
11+
12+
module.exports = (serviceName) => {
13+
const provider = new NodeTracerProvider({
14+
plugins: {
15+
express: {
16+
enabled: true,
17+
path: '@opentelemetry/plugin-express',
18+
},
19+
http: {
20+
enabled: true,
21+
path: '@opentelemetry/plugin-http',
22+
},
23+
},
24+
});
25+
26+
let exporter;
27+
if (EXPORTER.toLowerCase().startsWith('z')) {
28+
exporter = new ZipkinExporter({
29+
serviceName,
30+
});
31+
} else {
32+
exporter = new JaegerExporter({
33+
serviceName,
34+
});
35+
}
36+
37+
provider.addSpanProcessor(new SimpleSpanProcessor(exporter));
38+
39+
// Initialize the OpenTelemetry APIs to use the NodeTracerProvider bindings
40+
opentelemetry.trace.initGlobalTracerProvider(provider);
41+
42+
return opentelemetry.trace.getTracer('express-example');
43+
};

packages/opentelemetry-plugin-express/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ const { NodeTracerProvider } = require('@opentelemetry/node');
4343
const provider = new NodeTracerProvider();
4444
```
4545

46+
See [examples/express](https://github.com/open-telemetry/opentelemetry-js/tree/master/examples/express) for a short example.
47+
4648
### Express Plugin Options
4749

4850
Express plugin has few options available to choose from. You can set the following:

0 commit comments

Comments
 (0)