Skip to content

Commit 1a44fbc

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 c270b9a commit 1a44fbc

10 files changed

+136
-16
lines changed

doc/api/diagnostics_channel.md

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

429429
Emitted when server sends a response.
430430

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

doc/api/perf_hooks.md

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

627627
If `performanceEntry.name` is equal to `lookup`, the `detail`
628-
will contain the following properties: `hostname`, `family`, `hints`, `verbatim`.
628+
will contain the following properties: `hostname`, `family`, `hints`, `verbatim`,
629+
`addresses`.
629630

630631
If `performanceEntry.name` is equal to `lookupService`, the `detail` will
631-
contain the following properties: `host`, `port`.
632+
contain the following properties: `host`, `port`, `hostname`, `service`.
632633

633634
If `performanceEntry.name` is equal to `queryxxx` or `getHostByAddr`, the `detail` will
634-
contain the following properties: `host`, `ttl`.
635+
contain the following properties: `host`, `ttl`, `result`. The value of `result` is
636+
same as the result of `queryxxx` or `getHostByAddr`.
635637

636638
## Class: `PerformanceNodeTiming`
637639

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
@@ -112,7 +112,7 @@ function onlookup(err, addresses) {
112112
}
113113
this.callback(null, addresses[0], this.family || isIP(addresses[0]));
114114
if (this[kPerfHooksDnsLookupContext] && hasObserver('dns')) {
115-
stopPerf(this, kPerfHooksDnsLookupContext);
115+
stopPerf(this, kPerfHooksDnsLookupContext, { detail: { addresses } });
116116
}
117117
}
118118

@@ -133,7 +133,7 @@ function onlookupall(err, addresses) {
133133

134134
this.callback(null, addresses);
135135
if (this[kPerfHooksDnsLookupContext] && hasObserver('dns')) {
136-
stopPerf(this, kPerfHooksDnsLookupContext);
136+
stopPerf(this, kPerfHooksDnsLookupContext, { detail: { addresses } });
137137
}
138138
}
139139

@@ -251,7 +251,7 @@ function onlookupservice(err, hostname, service) {
251251

252252
this.callback(null, hostname, service);
253253
if (this[kPerfHooksDnsLookupServiceContext] && hasObserver('dns')) {
254-
stopPerf(this, kPerfHooksDnsLookupServiceContext);
254+
stopPerf(this, kPerfHooksDnsLookupServiceContext, { detail: { hostname, service } });
255255
}
256256
}
257257

@@ -304,7 +304,7 @@ function onresolve(err, result, ttls) {
304304
else {
305305
this.callback(null, result);
306306
if (this[kPerfHooksDnsLookupResolveContext] && hasObserver('dns')) {
307-
stopPerf(this, kPerfHooksDnsLookupResolveContext);
307+
stopPerf(this, kPerfHooksDnsLookupResolveContext, { detail: { result } });
308308
}
309309
}
310310
}

lib/internal/dns/promises.js

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

@@ -112,7 +112,7 @@ function onlookupall(err, addresses) {
112112

113113
this.resolve(addresses);
114114
if (this[kPerfHooksDnsLookupContext] && hasObserver('dns')) {
115-
stopPerf(this, kPerfHooksDnsLookupContext);
115+
stopPerf(this, kPerfHooksDnsLookupContext, { detail: { addresses } });
116116
}
117117
}
118118

@@ -205,7 +205,7 @@ function onlookupservice(err, hostname, service) {
205205

206206
this.resolve({ hostname, service });
207207
if (this[kPerfHooksDnsLookupServiceContext] && hasObserver('dns')) {
208-
stopPerf(this, kPerfHooksDnsLookupServiceContext);
208+
stopPerf(this, kPerfHooksDnsLookupServiceContext, { detail: { hostname, service } });
209209
}
210210
}
211211

@@ -261,7 +261,7 @@ function onresolve(err, result, ttls) {
261261

262262
this.resolve(result);
263263
if (this[kPerfHooksDnsLookupResolveContext] && hasObserver('dns')) {
264-
stopPerf(this, kPerfHooksDnsLookupResolveContext);
264+
stopPerf(this, kPerfHooksDnsLookupResolveContext, { detail: { result } });
265265
}
266266
}
267267

lib/net.js

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

136136
const kPerfHooksNetConnectContext = Symbol('kPerfHooksNetConnectContext');
137+
138+
const dc = require('diagnostics_channel');
139+
const netClientSocketChannel = dc.channel('net.client.socket');
140+
const netServerSocketChannel = dc.channel('net.server.socket');
141+
137142
const {
138143
hasObserver,
139144
startPerf,
@@ -205,7 +210,11 @@ function connect(...args) {
205210
const options = normalized[0];
206211
debug('createConnection', normalized);
207212
const socket = new Socket(options);
208-
213+
if (netClientSocketChannel.hasSubscribers) {
214+
netClientSocketChannel.publish({
215+
socket,
216+
});
217+
}
209218
if (options.timeout) {
210219
socket.setTimeout(options.timeout);
211220
}
@@ -1747,6 +1756,11 @@ function onconnection(err, clientHandle) {
17471756

17481757
DTRACE_NET_SERVER_CONNECTION(socket);
17491758
self.emit('connection', socket);
1759+
if (netServerSocketChannel.hasSubscribers) {
1760+
netServerSocketChannel.publish({
1761+
socket,
1762+
});
1763+
}
17501764
}
17511765

17521766
/**

test/parallel/test-bootstrap-modules.js

+1
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ const expectedModules = new Set([
171171
'NativeModule v8',
172172
'NativeModule internal/v8/startup_snapshot',
173173
'NativeModule vm',
174+
'NativeModule diagnostics_channel',
174175
]);
175176

176177
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)