[d24f17c] | 1 | # Diagnostics Channel Support
|
---|
| 2 |
|
---|
| 3 | Stability: Experimental.
|
---|
| 4 |
|
---|
| 5 | Undici supports the [`diagnostics_channel`](https://nodejs.org/api/diagnostics_channel.html) (currently available only on Node.js v16+).
|
---|
| 6 | It is the preferred way to instrument Undici and retrieve internal information.
|
---|
| 7 |
|
---|
| 8 | The channels available are the following.
|
---|
| 9 |
|
---|
| 10 | ## `undici:request:create`
|
---|
| 11 |
|
---|
| 12 | This message is published when a new outgoing request is created.
|
---|
| 13 |
|
---|
| 14 | ```js
|
---|
| 15 | import diagnosticsChannel from 'diagnostics_channel'
|
---|
| 16 |
|
---|
| 17 | diagnosticsChannel.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 |
|
---|
| 28 | Note: a request is only loosely completed to a given socket.
|
---|
| 29 |
|
---|
| 30 |
|
---|
| 31 | ## `undici:request:bodySent`
|
---|
| 32 |
|
---|
| 33 | ```js
|
---|
| 34 | import diagnosticsChannel from 'diagnostics_channel'
|
---|
| 35 |
|
---|
| 36 | diagnosticsChannel.channel('undici:request:bodySent').subscribe(({ request }) => {
|
---|
| 37 | // request is the same object undici:request:create
|
---|
| 38 | })
|
---|
| 39 | ```
|
---|
| 40 |
|
---|
| 41 | ## `undici:request:headers`
|
---|
| 42 |
|
---|
| 43 | This message is published after the response headers have been received, i.e. the response has been completed.
|
---|
| 44 |
|
---|
| 45 | ```js
|
---|
| 46 | import diagnosticsChannel from 'diagnostics_channel'
|
---|
| 47 |
|
---|
| 48 | diagnosticsChannel.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 |
|
---|
| 59 | This message is published after the response body and trailers have been received, i.e. the response has been completed.
|
---|
| 60 |
|
---|
| 61 | ```js
|
---|
| 62 | import diagnosticsChannel from 'diagnostics_channel'
|
---|
| 63 |
|
---|
| 64 | diagnosticsChannel.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 |
|
---|
| 74 | This message is published if the request is going to error, but it has not errored yet.
|
---|
| 75 |
|
---|
| 76 | ```js
|
---|
| 77 | import diagnosticsChannel from 'diagnostics_channel'
|
---|
| 78 |
|
---|
| 79 | diagnosticsChannel.channel('undici:request:error').subscribe(({ request, error }) => {
|
---|
| 80 | // request is the same object undici:request:create
|
---|
| 81 | })
|
---|
| 82 | ```
|
---|
| 83 |
|
---|
| 84 | ## `undici:client:sendHeaders`
|
---|
| 85 |
|
---|
| 86 | This 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
|
---|
| 91 | import diagnosticsChannel from 'diagnostics_channel'
|
---|
| 92 |
|
---|
| 93 | diagnosticsChannel.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 |
|
---|
| 101 | This message is published before creating a new connection for **any** request.
|
---|
| 102 | You can not assume that this event is related to any specific request.
|
---|
| 103 |
|
---|
| 104 | ```js
|
---|
| 105 | import diagnosticsChannel from 'diagnostics_channel'
|
---|
| 106 |
|
---|
| 107 | diagnosticsChannel.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 |
|
---|
| 115 | This message is published after a connection is established.
|
---|
| 116 |
|
---|
| 117 | ```js
|
---|
| 118 | import diagnosticsChannel from 'diagnostics_channel'
|
---|
| 119 |
|
---|
| 120 | diagnosticsChannel.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 |
|
---|
| 128 | This message is published if it did not succeed to create new connection
|
---|
| 129 |
|
---|
| 130 | ```js
|
---|
| 131 | import diagnosticsChannel from 'diagnostics_channel'
|
---|
| 132 |
|
---|
| 133 | diagnosticsChannel.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 |
|
---|
| 142 | This message is published after the client has successfully connected to a server.
|
---|
| 143 |
|
---|
| 144 | ```js
|
---|
| 145 | import diagnosticsChannel from 'diagnostics_channel'
|
---|
| 146 |
|
---|
| 147 | diagnosticsChannel.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 |
|
---|
| 156 | This message is published after the connection has closed.
|
---|
| 157 |
|
---|
| 158 | ```js
|
---|
| 159 | import diagnosticsChannel from 'diagnostics_channel'
|
---|
| 160 |
|
---|
| 161 | diagnosticsChannel.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 |
|
---|
| 170 | This message is published if the socket experiences an error.
|
---|
| 171 |
|
---|
| 172 | ```js
|
---|
| 173 | import diagnosticsChannel from 'diagnostics_channel'
|
---|
| 174 |
|
---|
| 175 | diagnosticsChannel.channel('undici:websocket:socket_error').subscribe((error) => {
|
---|
| 176 | console.log(error)
|
---|
| 177 | })
|
---|
| 178 | ```
|
---|
| 179 |
|
---|
| 180 | ## `undici:websocket:ping`
|
---|
| 181 |
|
---|
| 182 | This message is published after the client receives a ping frame, if the connection is not closing.
|
---|
| 183 |
|
---|
| 184 | ```js
|
---|
| 185 | import diagnosticsChannel from 'diagnostics_channel'
|
---|
| 186 |
|
---|
| 187 | diagnosticsChannel.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 |
|
---|
| 195 | This message is published after the client receives a pong frame.
|
---|
| 196 |
|
---|
| 197 | ```js
|
---|
| 198 | import diagnosticsChannel from 'diagnostics_channel'
|
---|
| 199 |
|
---|
| 200 | diagnosticsChannel.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 | ```
|
---|