1'use strict'; 2 3const { inspect, format, formatWithOptions } = require('internal/util/inspect'); 4 5const { RegExp } = primordials; 6 7// `debugs` is deliberately initialized to undefined so any call to 8// debuglog() before initializeDebugEnv() is called will throw. 9let debugs; 10 11let debugEnvRegex = /^$/; 12 13// `debugEnv` is initial value of process.env.NODE_DEBUG 14function initializeDebugEnv(debugEnv) { 15 debugs = {}; 16 if (debugEnv) { 17 debugEnv = debugEnv.replace(/[|\\{}()[\]^$+?.]/g, '\\$&') 18 .replace(/\*/g, '.*') 19 .replace(/,/g, '$|^') 20 .toUpperCase(); 21 debugEnvRegex = new RegExp(`^${debugEnv}$`, 'i'); 22 } 23} 24 25// Emits warning when user sets 26// NODE_DEBUG=http or NODE_DEBUG=http2. 27function emitWarningIfNeeded(set) { 28 if ('HTTP' === set || 'HTTP2' === set) { 29 process.emitWarning('Setting the NODE_DEBUG environment variable ' + 30 'to \'' + set.toLowerCase() + '\' can expose sensitive ' + 31 'data (such as passwords, tokens and authentication headers) ' + 32 'in the resulting log.'); 33 } 34} 35 36function noop() {} 37 38function debuglogImpl(set) { 39 set = set.toUpperCase(); 40 if (debugs[set] === undefined) { 41 if (debugEnvRegex.test(set)) { 42 const pid = process.pid; 43 emitWarningIfNeeded(set); 44 debugs[set] = function debug(...args) { 45 const colors = process.stderr.hasColors && process.stderr.hasColors(); 46 const msg = formatWithOptions({ colors }, ...args); 47 const coloredPID = inspect(pid, { colors }); 48 process.stderr.write(format('%s %s: %s\n', set, coloredPID, msg)); 49 }; 50 } else { 51 debugs[set] = noop; 52 } 53 } 54 return debugs[set]; 55} 56 57// debuglogImpl depends on process.pid and process.env.NODE_DEBUG, 58// so it needs to be called lazily in top scopes of internal modules 59// that may be loaded before these run time states are allowed to 60// be accessed. 61function debuglog(set, cb) { 62 let debug = (...args) => { 63 // Only invokes debuglogImpl() when the debug function is 64 // called for the first time. 65 debug = debuglogImpl(set); 66 if (typeof cb === 'function') 67 cb(debug); 68 debug(...args); 69 }; 70 return (...args) => { 71 debug(...args); 72 }; 73} 74 75module.exports = { 76 debuglog, 77 initializeDebugEnv 78}; 79