feat: add OpenTracing example (#581)

* feat: add OpenTracing example

* fix: review comments

- Combine `Tracer` and `.init` to one line
- Use `setTimeout` to be consistent with other example
- Remove unused dependency
- Add missing keywords
- Update README
- Add missing `"use strict";`

* fix: review comments

- Update README
- Separate shim to another file

* fix: remove unnecessary file
This commit is contained in:
Even 2019-12-18 01:52:08 +01:00 committed by Mayur Kale
parent 4b25d4a26f
commit af5a364efd
8 changed files with 256 additions and 0 deletions

View File

@ -0,0 +1,77 @@
# Overview
OpenTracing shim allows existing OpenTracing instrumentation to report to OpenTelemetry.
This is a simple example that demonstrates how existing OpenTracing instrumentation can be integrated with OpenTelemetry.
The example shows key aspects of tracing such as
- Root Span (on client)
- Child Span from a remote parent (on server)
- Span Tag
- Span Log
- Make a shim between OpenTracing and OpenTelemetry tracers
## Installation
```sh
# from this directory
$ npm install
```
## Run the Application
### Zipkin
- Setup [Zipkin Tracing UI](https://zipkin.io/pages/quickstart.html)
- Run the server
```sh
# from this directory
$ npm run zipkin:server
```
- Run the client
```sh
# from this directory
$ npm run zipkin:client
```
- Check trace
`zipkin:client` should output the `traceId` in the terminal.
Go to Zipkin with your browser [http://localhost:9411/zipkin/traces/(your-trace-id)]() (e.g http://localhost:9411/zipkin/traces/4815c3d576d930189725f1f1d1bdfcc6)
<p align="center"><img src="./images/zipkin-ui.png?raw=true"/></p>
### Jaeger
- Setup [Jaeger Tracing UI](https://www.jaegertracing.io/docs/latest/getting-started/#all-in-one)
- Run the server
```sh
# from this directory
$ npm run jaeger:server
```
- Run the client
```sh
# from this directory
$ npm run jaeger:client
```
- Check trace
`jaeger:client` should output the `traceId` in the terminal.
Go to Jaeger with your browser [http://localhost:16686/trace/(your-trace-id)]() (e.g http://localhost:16686/trace/4815c3d576d930189725f1f1d1bdfcc6)
<p align="center"><img src="images/jaeger-ui.png?raw=true"/></p>
## Useful links
- For more information on OpenTelemetry, visit: <https://opentelemetry.io/>
- For more information on OpenTelemetry for Node.js, visit: <https://github.com/open-telemetry/opentelemetry-js/tree/master/packages/opentelemetry-node>
- For more information on OpenTracing, visit: <https://opentracing.io/>
## LICENSE
Apache License 2.0

View File

@ -0,0 +1,45 @@
"use strict";
const http = require("http");
const opentracing = require("opentracing");
const shim = require("./shim").shim("http_client_service");
opentracing.initGlobalTracer(shim);
const tracer = opentracing.globalTracer();
makeRequest();
async function makeRequest() {
const span = tracer.startSpan("make_request");
const headers = {};
tracer.inject(span, opentracing.FORMAT_HTTP_HEADERS, headers);
http
.get(
{
host: "localhost",
port: 3000,
path: "/",
headers
},
resp => {
let data = "";
resp.on("data", chunk => {
data += chunk;
});
resp.on("end", async () => {
console.log(JSON.parse(data));
span.finish();
console.log("Sleeping 5 seconds before shutdown to ensure all records are flushed.");
setTimeout(() => { console.log("Completed."); }, 5000);
});
}
)
.on("error", err => {
console.log("Error: " + err.message);
});
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

View File

@ -0,0 +1,42 @@
{
"name": "opentracing-shim",
"private": true,
"version": "0.2.0",
"description": "Example of using @opentelemetry/shim-opentracing in Node.js",
"main": "index.js",
"scripts": {
"zipkin:client": "cross-env EXPORTER=zipkin node ./client.js",
"zipkin:server": "cross-env EXPORTER=zipkin node ./server.js",
"jaeger:client": "cross-env EXPORTER=jaeger node ./client.js",
"jaeger:server": "cross-env EXPORTER=jaeger node ./server.js"
},
"repository": {
"type": "git",
"url": "git+ssh://git@github.com/open-telemetry/opentelemetry-js.git"
},
"keywords": [
"opentelemetry",
"http",
"tracing",
"opentracing"
],
"engines": {
"node": ">=8"
},
"author": "OpenTelemetry Authors",
"license": "Apache-2.0",
"bugs": {
"url": "https://github.com/open-telemetry/opentelemetry-js/issues"
},
"dependencies": {
"@opentelemetry/exporter-jaeger": "^0.2.0",
"@opentelemetry/exporter-zipkin": "^0.2.0",
"@opentelemetry/node": "^0.2.0",
"@opentelemetry/shim-opentracing": "^0.2.0",
"opentracing": "^0.14.4"
},
"homepage": "https://github.com/open-telemetry/opentelemetry-js#readme",
"devDependencies": {
"cross-env": "^6.0.0"
}
}

View File

@ -0,0 +1,58 @@
"use strict";
const http = require("http");
const opentracing = require("opentracing");
const utils = require("./utils");
const shim = require("./shim").shim("http_server_service");
opentracing.initGlobalTracer(shim);
const tracer = opentracing.globalTracer();
startServer(3000);
function startServer(port) {
const server = http.createServer(handleRequest);
server.listen(port, err => {
if (err) throw err;
console.log(`Server is listening on ${port}`);
});
}
async function handleRequest(req, res) {
const parentSpan = tracer.extract(
opentracing.FORMAT_HTTP_HEADERS,
req.headers
);
const span = tracer.startSpan("handle_request", {
childOf: parentSpan
});
span.setTag("custom", "tag value");
span.setTag("alpha", "1000");
await doSomething(span);
res.writeHead(200, { "Content-Type": "application/json" });
res.write(
JSON.stringify({ status: "OK", traceId: span.context().toTraceId() })
);
res.end();
span.finish();
}
async function doSomething(parentSpan) {
const span = tracer.startSpan("do_something", { childOf: parentSpan });
span.setTag("alpha", "200");
span.setTag("beta", "50");
span.log({ state: "waiting" });
// deliberately sleeping to mock some action.
await utils.sleep(1000);
span.finish();
}

View File

@ -0,0 +1,27 @@
"use strict";
const { NodeTracer } = require("@opentelemetry/node");
const { SimpleSpanProcessor } = require("@opentelemetry/tracing");
const { JaegerExporter } = require("@opentelemetry/exporter-jaeger");
const { ZipkinExporter } = require("@opentelemetry/exporter-zipkin");
const { TracerShim } = require("@opentelemetry/shim-opentracing");
function shim(serviceName) {
const tracer = new NodeTracer();
tracer.addSpanProcessor(new SimpleSpanProcessor(getExporter(serviceName)));
return new TracerShim(tracer);
}
function getExporter(serviceName) {
const type = process.env.EXPORTER.toLowerCase() || "jaeger";
if (type.startsWith("z")) {
return new ZipkinExporter({ serviceName });
}
return new JaegerExporter({ serviceName, flushInterval: 100 });
}
exports.shim = shim;

View File

@ -0,0 +1,7 @@
"use strict";
async function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
exports.sleep = sleep;