1# Diagnostics Channel 2 3<!-- YAML 4added: 5 - v15.1.0 6 - v14.17.0 7changes: 8 - version: v18.13.0 9 pr-url: https://github.com/nodejs/node/pull/45290 10 description: diagnostics_channel is now Stable. 11--> 12 13<!--introduced_in=v15.1.0--> 14 15> Stability: 2 - Stable 16 17<!-- source_link=lib/diagnostics_channel.js --> 18 19The `node:diagnostics_channel` module provides an API to create named channels 20to report arbitrary message data for diagnostics purposes. 21 22It can be accessed using: 23 24```mjs 25import diagnostics_channel from 'node:diagnostics_channel'; 26``` 27 28```cjs 29const diagnostics_channel = require('node:diagnostics_channel'); 30``` 31 32It is intended that a module writer wanting to report diagnostics messages 33will create one or many top-level channels to report messages through. 34Channels may also be acquired at runtime but it is not encouraged 35due to the additional overhead of doing so. Channels may be exported for 36convenience, but as long as the name is known it can be acquired anywhere. 37 38If you intend for your module to produce diagnostics data for others to 39consume it is recommended that you include documentation of what named 40channels are used along with the shape of the message data. Channel names 41should generally include the module name to avoid collisions with data from 42other modules. 43 44## Public API 45 46### Overview 47 48Following is a simple overview of the public API. 49 50```mjs 51import diagnostics_channel from 'node:diagnostics_channel'; 52 53// Get a reusable channel object 54const channel = diagnostics_channel.channel('my-channel'); 55 56function onMessage(message, name) { 57 // Received data 58} 59 60// Subscribe to the channel 61diagnostics_channel.subscribe('my-channel', onMessage); 62 63// Check if the channel has an active subscriber 64if (channel.hasSubscribers) { 65 // Publish data to the channel 66 channel.publish({ 67 some: 'data', 68 }); 69} 70 71// Unsubscribe from the channel 72diagnostics_channel.unsubscribe('my-channel', onMessage); 73``` 74 75```cjs 76const diagnostics_channel = require('node:diagnostics_channel'); 77 78// Get a reusable channel object 79const channel = diagnostics_channel.channel('my-channel'); 80 81function onMessage(message, name) { 82 // Received data 83} 84 85// Subscribe to the channel 86diagnostics_channel.subscribe('my-channel', onMessage); 87 88// Check if the channel has an active subscriber 89if (channel.hasSubscribers) { 90 // Publish data to the channel 91 channel.publish({ 92 some: 'data', 93 }); 94} 95 96// Unsubscribe from the channel 97diagnostics_channel.unsubscribe('my-channel', onMessage); 98``` 99 100#### `diagnostics_channel.hasSubscribers(name)` 101 102<!-- YAML 103added: 104 - v15.1.0 105 - v14.17.0 106--> 107 108* `name` {string|symbol} The channel name 109* Returns: {boolean} If there are active subscribers 110 111Check if there are active subscribers to the named channel. This is helpful if 112the message you want to send might be expensive to prepare. 113 114This API is optional but helpful when trying to publish messages from very 115performance-sensitive code. 116 117```mjs 118import diagnostics_channel from 'node:diagnostics_channel'; 119 120if (diagnostics_channel.hasSubscribers('my-channel')) { 121 // There are subscribers, prepare and publish message 122} 123``` 124 125```cjs 126const diagnostics_channel = require('node:diagnostics_channel'); 127 128if (diagnostics_channel.hasSubscribers('my-channel')) { 129 // There are subscribers, prepare and publish message 130} 131``` 132 133#### `diagnostics_channel.channel(name)` 134 135<!-- YAML 136added: 137 - v15.1.0 138 - v14.17.0 139--> 140 141* `name` {string|symbol} The channel name 142* Returns: {Channel} The named channel object 143 144This is the primary entry-point for anyone wanting to publish to a named 145channel. It produces a channel object which is optimized to reduce overhead at 146publish time as much as possible. 147 148```mjs 149import diagnostics_channel from 'node:diagnostics_channel'; 150 151const channel = diagnostics_channel.channel('my-channel'); 152``` 153 154```cjs 155const diagnostics_channel = require('node:diagnostics_channel'); 156 157const channel = diagnostics_channel.channel('my-channel'); 158``` 159 160#### `diagnostics_channel.subscribe(name, onMessage)` 161 162<!-- YAML 163added: 164 - v18.7.0 165--> 166 167* `name` {string|symbol} The channel name 168* `onMessage` {Function} The handler to receive channel messages 169 * `message` {any} The message data 170 * `name` {string|symbol} The name of the channel 171 172Register a message handler to subscribe to this channel. This message handler 173will be run synchronously whenever a message is published to the channel. Any 174errors thrown in the message handler will trigger an [`'uncaughtException'`][]. 175 176```mjs 177import diagnostics_channel from 'node:diagnostics_channel'; 178 179diagnostics_channel.subscribe('my-channel', (message, name) => { 180 // Received data 181}); 182``` 183 184```cjs 185const diagnostics_channel = require('node:diagnostics_channel'); 186 187diagnostics_channel.subscribe('my-channel', (message, name) => { 188 // Received data 189}); 190``` 191 192#### `diagnostics_channel.unsubscribe(name, onMessage)` 193 194<!-- YAML 195added: 196 - v18.7.0 197--> 198 199* `name` {string|symbol} The channel name 200* `onMessage` {Function} The previous subscribed handler to remove 201* Returns: {boolean} `true` if the handler was found, `false` otherwise. 202 203Remove a message handler previously registered to this channel with 204[`diagnostics_channel.subscribe(name, onMessage)`][]. 205 206```mjs 207import diagnostics_channel from 'node:diagnostics_channel'; 208 209function onMessage(message, name) { 210 // Received data 211} 212 213diagnostics_channel.subscribe('my-channel', onMessage); 214 215diagnostics_channel.unsubscribe('my-channel', onMessage); 216``` 217 218```cjs 219const diagnostics_channel = require('node:diagnostics_channel'); 220 221function onMessage(message, name) { 222 // Received data 223} 224 225diagnostics_channel.subscribe('my-channel', onMessage); 226 227diagnostics_channel.unsubscribe('my-channel', onMessage); 228``` 229 230### Class: `Channel` 231 232<!-- YAML 233added: 234 - v15.1.0 235 - v14.17.0 236--> 237 238The class `Channel` represents an individual named channel within the data 239pipeline. It is used to track subscribers and to publish messages when there 240are subscribers present. It exists as a separate object to avoid channel 241lookups at publish time, enabling very fast publish speeds and allowing 242for heavy use while incurring very minimal cost. Channels are created with 243[`diagnostics_channel.channel(name)`][], constructing a channel directly 244with `new Channel(name)` is not supported. 245 246#### `channel.hasSubscribers` 247 248<!-- YAML 249added: 250 - v15.1.0 251 - v14.17.0 252--> 253 254* Returns: {boolean} If there are active subscribers 255 256Check if there are active subscribers to this channel. This is helpful if 257the message you want to send might be expensive to prepare. 258 259This API is optional but helpful when trying to publish messages from very 260performance-sensitive code. 261 262```mjs 263import diagnostics_channel from 'node:diagnostics_channel'; 264 265const channel = diagnostics_channel.channel('my-channel'); 266 267if (channel.hasSubscribers) { 268 // There are subscribers, prepare and publish message 269} 270``` 271 272```cjs 273const diagnostics_channel = require('node:diagnostics_channel'); 274 275const channel = diagnostics_channel.channel('my-channel'); 276 277if (channel.hasSubscribers) { 278 // There are subscribers, prepare and publish message 279} 280``` 281 282#### `channel.publish(message)` 283 284<!-- YAML 285added: 286 - v15.1.0 287 - v14.17.0 288--> 289 290* `message` {any} The message to send to the channel subscribers 291 292Publish a message to any subscribers to the channel. This will trigger 293message handlers synchronously so they will execute within the same context. 294 295```mjs 296import diagnostics_channel from 'node:diagnostics_channel'; 297 298const channel = diagnostics_channel.channel('my-channel'); 299 300channel.publish({ 301 some: 'message', 302}); 303``` 304 305```cjs 306const diagnostics_channel = require('node:diagnostics_channel'); 307 308const channel = diagnostics_channel.channel('my-channel'); 309 310channel.publish({ 311 some: 'message', 312}); 313``` 314 315#### `channel.subscribe(onMessage)` 316 317<!-- YAML 318added: 319 - v15.1.0 320 - v14.17.0 321deprecated: v18.7.0 322--> 323 324> Stability: 0 - Deprecated: Use [`diagnostics_channel.subscribe(name, onMessage)`][] 325 326* `onMessage` {Function} The handler to receive channel messages 327 * `message` {any} The message data 328 * `name` {string|symbol} The name of the channel 329 330Register a message handler to subscribe to this channel. This message handler 331will be run synchronously whenever a message is published to the channel. Any 332errors thrown in the message handler will trigger an [`'uncaughtException'`][]. 333 334```mjs 335import diagnostics_channel from 'node:diagnostics_channel'; 336 337const channel = diagnostics_channel.channel('my-channel'); 338 339channel.subscribe((message, name) => { 340 // Received data 341}); 342``` 343 344```cjs 345const diagnostics_channel = require('node:diagnostics_channel'); 346 347const channel = diagnostics_channel.channel('my-channel'); 348 349channel.subscribe((message, name) => { 350 // Received data 351}); 352``` 353 354#### `channel.unsubscribe(onMessage)` 355 356<!-- YAML 357added: 358 - v15.1.0 359 - v14.17.0 360deprecated: v18.7.0 361changes: 362 - version: 363 - v17.1.0 364 - v16.14.0 365 - v14.19.0 366 pr-url: https://github.com/nodejs/node/pull/40433 367 description: Added return value. Added to channels without subscribers. 368--> 369 370> Stability: 0 - Deprecated: Use [`diagnostics_channel.unsubscribe(name, onMessage)`][] 371 372* `onMessage` {Function} The previous subscribed handler to remove 373* Returns: {boolean} `true` if the handler was found, `false` otherwise. 374 375Remove a message handler previously registered to this channel with 376[`channel.subscribe(onMessage)`][]. 377 378```mjs 379import diagnostics_channel from 'node:diagnostics_channel'; 380 381const channel = diagnostics_channel.channel('my-channel'); 382 383function onMessage(message, name) { 384 // Received data 385} 386 387channel.subscribe(onMessage); 388 389channel.unsubscribe(onMessage); 390``` 391 392```cjs 393const diagnostics_channel = require('node:diagnostics_channel'); 394 395const channel = diagnostics_channel.channel('my-channel'); 396 397function onMessage(message, name) { 398 // Received data 399} 400 401channel.subscribe(onMessage); 402 403channel.unsubscribe(onMessage); 404``` 405 406### Built-in Channels 407 408> Stability: 1 - Experimental 409 410While the diagnostics\_channel API is now considered stable, the built-in 411channels currently available are not. Each channel must be declared stable 412independently. 413 414#### HTTP 415 416`http.client.request.start` 417 418* `request` {http.ClientRequest} 419 420Emitted when client starts a request. 421 422`http.client.response.finish` 423 424* `request` {http.ClientRequest} 425* `response` {http.IncomingMessage} 426 427Emitted when client receives a response. 428 429`http.server.request.start` 430 431* `request` {http.IncomingMessage} 432* `response` {http.ServerResponse} 433* `socket` {net.Socket} 434* `server` {http.Server} 435 436Emitted when server receives a request. 437 438`http.server.response.finish` 439 440* `request` {http.IncomingMessage} 441* `response` {http.ServerResponse} 442* `socket` {net.Socket} 443* `server` {http.Server} 444 445Emitted when server sends a response. 446 447`net.client.socket` 448 449* `socket` {net.Socket} 450 451Emitted when a new TCP or pipe client socket is created. 452 453`net.server.socket` 454 455* `socket` {net.Socket} 456 457Emitted when a new TCP or pipe connection is received. 458 459`udp.socket` 460 461* `socket` {dgram.Socket} 462 463Emitted when a new UDP socket is created. 464 465[`'uncaughtException'`]: process.md#event-uncaughtexception 466[`channel.subscribe(onMessage)`]: #channelsubscribeonmessage 467[`diagnostics_channel.channel(name)`]: #diagnostics_channelchannelname 468[`diagnostics_channel.subscribe(name, onMessage)`]: #diagnostics_channelsubscribename-onmessage 469[`diagnostics_channel.unsubscribe(name, onMessage)`]: #diagnostics_channelunsubscribename-onmessage 470