Tracing Node.js application with OpenTelemetry & Jaeger UI

Selvaganesh
4 min readJan 16, 2022

In this tutorial I will demonstrate how to trace and instrument Node.js application with OpenTelemetry.

Why do we need tracing?

If you are running micro-service apps you able to capture the traces of request and show the information about the application like how request came and time taken to return the response also helps to analyze your service performance and behavior

We will instrument this application with OpenTelemetry’s Node.js client library to generate trace data and send it to an JaegerExporter Collector. The Collector will then export the trace data to Jaeger UI to visualize the time series chart.

Install JaegerUI

To run JaegerUI in local use below docker command.

docker run -d --name jaeger \
-e COLLECTOR_ZIPKIN_HOST_PORT=:9411 \
-p 5775:5775/udp \
-p 6831:6831/udp \
-p 6832:6832/udp \
-p 5778:5778 \
-p 16686:16686 \
-p 14250:14250 \
-p 14268:14268 \
-p 14269:14269 \
-p 9411:9411 \
jaegertracing/all-in-one:1.29

Go to http://localhost:16686/search to use Jaeger

Install OpenTelemetry Packages

Next step is to setup OpenTelemetry packages to our application.

npm install @opentelemetry/api  @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-collector @opentelemetry/exporter-jaeger @opentelemetry/instrumentatio @opentelemetry/plugin-express @opentelemetry/plugin-http @opentelemetry/propagator-ot-trace @opentelemetry/resources @opentelemetry/sdk-node @opentelemetry/sdk-trace-base @opentelemetry/sdk-trace-node @opentelemetry/semantic-conventions @opentelemetry/tracing --save-dev

Add the above packages to provide instrumentation of service requests across ExpressJS, http and the library modules used, we don’t need to add anything extra in our application code apart from adding a tracer.

Create tracer.js file to node application

A tracer.js file takes care of tracing setup and allows to capture the request with following snippet.

To push the trace to Jaeger provide your host with below url, Jaeger component exposes the metrics scraping endpoint on the admin port

http://localhost:14268/api/traces

The above file takes care of instantiating the trace provider and configuring it with a trace exporter of our choice. To send trace data we are using JaegerExporterCollector. To verify the trace data whether spans are collected use `ConsoleSpanExporter to print in console

Instrumentation setup

There are two ways to setup instrumentation automatic and manual, to instrument express traces we will use new HttpInstrumentation(),
new ExpressInstrumentation()

Please read about this module here

Include tracer to NodeJs application

const { init } = require('./tracer')
const api = require('@opentelemetry/api')
init('demo-node-service', 'development') // calling tracer with service name and environment to view in jaegerui

The service name will be used to filter our tracing logs in the UI

Consider the below application as existing micor-service we are calling tracing config here to initialize.

Lets run our service and call api `http://localhost:3000/hello` see the traced logs in JaegerUI,

JaegerUI: http://localhost:16686/search

We are able to see the tracing

As you expand the first tree we can see the custom message we send from the code can be viewed below

Even if the api has error those span also gets captured

Include the tracer in your micro-service application and invoke the api calls to view the complete traces, also invoking from one service to other service complete logs are instrumented automatically.

Conclusion

The instrumented application traces can used to analyse the backend performance also used to debug api success and failure easily with Jaeger UI

The same typescript version can be viewed here

--

--