'use strict' const diagnosticsChannel = require('node:diagnostics_channel') const util = require('node:util') const undiciDebugLog = util.debuglog('undici') const fetchDebuglog = util.debuglog('fetch') const websocketDebuglog = util.debuglog('websocket') const channels = { // Client beforeConnect: diagnosticsChannel.channel('undici:client:beforeConnect'), connected: diagnosticsChannel.channel('undici:client:connected'), connectError: diagnosticsChannel.channel('undici:client:connectError'), sendHeaders: diagnosticsChannel.channel('undici:client:sendHeaders'), // Request create: diagnosticsChannel.channel('undici:request:create'), bodySent: diagnosticsChannel.channel('undici:request:bodySent'), headers: diagnosticsChannel.channel('undici:request:headers'), trailers: diagnosticsChannel.channel('undici:request:trailers'), error: diagnosticsChannel.channel('undici:request:error'), // WebSocket open: diagnosticsChannel.channel('undici:websocket:open'), close: diagnosticsChannel.channel('undici:websocket:close'), socketError: diagnosticsChannel.channel('undici:websocket:socket_error'), ping: diagnosticsChannel.channel('undici:websocket:ping'), pong: diagnosticsChannel.channel('undici:websocket:pong') } let isTrackingClientEvents = false function trackClientEvents (debugLog = undiciDebugLog) { if (isTrackingClientEvents) { return } isTrackingClientEvents = true diagnosticsChannel.subscribe('undici:client:beforeConnect', evt => { const { connectParams: { version, protocol, port, host } } = evt debugLog( 'connecting to %s%s using %s%s', host, port ? `:${port}` : '', protocol, version ) }) diagnosticsChannel.subscribe('undici:client:connected', evt => { const { connectParams: { version, protocol, port, host } } = evt debugLog( 'connected to %s%s using %s%s', host, port ? `:${port}` : '', protocol, version ) }) diagnosticsChannel.subscribe('undici:client:connectError', evt => { const { connectParams: { version, protocol, port, host }, error } = evt debugLog( 'connection to %s%s using %s%s errored - %s', host, port ? `:${port}` : '', protocol, version, error.message ) }) diagnosticsChannel.subscribe('undici:client:sendHeaders', evt => { const { request: { method, path, origin } } = evt debugLog('sending request to %s %s/%s', method, origin, path) }) } let isTrackingRequestEvents = false function trackRequestEvents (debugLog = undiciDebugLog) { if (isTrackingRequestEvents) { return } isTrackingRequestEvents = true diagnosticsChannel.subscribe('undici:request:headers', evt => { const { request: { method, path, origin }, response: { statusCode } } = evt debugLog( 'received response to %s %s/%s - HTTP %d', method, origin, path, statusCode ) }) diagnosticsChannel.subscribe('undici:request:trailers', evt => { const { request: { method, path, origin } } = evt debugLog('trailers received from %s %s/%s', method, origin, path) }) diagnosticsChannel.subscribe('undici:request:error', evt => { const { request: { method, path, origin }, error } = evt debugLog( 'request to %s %s/%s errored - %s', method, origin, path, error.message ) }) } let isTrackingWebSocketEvents = false function trackWebSocketEvents (debugLog = websocketDebuglog) { if (isTrackingWebSocketEvents) { return } isTrackingWebSocketEvents = true diagnosticsChannel.subscribe('undici:websocket:open', evt => { const { address: { address, port } } = evt debugLog('connection opened %s%s', address, port ? `:${port}` : '') }) diagnosticsChannel.subscribe('undici:websocket:close', evt => { const { websocket, code, reason } = evt debugLog( 'closed connection to %s - %s %s', websocket.url, code, reason ) }) diagnosticsChannel.subscribe('undici:websocket:socket_error', err => { debugLog('connection errored - %s', err.message) }) diagnosticsChannel.subscribe('undici:websocket:ping', evt => { debugLog('ping received') }) diagnosticsChannel.subscribe('undici:websocket:pong', evt => { debugLog('pong received') }) } if (undiciDebugLog.enabled || fetchDebuglog.enabled) { trackClientEvents(fetchDebuglog.enabled ? fetchDebuglog : undiciDebugLog) trackRequestEvents(fetchDebuglog.enabled ? fetchDebuglog : undiciDebugLog) } if (websocketDebuglog.enabled) { trackClientEvents(undiciDebugLog.enabled ? undiciDebugLog : websocketDebuglog) trackWebSocketEvents(websocketDebuglog) } module.exports = { channels }