11cb0ef41Sopenharmony_ci# Diagnostics Channel Support
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ciStability: Experimental.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ciUndici supports the [`diagnostics_channel`](https://nodejs.org/api/diagnostics_channel.html) (currently available only on Node.js v16+).
61cb0ef41Sopenharmony_ciIt is the preferred way to instrument Undici and retrieve internal information.
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ciThe channels available are the following.
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci## `undici:request:create`
111cb0ef41Sopenharmony_ci
121cb0ef41Sopenharmony_ciThis message is published when a new outgoing request is created.
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_ci```js
151cb0ef41Sopenharmony_ciimport diagnosticsChannel from 'diagnostics_channel'
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_cidiagnosticsChannel.channel('undici:request:create').subscribe(({ request }) => {
181cb0ef41Sopenharmony_ci  console.log('origin', request.origin)
191cb0ef41Sopenharmony_ci  console.log('completed', request.completed)
201cb0ef41Sopenharmony_ci  console.log('method', request.method)
211cb0ef41Sopenharmony_ci  console.log('path', request.path)
221cb0ef41Sopenharmony_ci  console.log('headers') // raw text, e.g: 'bar: bar\r\n'
231cb0ef41Sopenharmony_ci  request.addHeader('hello', 'world')
241cb0ef41Sopenharmony_ci  console.log('headers', request.headers) // e.g. 'bar: bar\r\nhello: world\r\n'
251cb0ef41Sopenharmony_ci})
261cb0ef41Sopenharmony_ci```
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ciNote: a request is only loosely completed to a given socket.
291cb0ef41Sopenharmony_ci
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci## `undici:request:bodySent`
321cb0ef41Sopenharmony_ci
331cb0ef41Sopenharmony_ci```js
341cb0ef41Sopenharmony_ciimport diagnosticsChannel from 'diagnostics_channel'
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_cidiagnosticsChannel.channel('undici:request:bodySent').subscribe(({ request }) => {
371cb0ef41Sopenharmony_ci  // request is the same object undici:request:create
381cb0ef41Sopenharmony_ci})
391cb0ef41Sopenharmony_ci```
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci## `undici:request:headers`
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ciThis message is published after the response headers have been received, i.e. the response has been completed.
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci```js
461cb0ef41Sopenharmony_ciimport diagnosticsChannel from 'diagnostics_channel'
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_cidiagnosticsChannel.channel('undici:request:headers').subscribe(({ request, response }) => {
491cb0ef41Sopenharmony_ci  // request is the same object undici:request:create
501cb0ef41Sopenharmony_ci  console.log('statusCode', response.statusCode)
511cb0ef41Sopenharmony_ci  console.log(response.statusText)
521cb0ef41Sopenharmony_ci  // response.headers are buffers.
531cb0ef41Sopenharmony_ci  console.log(response.headers.map((x) => x.toString()))
541cb0ef41Sopenharmony_ci})
551cb0ef41Sopenharmony_ci```
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci## `undici:request:trailers`
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_ciThis message is published after the response body and trailers have been received, i.e. the response has been completed.
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci```js
621cb0ef41Sopenharmony_ciimport diagnosticsChannel from 'diagnostics_channel'
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_cidiagnosticsChannel.channel('undici:request:trailers').subscribe(({ request, trailers }) => {
651cb0ef41Sopenharmony_ci  // request is the same object undici:request:create
661cb0ef41Sopenharmony_ci  console.log('completed', request.completed)
671cb0ef41Sopenharmony_ci  // trailers are buffers.
681cb0ef41Sopenharmony_ci  console.log(trailers.map((x) => x.toString()))
691cb0ef41Sopenharmony_ci})
701cb0ef41Sopenharmony_ci```
711cb0ef41Sopenharmony_ci
721cb0ef41Sopenharmony_ci## `undici:request:error`
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ciThis message is published if the request is going to error, but it has not errored yet.
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci```js
771cb0ef41Sopenharmony_ciimport diagnosticsChannel from 'diagnostics_channel'
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_cidiagnosticsChannel.channel('undici:request:error').subscribe(({ request, error }) => {
801cb0ef41Sopenharmony_ci  // request is the same object undici:request:create
811cb0ef41Sopenharmony_ci})
821cb0ef41Sopenharmony_ci```
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci## `undici:client:sendHeaders`
851cb0ef41Sopenharmony_ci
861cb0ef41Sopenharmony_ciThis message is published right before the first byte of the request is written to the socket.
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci*Note*: It will publish the exact headers that will be sent to the server in raw format.
891cb0ef41Sopenharmony_ci
901cb0ef41Sopenharmony_ci```js
911cb0ef41Sopenharmony_ciimport diagnosticsChannel from 'diagnostics_channel'
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_cidiagnosticsChannel.channel('undici:client:sendHeaders').subscribe(({ request, headers, socket }) => {
941cb0ef41Sopenharmony_ci  // request is the same object undici:request:create
951cb0ef41Sopenharmony_ci  console.log(`Full headers list ${headers.split('\r\n')}`);
961cb0ef41Sopenharmony_ci})
971cb0ef41Sopenharmony_ci```
981cb0ef41Sopenharmony_ci
991cb0ef41Sopenharmony_ci## `undici:client:beforeConnect`
1001cb0ef41Sopenharmony_ci
1011cb0ef41Sopenharmony_ciThis message is published before creating a new connection for **any** request.
1021cb0ef41Sopenharmony_ciYou can not assume that this event is related to any specific request.
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci```js
1051cb0ef41Sopenharmony_ciimport diagnosticsChannel from 'diagnostics_channel'
1061cb0ef41Sopenharmony_ci
1071cb0ef41Sopenharmony_cidiagnosticsChannel.channel('undici:client:beforeConnect').subscribe(({ connectParams, connector }) => {
1081cb0ef41Sopenharmony_ci  // const { host, hostname, protocol, port, servername } = connectParams
1091cb0ef41Sopenharmony_ci  // connector is a function that creates the socket
1101cb0ef41Sopenharmony_ci})
1111cb0ef41Sopenharmony_ci```
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci## `undici:client:connected`
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ciThis message is published after a connection is established.
1161cb0ef41Sopenharmony_ci
1171cb0ef41Sopenharmony_ci```js
1181cb0ef41Sopenharmony_ciimport diagnosticsChannel from 'diagnostics_channel'
1191cb0ef41Sopenharmony_ci
1201cb0ef41Sopenharmony_cidiagnosticsChannel.channel('undici:client:connected').subscribe(({ socket, connectParams, connector }) => {
1211cb0ef41Sopenharmony_ci  // const { host, hostname, protocol, port, servername } = connectParams
1221cb0ef41Sopenharmony_ci // connector is a function that creates the socket
1231cb0ef41Sopenharmony_ci})
1241cb0ef41Sopenharmony_ci```
1251cb0ef41Sopenharmony_ci
1261cb0ef41Sopenharmony_ci## `undici:client:connectError`
1271cb0ef41Sopenharmony_ci
1281cb0ef41Sopenharmony_ciThis message is published if it did not succeed to create new connection
1291cb0ef41Sopenharmony_ci
1301cb0ef41Sopenharmony_ci```js
1311cb0ef41Sopenharmony_ciimport diagnosticsChannel from 'diagnostics_channel'
1321cb0ef41Sopenharmony_ci
1331cb0ef41Sopenharmony_cidiagnosticsChannel.channel('undici:client:connectError').subscribe(({ error, socket, connectParams, connector }) => {
1341cb0ef41Sopenharmony_ci  // const { host, hostname, protocol, port, servername } = connectParams
1351cb0ef41Sopenharmony_ci  // connector is a function that creates the socket
1361cb0ef41Sopenharmony_ci  console.log(`Connect failed with ${error.message}`)
1371cb0ef41Sopenharmony_ci})
1381cb0ef41Sopenharmony_ci```
1391cb0ef41Sopenharmony_ci
1401cb0ef41Sopenharmony_ci## `undici:websocket:open`
1411cb0ef41Sopenharmony_ci
1421cb0ef41Sopenharmony_ciThis message is published after the client has successfully connected to a server.
1431cb0ef41Sopenharmony_ci
1441cb0ef41Sopenharmony_ci```js
1451cb0ef41Sopenharmony_ciimport diagnosticsChannel from 'diagnostics_channel'
1461cb0ef41Sopenharmony_ci
1471cb0ef41Sopenharmony_cidiagnosticsChannel.channel('undici:websocket:open').subscribe(({ address, protocol, extensions }) => {
1481cb0ef41Sopenharmony_ci  console.log(address) // address, family, and port
1491cb0ef41Sopenharmony_ci  console.log(protocol) // negotiated subprotocols
1501cb0ef41Sopenharmony_ci  console.log(extensions) // negotiated extensions
1511cb0ef41Sopenharmony_ci})
1521cb0ef41Sopenharmony_ci```
1531cb0ef41Sopenharmony_ci
1541cb0ef41Sopenharmony_ci## `undici:websocket:close`
1551cb0ef41Sopenharmony_ci
1561cb0ef41Sopenharmony_ciThis message is published after the connection has closed.
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ci```js
1591cb0ef41Sopenharmony_ciimport diagnosticsChannel from 'diagnostics_channel'
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_cidiagnosticsChannel.channel('undici:websocket:close').subscribe(({ websocket, code, reason }) => {
1621cb0ef41Sopenharmony_ci  console.log(websocket) // the WebSocket object
1631cb0ef41Sopenharmony_ci  console.log(code) // the closing status code
1641cb0ef41Sopenharmony_ci  console.log(reason) // the closing reason
1651cb0ef41Sopenharmony_ci})
1661cb0ef41Sopenharmony_ci```
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci## `undici:websocket:socket_error`
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ciThis message is published if the socket experiences an error.
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_ci```js
1731cb0ef41Sopenharmony_ciimport diagnosticsChannel from 'diagnostics_channel'
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_cidiagnosticsChannel.channel('undici:websocket:socket_error').subscribe((error) => {
1761cb0ef41Sopenharmony_ci  console.log(error)
1771cb0ef41Sopenharmony_ci})
1781cb0ef41Sopenharmony_ci```
1791cb0ef41Sopenharmony_ci
1801cb0ef41Sopenharmony_ci## `undici:websocket:ping`
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ciThis message is published after the client receives a ping frame, if the connection is not closing.
1831cb0ef41Sopenharmony_ci
1841cb0ef41Sopenharmony_ci```js
1851cb0ef41Sopenharmony_ciimport diagnosticsChannel from 'diagnostics_channel'
1861cb0ef41Sopenharmony_ci
1871cb0ef41Sopenharmony_cidiagnosticsChannel.channel('undici:websocket:ping').subscribe(({ payload }) => {
1881cb0ef41Sopenharmony_ci  // a Buffer or undefined, containing the optional application data of the frame
1891cb0ef41Sopenharmony_ci  console.log(payload)
1901cb0ef41Sopenharmony_ci})
1911cb0ef41Sopenharmony_ci```
1921cb0ef41Sopenharmony_ci
1931cb0ef41Sopenharmony_ci## `undici:websocket:pong`
1941cb0ef41Sopenharmony_ci
1951cb0ef41Sopenharmony_ciThis message is published after the client receives a pong frame.
1961cb0ef41Sopenharmony_ci
1971cb0ef41Sopenharmony_ci```js
1981cb0ef41Sopenharmony_ciimport diagnosticsChannel from 'diagnostics_channel'
1991cb0ef41Sopenharmony_ci
2001cb0ef41Sopenharmony_cidiagnosticsChannel.channel('undici:websocket:pong').subscribe(({ payload }) => {
2011cb0ef41Sopenharmony_ci  // a Buffer or undefined, containing the optional application data of the frame
2021cb0ef41Sopenharmony_ci  console.log(payload)
2031cb0ef41Sopenharmony_ci})
2041cb0ef41Sopenharmony_ci```
205