Helios is now part of Snyk! Read the full announcement here.

SANDBOX

SECURITY

OBSERVABILITY

LANGUAGES

USE CASES

RESOURCES

Distributed tracing Node.js- OpenTelemetry-based monitoring

Written by


Subscribe to our Blog

Get the Latest News and Content

As the trend toward microservices-based architectures continues to gain momentum, it’s becoming increasingly clear that distributed tracing will be a crucial tool for monitoring and debugging these complex systems in the future.

When designing a microservices-based architecture, breaking extensive services into smaller, more manageable components is standard practice. Communication between these components becomes crucial, but finding the root cause can be challenging when issues arise.

Distributed tracing offers a solution by enabling the tracking of requests throughout the system, facilitating fast issue identification and resolution.

OpenTelemetry (OTel) is an industry-standard many development teams use to understand their software’s performance and behavior better. As an open-source project, it offers a vendor-agnostic standard for distributed tracing, metrics, and logging. OTel supports many programming languages, including Node.js, and makes it simple to instrument your code to collect and send telemetry data to various backends. With OTel, developers can easily generate, collect, and export telemetry to gain insights into their system’s inner workings.

Nodejs distributed tracing- This article will explore using OpenTelemetry to implement distributed tracing in a Node.js-based microservices application.

 

How to use OpenTelemetry instrumentation with nodejs

 

OpenTelemetry framework enables you to instrument your code and collect essential data, traces, and metrics to understand your application’s behavior better. In here let’s try to see how node.js app monitoring can be done.

OpenTelemetry nodejs provides an easy way to collect data and traces from your application.

To install OpenTelemetry for Node.js, you can follow these steps:

Step 1: Set up a new Node.js project Create a new directory for your project and navigate to it in the terminal. Then, initialize a new Node.js project by running the following command:

npm init -y

Step 2: Install required packages Next, install the necessary OpenTelemetry packages by running the following command:

npm install @opentelemetry/api 
npm install @opentelemetry/core
npm install @opentelemetry/node 
npm install @opentelemetry/tracing

Step 3: Create a new JavaScript file, for example, app.js, and add the following code:

const { NodeTracerProvider } = require('@opentelemetry/node');
const { SimpleSpanProcessor, ConsoleSpanExporter } = require('@opentelemetry/tracing');

// Create a new tracer provider
const tracerProvider = new NodeTracerProvider();

// Configure the tracer provider
tracerProvider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
tracerProvider.register();

// Start tracing
const tracer = tracerProvider.getTracer('example');

// Create a new span
const span = tracer.startSpan('example-span');

// Add attributes to the span
span.setAttribute('foo', 'bar');

// End the span
span.end();

// Shutdown the tracer provider
tracerProvider.shutdown();

Step 4: Run the code Save the changes to app.js and run the following command to execute the code:

node app.js

You should see the output in the console, including information about the created span.

{
 traceId: '2c43e0c82319ac329f071920099c556b',
 parentId: undefined,
 name: 'example-span',
 id: '5e42651016289074',
 kind: 0,
 timestamp: 1684338736636306,
 duration: 502,
 attributes: { foo: 'bar' },
 status: { code: 0 },
 events: []
}

This is a basic example that exports the span information to the console. In a real-world scenario, you would typically export the spans to a backend like Jaeger, Zipkin, or any other OpenTelemetry-compatible exporter.

That’s it! You have successfully installed and set up OpenTelemetry for Node.js. You can now proceed with instrumenting your application for distributed tracing and monitoring.

 

Exporting data to third-party tools

 

Exporting data to third-party tools is a crucial feature of OpenTelemetry, in general and specifically, in order to enable nodejs monitoring. It enables you to send the trace and metric data from OpenTelemetry to various backend systems like Jaeger, Zipkin, Prometheus, and more.

OpenTelemetry offers a range of exporters that you can utilize to export your data to these backend systems. To use an exporter, you must first configure it with the necessary options and then register it with your tracer or meter provider.

Here’s an example of how to configure and use the ZipKin exporter. You can follow the steps in ZipKin page for installation of ZipKin locally. Once you installed and run it properly you can access it from http://localhost:9411/ as below screen.

Configuring Zipkin exporter

To export OpenTelemetry traces to Zipkin, you’ll need to use the @opentelemetry/exporter-zipkin package. Follow the steps below to install the package and modify the previous code to export traces to Zipkin:

Step 1: Install the required package Run the following command to install the @opentelemetry/exporter-zipkin package:

npm install --save @opentelemetry/exporter-zipkin

Step 2: Update the code Replace the existing code in app.js with the following updated code

const { NodeTracerProvider } = require('@opentelemetry/node');
const { SimpleSpanProcessor } = require('@opentelemetry/tracing');
const { ZipkinExporter } = require('@opentelemetry/exporter-zipkin');

// Create a new tracer provider
const tracerProvider = new NodeTracerProvider();

// Configure the tracer provider
const exporter = new ZipkinExporter({
  serviceName: 'app', // Replace with your service name
  url: 'http://localhost:9411/api/v2/spans' // Replace with your Zipkin server URL
});
tracerProvider.addSpanProcessor(new SimpleSpanProcessor(exporter));
tracerProvider.register();

// Start tracing
const tracer = tracerProvider.getTracer('example');

// Create a new span
const span = tracer.startSpan('example-span');

// Add attributes to the span
span.setAttribute('service.name', 'app');
span.setAttribute('foo', 'bar');

// End the span
span.end();

// Gracefully shutdown the tracer provider
tracerProvider.shutdown().then(() => {
  console.log('Tracer provider shutdown successfully.');
}).catch((err) => {
  console.log('Error shutting down tracer provider:', err);
});
Step 3: Run the code Save the changes to app.js and run the following command to execute the code:
node app.js

The code will now export traces to your Zipkin server. You can access the Zipkin UI at the specified URL to view the traces. Once you run the above successfully, you can access that from ZipKin as shown in the below screens. Apart from the exporters provided by OpenTelemetry, there are also community-contributed exporters that you can utilize. You can find a list of these exporters in the OpenTelemetry registry.

 

Actionable observability for node.js- The missing element

 

When it comes to actionable observability in Node.js applications, there is one critical element that is often overlooked: enriching your observability data with contextual information. This contextual information can provide valuable insights and make your observability data more actionable. Here are some techniques to enhance actionable observability in your Node.js application: Instrumentation with tags and labels:

When instrumenting your code with OpenTelemetry or other observability tools, make use of tags or labels to attach contextual information to your metrics, logs, and traces. Tags can include details such as user ID, request ID, operation type, or any other relevant metadata that can aid in troubleshooting or understanding the behavior of your application.

Error and exception context: When capturing errors and exceptions in your Node.js application, ensure that you include relevant contextual information. Along with the error message and stack trace, consider adding additional data like the current user, request information, or specific parameters related to the error. This additional context can greatly help in identifying the root cause and providing actionable insights.

Custom metrics and business-specific instrumentation: Don’t limit your observability to just basic system metrics. Consider instrumenting custom metrics that align with your specific business logic. These metrics can provide insights into application-specific behaviors, such as transaction counts, user actions, or performance of critical functions. By capturing and analyzing these metrics, you can gain actionable insights into your application’s performance and behavior.

 

Distributed tracing and request context propagation:

 

If your Node.js application is part of a distributed system, utilize distributed tracing to capture end-to-end traces across different services. Ensure that you propagate the request context, including trace IDs and other relevant information, throughout the entire request flow. This allows you to correlate and analyze traces across multiple services, enabling better visibility into the overall system behavior and identifying bottlenecks or performance issues.

Alerting and anomaly detection: Set up intelligent alerting and anomaly detection based on your observability data. Define meaningful thresholds and rules for metrics, logs, and traces that can indicate abnormal behavior or potential issues.

This proactive monitoring approach allows you to identify and take action on potential problems before they impact your application’s performance or user experience. Integration with incident management and collaboration tools: Integrate your observability tools with incident management and collaboration platforms. This integration enables seamless communication and collaboration among teams when responding to incidents.

When an issue is detected, you can automatically create an incident ticket, notify the relevant team members, and provide them with the necessary observability data to quickly diagnose and resolve the problem.

By incorporating all these mentioned practices, you can enhance the actionable observability of your Node.js application. The enriched context and insights derived from observability data will empower you to make informed decisions, identify and resolve issues faster, and ultimately improve the overall performance and reliability of your application.

 

End-to-end trace-based observability for Node.js

 

In order to easily implement distributed tracing and to gain the needed visualization with data inishgts, you may want to work with an E2E tool. Helios is a trace-based observability dev tool, based on OTel, that offers an end-to-end tracing solution for microservices and specifically, for Nodejs. You can find the installation guide here.

The solution is designed to help engineering teams debug issues, optimize performance, and improve reliability across distributed environments. Here are some use cases for distributed tracing in Node.js with tools such as Helios:

End-to-end visibility: A complete and comprehensive view of distributed systems, including all the services and resources involved in processing a request. This makes it easier to understand how requests flow through the system and pinpoint the issues’ root causes quickly.

Real-time performance monitoring: Real-time performance metrics, such as response times and error rates, for all the services in the system, allows you to proactively monitor performance and identify potential issues before they impact your users.

Collaboration and communication: A collaborative environment enables teams to troubleshoot issues and optimize performance. Teams can share trace data, metrics, and logs and can communicate and coordinate their efforts.

Automation and integrations: Automation and integration capabilities help to automate common tasks, such as alerting and remediation. For instance, Helios integrates with popular tools and platforms, such as Kubernetes, and AWS, to provide a seamless workflow for distributed tracing.

Ease of use: Developer experience is key. A simple configuration process that can be completed in minutes is critical. It provides a clean and intuitive interface that makes navigating and exploring trace data easy and offers a wide range of visualization tools to help teams understand their system.

Overall, advanced approaches as described can benefit teams working with distributed systems in Node.js. By providing end-to-end visibility, real-time performance monitoring, collaboration and communication tools, automation and integrations, and ease of use. It helps teams with debugging nodejs, troubleshooting issues, optimizing performance, and improving reliability across their systems. Conclusion

E2E distributed tracing leveraging OpenTelemetry with the full context in a single trace
An example for an E2E trace from the Helios Sandbox, providing the full context for the error that occurred in this deposit flow.

 

Conclusion

 

In conclusion, distributed tracing is critical to building and maintaining complex systems in Node.js. Using tools like OpenTelemetry, teams can easily instrument their code, export data to third-party nodejs debugging tools, and achieve actionable observability. Advanced tools offer an end-to-end tracing solution for microservices and Node.js that provides real-time monitoring, automation and integrations, collaboration and communication as well as ease of use. By leveraging these tools and best practices, teams can troubleshoot issues, optimize performance, and improve reliability across their systems, ensuring a high-quality user experience.

Subscribe to our Blog

Get the Latest News and Content

About Helios

Helios is an applied observability platform that produces actionable security and monitoring insights. We apply our deep runtime data collection capabilities to help Sec, Dev, and Ops teams understand the actual application risk posture, prioritize vulnerabilities, shorten troubleshooting time, and reduce MTTR.

The Author

Helios
Helios

Helios is an applied observability platform that produces actionable security and monitoring insights. We apply our deep runtime data collection capabilities to help Sec, Dev, and Ops teams understand the actual application risk posture, prioritize vulnerabilities, shorten troubleshooting time, and reduce MTTR.

Related Content

Challenges of existing SCA tools
Challenges with Traditional SCA Tools
Application security testing tools are designed to ensure that applications are put through rigorous security assessments to identify security flaws within...
Read More
Banner for blog post - Scaling microservices - Challenges, best practices and tools
The Challenges of Collecting Runtime Data
Collecting data in real-time plays a crucial role in securing, monitoring, and troubleshooting applications. This real-time data, often referred to as...
Read More
Helios Runtime for Appsec
Helios Runtime for AppSec: The missing link in application security
Modern development teams increasingly rely on open-source packages to rapidly build and deploy applications. In fact, most, if not all applications consist...
Read More