Prerequisites:
Node.js
application
Opencensus
library
Zipkin Exporter
and local Zipkin service
app.js:
const tracing = require('@opencensus/nodejs');
const zipkin = require('@opencensus/exporter-zipkin');
const ZIPKIN_ENDPOINT = process.env.ZIPKIN_ENDPOINT || "http://localhost:9411";
const options = {
url: `${ZIPKIN_ENDPOINT}/api/v2/spans`,
serviceName: 'MyApplication'
}
const exporter = new zipkin.ZipkinTraceExporter(options);
tracing.start({'exporter': exporter});
...
app.use(..)
...
package.json:
"dependencies": {
"@opencensus/exporter-zipkin" : "0.0.19",
"@opencensus/nodejs" : "0.0.19"
...
Zipkin server started locally with command:
docker run -d -p 9411:9411 openzipkin/zipkin
after triggering /service1
Zipkin Ui displays 2 spans for 2 different requests:
first /service1
incoming request that is configured in Node.js routers
second /external_service_2
is subsequent call to external service
Problem
The problem is that after triggering /service1
:
1. Zipkin UI displays 2 spans with same name MyApplication
(see image),
but expected 2 different span names
2. As far Zipkin UI displays 2 spans with same name,
service dependencies page contains one Service only(see image)
I have tested this with the official opencensus-node example at github.
Zipkin UI displays 2 spans with same name MyApplication(see image), but expected 2 different span names
Just to be clear, MyApplication
is the service name you set in your app.js, and the span names are those which you selected on the image /service1
, /service1
, /external_service_2
.
I think this is the intended behavior, you got one service (MyApplication
), a root span (/service1
) and a child span (/external_service_2
).
If you got multiple services connected to the same Zipkin server then you'll have multiple names for the services.
From the Zipkin's documentation:
Span
A set of Annotations and BinaryAnnotations that correspond to a particular RPC. Spans contain identifying information such as traceId, spanId, parentId, and RPC name.
Trace
A set of spans that share a single root span. Traces are built by collecting all Spans that share a traceId. The spans are then arranged in a tree based on spanId and parentId thus providing an overview of the path a request takes through the system.
As far Zipkin UI displays 2 spans with same name, service dependencies page contains one Service only(see image)
Again, this is the intended behavior, since you got only one service and the external request you made goes through it.
If you mean the framed names on the first image, at the top it shows only the root span you clicked on the previous screen. However, you can write custom span names after a little change in your code.
From the tracing documentation (with your code):
const options = {
url: `${ZIPKIN_ENDPOINT}/api/v2/spans`,
serviceName: 'MyApplication'
}
const tracer = tracing.start({samplingRate: 1}).tracer;
tracer.registerSpanEventListener(new zipkin.ZipkinTraceExporter(options));
Now you can use tracer.startRootSpan
, I used it in the express sample with a request:
tracer.startRootSpan({name: 'main'}, rootSpan => {
rp('http://localhost:3000/sample').then(data => {
res.send(data);
rootSpan.end();
}, err => {
console.error(`${err.message}`);
rootSpan.end();
});
});
A span must be closed.
For more information, check the test file of the tracer.