Naming Pattern Registry for Diagnostics Channels
Untracing provides a unified naming registry and standard to ensure that library authors and observability tools speak the same language when using Diagnostics Channels and Tracing Channels.
Note
This document is a work in progress and not finalized yet.
Node.js Diagnostics Channels (also supported in Bun, Cloudflare Workers and Deno) offer two ways to emit telemetry:
1. Diagnostic Channel (Atomic)
A single, named event stream from the Channel class. Useful for specific, point-in-time notifications(e.g., undici:request:bodySent).
- Naming: Arbitrary, and can be chosen freely (e.g.,
undici:request:bodySent) - Untracing Goal: Standardize these to follow the same prefixing as Tracing Channels.
2. Tracing Channel (Lifecycle)
A collection of five related Channel instances representing the execution lifecycle of a single traceable action.
When you create a TracingChannel with the name my-op, Node.js automatically manages:
tracing:my-op:starttracing:my-op:endtracing:my-op:asyncStarttracing:my-op:asyncEndtracing:my-op:error
The prefix (tracing:) and the eventType suffix (:start, :end, etc.) are hardcoded by the Node runtime.
To allow Application Performance Monitoring (APM) tools (OpenTelemetry, etc.) to automatically track operations across different libraries,
all Channel instances (standalone or as part of TracingChannel) should follow this strict pattern:
tracing:{namespace}.{operation}:{eventType}
tracing:{namespace}:{operation}:{eventType}
Both . (dot) and : (colon) are accepted as the delimiter between namespace and operation. Node.js itself uses both conventions:
- Dot: Node.js core built-in channels (e.g.,
http.client.request,net.server.socket,module.require) - Colon: undici (e.g.,
undici:request:create,undici:client:connected)
Libraries should pick one delimiter and use it consistently. The dot style reads as a hierarchy (h3.request), while the colon style reads as a scoped label (mysql2:query). Both are valid.
Pattern Breakdown
- Namespace: The package or module name (e.g.,
unstorage,h3,undici). - Operation: The entity being acted upon (e.g.,
request,file,query). Use full nouns, not abbreviations. - Event Type: The lifecycle hook (e.g.,
start,end).
Examples:
import diagnostics_channel from 'node:diagnostics_channel';
// Diagnostic Channel
const standaloneChannel = diagnostics_channel.channel('tracing:{namespace}.{operation}:{eventType}');
// Tracing Channel (Dot delimiter)
const tracingChannel = diagnostics_channel.tracingChannel('{namespace}.{operation}');
// Tracing Channel (Colon delimiter)
const tracingChannel = diagnostics_channel.tracingChannel('{namespace}:{operation}');Some libraries and frameworks are already using Diagnostics Channels or Tracing Channels. Here are a few examples:
- Node.js built-in Diagnostics Channels (dot delimiter:
http.client.request,net.server.socket) - undici Diagnostics Channels (colon delimiter:
undici:request:create) - Fastify Diagnostics Channel Hooks
- Tracing Channels in srvx: Example, PR
- mysql2 Tracing Channels (colon delimiter:
mysql2:query)