Got an old application, that prints out quite a lot of messages using console.log, but I just can not find in which files and lines console.log is
All solutions to this question so far rely on splitting and matching the stack trace as a string, which will break in (the unlikely) case the format of that string is changed in the future. Inspired by this gist on GitHub and the other answers here, I want to provide my own solution:
'use strict';
const path = require('path');
['debug', 'log', 'warn', 'error'].forEach((methodName) => {
const originalLoggingMethod = console[methodName];
console[methodName] = (firstArgument, ...otherArguments) => {
const originalPrepareStackTrace = Error.prepareStackTrace;
Error.prepareStackTrace = (_, stack) => stack;
const callee = new Error().stack[1];
Error.prepareStackTrace = originalPrepareStackTrace;
const relativeFileName = path.relative(process.cwd(), callee.getFileName());
const prefix = `${relativeFileName}:${callee.getLineNumber()}:`;
if (typeof firstArgument === 'string') {
originalLoggingMethod(prefix + ' ' + firstArgument, ...otherArguments);
} else {
originalLoggingMethod(prefix, firstArgument, ...otherArguments);
}
};
});
// Tests:
console.log('%s %d', 'hi', 42);
console.log({ a: 'foo', b: 'bar'});
Unlike the other solutions, this script
You can color the prefix with chalk or color.js, but I didn't want to introduce dependencies for this here.
The above script uses the V8 API to customize stack traces. The callee is a CallSite object with the following methods in case you want to customize the prefix:
getThis: returns the value ofthisgetTypeName: returns the type ofthisas a string. This is the name of the function stored in the constructor field ofthis, if available, otherwise the object’s[[Class]]internal property.getFunction: returns the current functiongetFunctionName: returns the name of the current function, typically itsnameproperty. If anameproperty is not available an attempt is made to infer a name from the function’s context.getMethodName: returns the name of the property ofthisor one of its prototypes that holds the current functiongetFileName: if this function was defined in a script returns the name of the scriptgetLineNumber: if this function was defined in a script returns the current line numbergetColumnNumber: if this function was defined in a script returns the current column numbergetEvalOrigin: if this function was created using a call toevalreturns a string representing the location whereevalwas calledisToplevel: is this a top-level invocation, that is, is this the global object?isEval: does this call take place in code defined by a call toeval?isNative: is this call in native V8 code?isConstructor: is this a constructor call?isAsync: is this an async call (i.e.awaitorPromise.all())?isPromiseAll: is this an async call toPromise.all()?getPromiseIndex: returns the index of the promise element that was followed inPromise.all()for async stack traces, ornullif theCallSiteis not aPromise.all()call.
This answer is a cross-post of an answer I just gave to a similar question as more people might find this page.