Skip to content

Commit 9dad4b0

Browse files
danielleadamstheanarkh
authored andcommitted
lib: add diagnostics channel and perf hooks detail
Co-Authored-By: theanarkh <[email protected]> PR-URL: #43984 Backport-PR-URL: #44256 Reviewed-By: Matteo Collina [email protected] Reviewed-By: Mohammed Keyvanzadeh [email protected] Reviewed-By: Minwoo Jung [email protected]
1 parent 763a63c commit 9dad4b0

10 files changed

+136
-16
lines changed

doc/api/diagnostics_channel.md

+18
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,24 @@ Emitted when server receives a request.
425425

426426
Emitted when server sends a response.
427427

428+
`net.client.socket`
429+
430+
* `socket` {net.Socket}
431+
432+
Emitted when a new TCP or pipe client socket is created.
433+
434+
`net.server.socket`
435+
436+
* `socket` {net.Socket}
437+
438+
Emitted when a new TCP or pipe connection is received.
439+
440+
`udp.socket`
441+
442+
* `socket` {dgram.Socket}
443+
444+
Emitted when a new UDP socket is created.
445+
428446
[`'uncaughtException'`]: process.md#event-uncaughtexception
429447
[`channel.subscribe(onMessage)`]: #channelsubscribeonmessage
430448
[`diagnostics_channel.channel(name)`]: #diagnostics_channelchannelname

doc/api/perf_hooks.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -602,13 +602,15 @@ When `performanceEntry.type` is equal to `'dns'`, the
602602
additional information.
603603

604604
If `performanceEntry.name` is equal to `lookup`, the `detail`
605-
will contain the following properties: `hostname`, `family`, `hints`, `verbatim`.
605+
will contain the following properties: `hostname`, `family`, `hints`, `verbatim`,
606+
`addresses`.
606607

607608
If `performanceEntry.name` is equal to `lookupService`, the `detail` will
608-
contain the following properties: `host`, `port`.
609+
contain the following properties: `host`, `port`, `hostname`, `service`.
609610

610611
If `performanceEntry.name` is equal to `queryxxx` or `getHostByAddr`, the `detail` will
611-
contain the following properties: `host`, `ttl`.
612+
contain the following properties: `host`, `ttl`, `result`. The value of `result` is
613+
same as the result of `queryxxx` or `getHostByAddr`.
612614

613615
## Class: `PerformanceNodeTiming`
614616

lib/dgram.js

+8
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ const {
7474
SendWrap
7575
} = internalBinding('udp_wrap');
7676

77+
const dc = require('diagnostics_channel');
78+
const udpSocketChannel = dc.channel('udp.socket');
79+
7780
const BIND_STATE_UNBOUND = 0;
7881
const BIND_STATE_BINDING = 1;
7982
const BIND_STATE_BOUND = 2;
@@ -145,6 +148,11 @@ function Socket(type, listener) {
145148
this.once('close', () => signal.removeEventListener('abort', onAborted));
146149
}
147150
}
151+
if (udpSocketChannel.hasSubscribers) {
152+
udpSocketChannel.publish({
153+
socket: this,
154+
});
155+
}
148156
}
149157
ObjectSetPrototypeOf(Socket.prototype, EventEmitter.prototype);
150158
ObjectSetPrototypeOf(Socket, EventEmitter);

lib/dns.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ function onlookup(err, addresses) {
110110
}
111111
this.callback(null, addresses[0], this.family || isIP(addresses[0]));
112112
if (this[kPerfHooksDnsLookupContext] && hasObserver('dns')) {
113-
stopPerf(this, kPerfHooksDnsLookupContext);
113+
stopPerf(this, kPerfHooksDnsLookupContext, { detail: { addresses } });
114114
}
115115
}
116116

@@ -131,7 +131,7 @@ function onlookupall(err, addresses) {
131131

132132
this.callback(null, addresses);
133133
if (this[kPerfHooksDnsLookupContext] && hasObserver('dns')) {
134-
stopPerf(this, kPerfHooksDnsLookupContext);
134+
stopPerf(this, kPerfHooksDnsLookupContext, { detail: { addresses } });
135135
}
136136
}
137137

@@ -227,7 +227,7 @@ function onlookupservice(err, hostname, service) {
227227

228228
this.callback(null, hostname, service);
229229
if (this[kPerfHooksDnsLookupServiceContext] && hasObserver('dns')) {
230-
stopPerf(this, kPerfHooksDnsLookupServiceContext);
230+
stopPerf(this, kPerfHooksDnsLookupServiceContext, { detail: { hostname, service } });
231231
}
232232
}
233233

@@ -280,7 +280,7 @@ function onresolve(err, result, ttls) {
280280
else {
281281
this.callback(null, result);
282282
if (this[kPerfHooksDnsLookupResolveContext] && hasObserver('dns')) {
283-
stopPerf(this, kPerfHooksDnsLookupResolveContext);
283+
stopPerf(this, kPerfHooksDnsLookupResolveContext, { detail: { result } });
284284
}
285285
}
286286
}

lib/internal/dns/promises.js

+4-4
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ function onlookup(err, addresses) {
8686
const family = this.family || isIP(addresses[0]);
8787
this.resolve({ address: addresses[0], family });
8888
if (this[kPerfHooksDnsLookupContext] && hasObserver('dns')) {
89-
stopPerf(this, kPerfHooksDnsLookupContext);
89+
stopPerf(this, kPerfHooksDnsLookupContext, { detail: { addresses } });
9090
}
9191
}
9292

@@ -109,7 +109,7 @@ function onlookupall(err, addresses) {
109109

110110
this.resolve(addresses);
111111
if (this[kPerfHooksDnsLookupContext] && hasObserver('dns')) {
112-
stopPerf(this, kPerfHooksDnsLookupContext);
112+
stopPerf(this, kPerfHooksDnsLookupContext, { detail: { addresses } });
113113
}
114114
}
115115

@@ -191,7 +191,7 @@ function onlookupservice(err, hostname, service) {
191191

192192
this.resolve({ hostname, service });
193193
if (this[kPerfHooksDnsLookupServiceContext] && hasObserver('dns')) {
194-
stopPerf(this, kPerfHooksDnsLookupServiceContext);
194+
stopPerf(this, kPerfHooksDnsLookupServiceContext, { detail: { hostname, service } });
195195
}
196196
}
197197

@@ -247,7 +247,7 @@ function onresolve(err, result, ttls) {
247247

248248
this.resolve(result);
249249
if (this[kPerfHooksDnsLookupResolveContext] && hasObserver('dns')) {
250-
stopPerf(this, kPerfHooksDnsLookupResolveContext);
250+
stopPerf(this, kPerfHooksDnsLookupResolveContext, { detail: { result } });
251251
}
252252
}
253253

lib/net.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ const isWindows = process.platform === 'win32';
133133
const noop = () => {};
134134

135135
const kPerfHooksNetConnectContext = Symbol('kPerfHooksNetConnectContext');
136+
137+
const dc = require('diagnostics_channel');
138+
const netClientSocketChannel = dc.channel('net.client.socket');
139+
const netServerSocketChannel = dc.channel('net.server.socket');
140+
136141
const {
137142
hasObserver,
138143
startPerf,
@@ -204,7 +209,11 @@ function connect(...args) {
204209
const options = normalized[0];
205210
debug('createConnection', normalized);
206211
const socket = new Socket(options);
207-
212+
if (netClientSocketChannel.hasSubscribers) {
213+
netClientSocketChannel.publish({
214+
socket,
215+
});
216+
}
208217
if (options.timeout) {
209218
socket.setTimeout(options.timeout);
210219
}
@@ -1714,6 +1723,11 @@ function onconnection(err, clientHandle) {
17141723

17151724
DTRACE_NET_SERVER_CONNECTION(socket);
17161725
self.emit('connection', socket);
1726+
if (netServerSocketChannel.hasSubscribers) {
1727+
netServerSocketChannel.publish({
1728+
socket,
1729+
});
1730+
}
17171731
}
17181732

17191733
/**

test/parallel/test-bootstrap-modules.js

+1
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ const expectedModules = new Set([
160160
'NativeModule v8',
161161
'NativeModule internal/v8/startup_snapshot',
162162
'NativeModule vm',
163+
'NativeModule diagnostics_channel',
163164
]);
164165

165166
if (!common.isMainThread) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const net = require('net');
5+
const dc = require('diagnostics_channel');
6+
7+
const netClientSocketChannel = dc.channel('net.client.socket');
8+
const netServerSocketChannel = dc.channel('net.server.socket');
9+
10+
const isNetSocket = (socket) => socket instanceof net.Socket;
11+
12+
netClientSocketChannel.subscribe(common.mustCall(({ socket }) => {
13+
assert.strictEqual(isNetSocket(socket), true);
14+
}));
15+
16+
netServerSocketChannel.subscribe(common.mustCall(({ socket }) => {
17+
assert.strictEqual(isNetSocket(socket), true);
18+
}));
19+
20+
const server = net.createServer(common.mustCall((socket) => {
21+
socket.destroy();
22+
server.close();
23+
}));
24+
25+
server.listen(() => {
26+
const { port } = server.address();
27+
net.connect(port);
28+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const dgram = require('dgram');
5+
const dc = require('diagnostics_channel');
6+
7+
const udpSocketChannel = dc.channel('udp.socket');
8+
9+
const isUDPSocket = (socket) => socket instanceof dgram.Socket;
10+
11+
udpSocketChannel.subscribe(common.mustCall(({ socket }) => {
12+
assert.strictEqual(isUDPSocket(socket), true);
13+
}));
14+
const socket = dgram.createSocket('udp4');
15+
socket.close();

test/parallel/test-dns-perf_hooks.js

+38-4
Original file line numberDiff line numberDiff line change
@@ -6,21 +6,55 @@ const dns = require('dns');
66
const { PerformanceObserver } = require('perf_hooks');
77

88
const entries = [];
9-
const obs = new PerformanceObserver(common.mustCallAtLeast((items) => {
9+
const obs = new PerformanceObserver((items) => {
1010
entries.push(...items.getEntries());
11-
}));
11+
});
1212

1313
obs.observe({ type: 'dns' });
1414

15-
dns.lookup('localhost', () => {});
15+
let count = 0;
16+
17+
function inc() {
18+
count++;
19+
}
20+
21+
// If DNS resolution fails, skip it
22+
// https://github.com/nodejs/node/issues/44003
23+
dns.lookup('localhost', common.mustCall((err) => { !err && inc(); }));
24+
dns.lookupService('127.0.0.1', 80, common.mustCall((err) => { !err && inc(); }));
25+
dns.resolveAny('localhost', common.mustCall((err) => { !err && inc(); }));
26+
27+
dns.promises.lookup('localhost').then(inc).catch(() => {});
28+
dns.promises.lookupService('127.0.0.1', 80).then(inc).catch(() => {});
29+
dns.promises.resolveAny('localhost').then(inc).catch(() => {});
1630

1731
process.on('exit', () => {
18-
assert.strictEqual(entries.length, 1);
32+
assert.strictEqual(entries.length, count);
1933
entries.forEach((entry) => {
2034
assert.strictEqual(!!entry.name, true);
2135
assert.strictEqual(entry.entryType, 'dns');
2236
assert.strictEqual(typeof entry.startTime, 'number');
2337
assert.strictEqual(typeof entry.duration, 'number');
2438
assert.strictEqual(typeof entry.detail, 'object');
39+
switch (entry.name) {
40+
case 'lookup':
41+
assert.strictEqual(typeof entry.detail.hostname, 'string');
42+
assert.strictEqual(typeof entry.detail.family, 'number');
43+
assert.strictEqual(typeof entry.detail.hints, 'number');
44+
assert.strictEqual(typeof entry.detail.verbatim, 'boolean');
45+
assert.strictEqual(Array.isArray(entry.detail.addresses), true);
46+
break;
47+
case 'lookupService':
48+
assert.strictEqual(typeof entry.detail.host, 'string');
49+
assert.strictEqual(typeof entry.detail.port, 'number');
50+
assert.strictEqual(typeof entry.detail.hostname, 'string');
51+
assert.strictEqual(typeof entry.detail.service, 'string');
52+
break;
53+
case 'queryAny':
54+
assert.strictEqual(typeof entry.detail.host, 'string');
55+
assert.strictEqual(typeof entry.detail.ttl, 'boolean');
56+
assert.strictEqual(Array.isArray(entry.detail.result), true);
57+
break;
58+
}
2559
});
2660
});

0 commit comments

Comments
 (0)