Tracing
- Requirements
- Run it locally
- How does it work?
- Using the Tracer
- Configure Sampler
- Configure Exporter
- Create a span
- Create a child span
- End the spans
- References
Run it locally
- Clone the example repository:
git clone https://github.com/opencensus-otherwork/opencensus-quickstarts
- Change to the example directory:
cd opencensus-quickstarts/node.js
- Install dependencies:
npm install
- Download Zipkin:
curl -sSL https://zipkin.io/quickstart.sh | bash -s
- Start Zipkin:
java -jar zipkin.jar
- Run the code:
node tracing-to-zipkin/tracingtozipkin.js
- Navigate to Zipkin Web UI: http://localhost:9411
- Click Find Traces, and you should see a trace.
- Click into that, and you should see the details.
How does it work?
// 1. Get the global singleton Tracer object
// 2. Configure 100% sample rate, otherwise, few traces will be sampled.
const tracer = tracing.start({samplingRate: 1}).tracer;
// 3. Configure exporter to export traces to Zipkin.
tracer.registerSpanEventListener(new zipkin.ZipkinTraceExporter({
url: 'http://localhost:9411/api/v2/spans',
serviceName: 'node.js-quickstart'
}));
function main() {
// 4. Create a scoped span, a scoped span will automatically end when closed.
tracer.startRootSpan({name: 'main'}, rootSpan => {
for (let i = 0; i < 10; i++) {
doWork(i);
}
// 6b. End the spans
rootSpan.end();
});
}
const tracing = require('@opencensus/nodejs');
const zipkin = require('@opencensus/exporter-zipkin');
const stdin = process.openStdin();
// 1. Get the global singleton Tracer object
// 2. Configure 100% sample rate, otherwise, few traces will be sampled.
const tracer = tracing.start({samplingRate: 1}).tracer;
// 3. Configure exporter to export traces to Zipkin.
tracer.registerSpanEventListener(new zipkin.ZipkinTraceExporter({
url: 'http://localhost:9411/api/v2/spans',
serviceName: 'node.js-quickstart'
}));
function main() {
// 4. Create a span. A span must be closed.
tracer.startRootSpan({name: 'main'}, rootSpan => {
for (let i = 0; i < 10; i++) {
doWork();
}
rootSpan.end();
});
}
function doWork() {
// 5. Start another span. In this example, the main method already started a span,
// so that'll be the parent span, and this will be a child span.
const span = tracer.startChildSpan('doWork');
span.start();
console.log('doing busy work');
for (let i = 0; i <= 40000000; i++) {} // short delay
// 6. Annotate our span to capture metadata about our operation
span.addAnnotation('invoking doWork')
for (let i = 0; i <= 20000000; i++) {} // short delay
span.end();
}
main();
Using the Tracer
To start a trace, you first need to get a reference to the Tracer
(3). It can be retrieved as a global singleton.
// 1. Get the global singleton Tracer object
// 2. Configure 100% sample rate, otherwise, few traces will be sampled.
const tracer = tracing.start({samplingRate: 1}).tracer;
Configure Sampler
Configure 100% sample rate, otherwise, few traces will be sampled.
// 1. Get the global singleton Tracer object
// 2. Configure 100% sample rate, otherwise, few traces will be sampled.
const tracer = tracing.start({samplingRate: 1}).tracer;
Configure Exporter
OpenCensus can export traces to different distributed tracing stores (such as Zipkin, Jeager, Stackdriver Trace). In (3), we configure OpenCensus to export to Zipkin, which is listening on localhost
port 9411
, and all of the traces from this program will be associated with a service name node.js-quickstart
.
// 3. Configure exporter to export traces to Zipkin.
tracer.registerSpanEventListener(new zipkin.ZipkinTraceExporter({
url: 'http://localhost:9411/api/v2/spans',
serviceName: 'node.js-quickstart'
}));
Create a span
To create a span in a trace, we used the Tracer
to start a new span (4). A span must be closed in order to mark the end of the span.
// 4. Create a scoped span, a scoped span will automatically end when closed.
tracer.startRootSpan({name: 'main'}, rootSpan => {
for (let i = 0; i < 10; i++) {
doWork(i);
}
rootSpan.end();
});
Create a child span
The main
method calls doWork
a number of times. Each invocation also generates a child span. Take a look at the doWork
method.
function doWork() {
// 5. Start another span. In this example, the main method already started a span,
// so that'll be the parent span, and this will be a child span.
const span = tracer.startChildSpan('doWork');
span.start();
console.log('doing busy work');
for (let i = 0; i <= 40000000; i++) {} // short delay
// 6. Annotate our span to capture metadata about our operation
span.addAnnotation('invoking doWork')
for (let i = 0; i <= 20000000; i++) {} // short delay
span.end();
}
End the spans
We must end the spans so they becomes available for exporting.
// 6a. End the spans
span.end();
// 6b. End the spans
rootSpan.end();
Create an Annotation
An annotation tells a descriptive story in text of an event that occurred during a span’s lifetime.
// 6. Annotate our span to capture metadata about our operation
span.addAnnotation('invoking doWork')
References
Resource | URL |
---|---|
Zipkin project | https://zipkin.io/ |
Setting up Zipkin | Zipkin Codelab |
Node.js exporters | Node.js exporters |