• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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