How to Use Node.js diagnostics_channel
This article provides a practical guide on how to use the
node:diagnostics_channel module in Node.js to publish and
subscribe to internal diagnostic events. You will learn how to create
channels, publish telemetry data, and consume those events to monitor
application performance and behavior without tightly coupling your
business logic to your observability tools.
The node:diagnostics_channel module is a built-in
Node.js API designed to facilitate the flow of diagnostic data. It
allows libraries and application code to publish data points—such as
database query times, HTTP request details, or custom application
states—that monitoring tools, loggers, and APM (Application Performance
Monitoring) agents can subscribe to.
Why Use diagnostics_channel?
Historically, integrating APM tools required monkey-patching core modules or third-party libraries. This module solves that problem by introducing a publish-subscribe (pub/sub) pattern directly into the Node.js runtime.
Key benefits include: * Decoupling: Publishers do not need to know who is subscribing to their data. * Performance: Channels are designed to be extremely lightweight when there are no active subscribers. * Standardization: It provides a unified way for library maintainers to expose diagnostic hooks.
Subscribing to a Channel
To consume diagnostic data, you subscribe to a specific named channel
using the diagnostics_channel module.
import diagnostics_channel from 'node:diagnostics_channel';
// Subscribe to a specific channel
diagnostics_channel.subscribe('my-app.database.query', (message, name) => {
console.log(`Received event from ${name}:`, message);
});The callback function receives two arguments: the
message object published by the channel, and the
name of the channel.
Publishing to a Channel
To publish data, you first need to acquire a channel by its unique
name, and then call the publish() method.
import diagnostics_channel from 'node:diagnostics_channel';
// Acquire the channel
const queryChannel = diagnostics_channel.channel('my-app.database.query');
// Publish data to the channel
if (queryChannel.hasSubscribers) {
queryChannel.publish({
query: 'SELECT * FROM users',
durationMs: 12,
timestamp: Date.now()
});
}Note: Checking channel.hasSubscribers before
publishing is a best practice. It prevents the unnecessary creation of
message objects and execution of measurement logic when no active
listeners exist, keeping overhead to a minimum.
Unsubscribing from a Channel
If you no longer need to listen to events, you should unsubscribe to prevent memory leaks.
import diagnostics_channel from 'node:diagnostics_channel';
function onMessage(message, name) {
console.log('Event received:', message);
}
// Subscribe
diagnostics_channel.subscribe('my-app.database.query', onMessage);
// Unsubscribe when done
diagnostics_channel.unsubscribe('my-app.database.query', onMessage);Channel Naming Best Practices
When creating channel names, use a namespace prefix (e.g.,
app.database.query or library.http.request) to
avoid name collisions with other packages or Node.js internal
channels.