Skip to content

Commit b164a2e

Browse files
jasnellBethGriggs
authored andcommittedMar 9, 2020
console: add trace-events for time and count
Add the `node.console` trace event category to capture `console.count()`, `console.countReset()`, `console.time()`, `console.timeLog()`, and `console.timeEnd()` to the trace event log. PR-URL: #23703 Backport-PR-URL: #28840 Reviewed-By: Luigi Pinca <luigipinca@gmail.com> Reviewed-By: Richard Lau <riclau@uk.ibm.com>
1 parent 47046aa commit b164a2e

File tree

4 files changed

+78
-2
lines changed

4 files changed

+78
-2
lines changed
 

‎doc/api/tracing.md

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ The available categories are:
1818
The [`async_hooks`] events have a unique `asyncId` and a special `triggerId`
1919
`triggerAsyncId` property.
2020
* `node.bootstrap` - Enables capture of Node.js bootstrap milestones.
21+
* `node.console` - Enables capture of `console.time()` and `console.count()`
22+
output.
2123
* `node.fs.sync` - Enables capture of trace data for file system sync methods.
2224
* `node.perf` - Enables capture of [Performance API] measurements.
2325
* `node.perf.usertiming` - Enables capture of only Performance API User Timing

‎lib/console.js

+12
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
'use strict';
2323

24+
const { trace } = internalBinding('trace_events');
2425
const {
2526
isStackOverflowError,
2627
codes: {
@@ -37,6 +38,12 @@ const {
3738
} = util.types;
3839
const kCounts = Symbol('counts');
3940

41+
const kTraceConsoleCategory = 'node,node.console';
42+
const kTraceCount = 'C'.charCodeAt(0);
43+
const kTraceBegin = 'b'.charCodeAt(0);
44+
const kTraceEnd = 'e'.charCodeAt(0);
45+
const kTraceInstant = 'n'.charCodeAt(0);
46+
4047
const {
4148
keys: ObjectKeys,
4249
values: ObjectValues,
@@ -230,13 +237,15 @@ Console.prototype.dir = function dir(object, options) {
230237
Console.prototype.time = function time(label = 'default') {
231238
// Coerces everything other than Symbol to a string
232239
label = `${label}`;
240+
trace(kTraceBegin, kTraceConsoleCategory, `time::${label}`, 0);
233241
this._times.set(label, process.hrtime());
234242
};
235243

236244
Console.prototype.timeEnd = function timeEnd(label = 'default') {
237245
// Coerces everything other than Symbol to a string
238246
label = `${label}`;
239247
const hasWarned = timeLogImpl(this, 'timeEnd', label);
248+
trace(kTraceEnd, kTraceConsoleCategory, `time::${label}`, 0);
240249
if (!hasWarned) {
241250
this._times.delete(label);
242251
}
@@ -246,6 +255,7 @@ Console.prototype.timeLog = function timeLog(label, ...data) {
246255
// Coerces everything other than Symbol to a string
247256
label = `${label}`;
248257
timeLogImpl(this, 'timeLog', label, data);
258+
trace(kTraceInstant, kTraceConsoleCategory, `time::${label}`, 0);
249259
};
250260

251261
// Returns true if label was not found
@@ -306,6 +316,7 @@ Console.prototype.count = function count(label = 'default') {
306316
else
307317
count++;
308318
counts.set(label, count);
319+
trace(kTraceCount, kTraceConsoleCategory, `count::${label}`, 0, count);
309320
this.log(`${label}: ${count}`);
310321
};
311322

@@ -315,6 +326,7 @@ Console.prototype.count = function count(label = 'default') {
315326
// the counter from being a memory leak.
316327
Console.prototype.countReset = function countReset(label = 'default') {
317328
const counts = this[kCounts];
329+
trace(kTraceCount, kTraceConsoleCategory, `count::${label}`, 0, 0);
318330
counts.delete(`${label}`);
319331
};
320332

‎test/parallel/test-bootstrap-modules.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ const list = process.moduleLoadList.slice();
1111

1212
const assert = require('assert');
1313

14-
assert(list.length <= 82,
15-
`Expected <= 82 elements in moduleLoadLists, got ${list.length}`);
14+
assert(list.length <= 83,
15+
`Expected <= 83 elements in moduleLoadLists, got ${list.length}`);
+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const cp = require('child_process');
5+
const path = require('path');
6+
const fs = require('fs');
7+
const tmpdir = require('../common/tmpdir');
8+
9+
// Tests that node.console trace events for counters and time methods are
10+
// emitted as expected.
11+
12+
const names = [
13+
'time::foo',
14+
'count::bar'
15+
];
16+
const expectedCounts = [ 1, 2, 0 ];
17+
const expectedTimeTypes = [ 'b', 'n', 'e' ];
18+
19+
if (process.argv[2] === 'child') {
20+
// The following console outputs exercise the test, causing node.console
21+
// trace events to be emitted for the counter and time calls.
22+
console.count('bar');
23+
console.count('bar');
24+
console.countReset('bar');
25+
console.time('foo');
26+
setImmediate(() => {
27+
console.timeLog('foo');
28+
setImmediate(() => {
29+
console.timeEnd('foo');
30+
});
31+
});
32+
} else {
33+
tmpdir.refresh();
34+
35+
const proc = cp.fork(__filename,
36+
[ 'child' ], {
37+
cwd: tmpdir.path,
38+
execArgv: [
39+
'--trace-event-categories',
40+
'node.console'
41+
]
42+
});
43+
44+
proc.once('exit', common.mustCall(async () => {
45+
const file = path.join(tmpdir.path, 'node_trace.1.log');
46+
47+
assert(fs.existsSync(file));
48+
const data = await fs.promises.readFile(file, { encoding: 'utf8' });
49+
JSON.parse(data).traceEvents
50+
.filter((trace) => trace.cat !== '__metadata')
51+
.forEach((trace) => {
52+
assert.strictEqual(trace.pid, proc.pid);
53+
assert(names.includes(trace.name));
54+
if (trace.name === 'count::bar')
55+
assert.strictEqual(trace.args.data, expectedCounts.shift());
56+
else if (trace.name === 'time::foo')
57+
assert.strictEqual(trace.ph, expectedTimeTypes.shift());
58+
});
59+
assert.strictEqual(expectedCounts.length, 0);
60+
assert.strictEqual(expectedTimeTypes.length, 0);
61+
}));
62+
}

0 commit comments

Comments
 (0)
Please sign in to comment.