Skip to content

Commit 7611d5b

Browse files
committed
util: add colors to debuglog()
This adds colors to the passed through arguments in case the stream supports colors. The PID will also be highlighted. PR-URL: #30930 Reviewed-By: James M Snell <[email protected]>
1 parent ba0682e commit 7611d5b

File tree

2 files changed

+37
-9
lines changed

2 files changed

+37
-9
lines changed

lib/internal/util/debuglog.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
'use strict';
22

3-
const { format } = require('internal/util/inspect');
3+
const { inspect, format, formatWithOptions } = require('internal/util/inspect');
44

55
// `debugs` is deliberately initialized to undefined so any call to
66
// debuglog() before initializeDebugEnv() is called will throw.
@@ -38,8 +38,10 @@ function debuglogImpl(set) {
3838
const pid = process.pid;
3939
emitWarningIfNeeded(set);
4040
debugs[set] = function debug(...args) {
41-
const msg = format(...args);
42-
process.stderr.write(format('%s %d: %s\n', set, pid, msg));
41+
const colors = process.stderr.hasColors && process.stderr.hasColors();
42+
const msg = formatWithOptions({ colors }, ...args);
43+
const coloredPID = inspect(pid, { colors });
44+
process.stderr.write(format('%s %s: %s\n', set, coloredPID, msg));
4345
};
4446
} else {
4547
debugs[set] = null;

test/sequential/test-util-debug.js

+32-6
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
'use strict';
2323
const common = require('../common');
2424
const assert = require('assert');
25+
const util = require('util');
2526

2627
const [, , modeArgv, sectionArgv] = process.argv;
2728

@@ -54,19 +55,36 @@ function parent() {
5455
test('*-test', true, 'abc-test');
5556
}
5657

57-
function test(environ, shouldWrite, section) {
58+
function test(environ, shouldWrite, section, forceColors = false) {
5859
let expectErr = '';
5960
const expectOut = 'ok\n';
6061

6162
const spawn = require('child_process').spawn;
6263
const child = spawn(process.execPath, [__filename, 'child', section], {
63-
env: Object.assign(process.env, { NODE_DEBUG: environ })
64+
env: Object.assign(process.env, {
65+
NODE_DEBUG: environ,
66+
FORCE_COLOR: forceColors ? 'true' : 'false'
67+
})
6468
});
6569

6670
if (shouldWrite) {
67-
expectErr =
68-
`${section.toUpperCase()} ${child.pid}: this { is: 'a' } /debugging/\n${
69-
section.toUpperCase()} ${child.pid}: num=1 str=a obj={"foo":"bar"}\n`;
71+
if (forceColors) {
72+
const { colors, styles } = util.inspect;
73+
const addCodes = (arr) => [`\x1B[${arr[0]}m`, `\x1B[${arr[1]}m`];
74+
const num = addCodes(colors[styles.number]);
75+
const str = addCodes(colors[styles.string]);
76+
const regexp = addCodes(colors[styles.regexp]);
77+
const start = `${section.toUpperCase()} ${num[0]}${child.pid}${num[1]}`;
78+
const debugging = `${regexp[0]}/debugging/${regexp[1]}`;
79+
expectErr =
80+
`${start}: this { is: ${str[0]}'a'${str[1]} } ${debugging}\n` +
81+
`${start}: num=1 str=a obj={"foo":"bar"}\n`;
82+
} else {
83+
const start = `${section.toUpperCase()} ${child.pid}`;
84+
expectErr =
85+
`${start}: this { is: 'a' } /debugging/\n` +
86+
`${start}: num=1 str=a obj={"foo":"bar"}\n`;
87+
}
7088
}
7189

7290
let err = '';
@@ -85,12 +103,20 @@ function test(environ, shouldWrite, section) {
85103
assert(!c);
86104
assert.strictEqual(err, expectErr);
87105
assert.strictEqual(out, expectOut);
106+
// Run the test again, this time with colors enabled.
107+
if (!forceColors) {
108+
test(environ, shouldWrite, section, true);
109+
}
88110
}));
89111
}
90112

91113

92114
function child(section) {
93-
const util = require('util');
115+
const tty = require('tty');
116+
// Make sure we check for colors, no matter of the stream's default.
117+
Object.defineProperty(process.stderr, 'hasColors', {
118+
value: tty.WriteStream.prototype.hasColors
119+
});
94120
const debug = util.debuglog(section);
95121
debug('this', { is: 'a' }, /debugging/);
96122
debug('num=%d str=%s obj=%j', 1, 'a', { foo: 'bar' });

0 commit comments

Comments
 (0)