1# Diagnostics Channel Support 2 3Stability: Experimental. 4 5Undici supports the [`diagnostics_channel`](https://nodejs.org/api/diagnostics_channel.html) (currently available only on Node.js v16+). 6It is the preferred way to instrument Undici and retrieve internal information. 7 8The channels available are the following. 9 10## `undici:request:create` 11 12This message is published when a new outgoing request is created. 13 14```js 15import diagnosticsChannel from 'diagnostics_channel' 16 17diagnosticsChannel.channel('undici:request:create').subscribe(({ request }) => { 18 console.log('origin', request.origin) 19 console.log('completed', request.completed) 20 console.log('method', request.method) 21 console.log('path', request.path) 22 console.log('headers') // raw text, e.g: 'bar: bar\r\n' 23 request.addHeader('hello', 'world') 24 console.log('headers', request.headers) // e.g. 'bar: bar\r\nhello: world\r\n' 25}) 26``` 27 28Note: a request is only loosely completed to a given socket. 29 30 31## `undici:request:bodySent` 32 33```js 34import diagnosticsChannel from 'diagnostics_channel' 35 36diagnosticsChannel.channel('undici:request:bodySent').subscribe(({ request }) => { 37 // request is the same object undici:request:create 38}) 39``` 40 41## `undici:request:headers` 42 43This message is published after the response headers have been received, i.e. the response has been completed. 44 45```js 46import diagnosticsChannel from 'diagnostics_channel' 47 48diagnosticsChannel.channel('undici:request:headers').subscribe(({ request, response }) => { 49 // request is the same object undici:request:create 50 console.log('statusCode', response.statusCode) 51 console.log(response.statusText) 52 // response.headers are buffers. 53 console.log(response.headers.map((x) => x.toString())) 54}) 55``` 56 57## `undici:request:trailers` 58 59This message is published after the response body and trailers have been received, i.e. the response has been completed. 60 61```js 62import diagnosticsChannel from 'diagnostics_channel' 63 64diagnosticsChannel.channel('undici:request:trailers').subscribe(({ request, trailers }) => { 65 // request is the same object undici:request:create 66 console.log('completed', request.completed) 67 // trailers are buffers. 68 console.log(trailers.map((x) => x.toString())) 69}) 70``` 71 72## `undici:request:error` 73 74This message is published if the request is going to error, but it has not errored yet. 75 76```js 77import diagnosticsChannel from 'diagnostics_channel' 78 79diagnosticsChannel.channel('undici:request:error').subscribe(({ request, error }) => { 80 // request is the same object undici:request:create 81}) 82``` 83 84## `undici:client:sendHeaders` 85 86This message is published right before the first byte of the request is written to the socket. 87 88*Note*: It will publish the exact headers that will be sent to the server in raw format. 89 90```js 91import diagnosticsChannel from 'diagnostics_channel' 92 93diagnosticsChannel.channel('undici:client:sendHeaders').subscribe(({ request, headers, socket }) => { 94 // request is the same object undici:request:create 95 console.log(`Full headers list ${headers.split('\r\n')}`); 96}) 97``` 98 99## `undici:client:beforeConnect` 100 101This message is published before creating a new connection for **any** request. 102You can not assume that this event is related to any specific request. 103 104```js 105import diagnosticsChannel from 'diagnostics_channel' 106 107diagnosticsChannel.channel('undici:client:beforeConnect').subscribe(({ connectParams, connector }) => { 108 // const { host, hostname, protocol, port, servername } = connectParams 109 // connector is a function that creates the socket 110}) 111``` 112 113## `undici:client:connected` 114 115This message is published after a connection is established. 116 117```js 118import diagnosticsChannel from 'diagnostics_channel' 119 120diagnosticsChannel.channel('undici:client:connected').subscribe(({ socket, connectParams, connector }) => { 121 // const { host, hostname, protocol, port, servername } = connectParams 122 // connector is a function that creates the socket 123}) 124``` 125 126## `undici:client:connectError` 127 128This message is published if it did not succeed to create new connection 129 130```js 131import diagnosticsChannel from 'diagnostics_channel' 132 133diagnosticsChannel.channel('undici:client:connectError').subscribe(({ error, socket, connectParams, connector }) => { 134 // const { host, hostname, protocol, port, servername } = connectParams 135 // connector is a function that creates the socket 136 console.log(`Connect failed with ${error.message}`) 137}) 138``` 139 140## `undici:websocket:open` 141 142This message is published after the client has successfully connected to a server. 143 144```js 145import diagnosticsChannel from 'diagnostics_channel' 146 147diagnosticsChannel.channel('undici:websocket:open').subscribe(({ address, protocol, extensions }) => { 148 console.log(address) // address, family, and port 149 console.log(protocol) // negotiated subprotocols 150 console.log(extensions) // negotiated extensions 151}) 152``` 153 154## `undici:websocket:close` 155 156This message is published after the connection has closed. 157 158```js 159import diagnosticsChannel from 'diagnostics_channel' 160 161diagnosticsChannel.channel('undici:websocket:close').subscribe(({ websocket, code, reason }) => { 162 console.log(websocket) // the WebSocket object 163 console.log(code) // the closing status code 164 console.log(reason) // the closing reason 165}) 166``` 167 168## `undici:websocket:socket_error` 169 170This message is published if the socket experiences an error. 171 172```js 173import diagnosticsChannel from 'diagnostics_channel' 174 175diagnosticsChannel.channel('undici:websocket:socket_error').subscribe((error) => { 176 console.log(error) 177}) 178``` 179 180## `undici:websocket:ping` 181 182This message is published after the client receives a ping frame, if the connection is not closing. 183 184```js 185import diagnosticsChannel from 'diagnostics_channel' 186 187diagnosticsChannel.channel('undici:websocket:ping').subscribe(({ payload }) => { 188 // a Buffer or undefined, containing the optional application data of the frame 189 console.log(payload) 190}) 191``` 192 193## `undici:websocket:pong` 194 195This message is published after the client receives a pong frame. 196 197```js 198import diagnosticsChannel from 'diagnostics_channel' 199 200diagnosticsChannel.channel('undici:websocket:pong').subscribe(({ payload }) => { 201 // a Buffer or undefined, containing the optional application data of the frame 202 console.log(payload) 203}) 204``` 205