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 called.
有一个旧的应用程序,使用console.log打印出相当多的消息,但我无法找到调用console.log的文件和行。
Is there a way to hook into the app and show file name and line numbers?
有没有办法挂钩应用程序并显示文件名和行号?
3 个解决方案
#1
3
For a temporary hack to find the log statements that you want to get rid of, it's not too difficult to override console.log
yourself.
对于临时hack来找到你想要删除的日志语句,自己覆盖console.log并不困难。
var log = console.log;
console.log = function() {
log.apply(console, arguments);
// Print the stack trace
console.trace();
};
// Somewhere else...
function foo(){
console.log('Foobar');
}
foo();
That will print something like
这将打印出类似的东西
Foobar
Trace
at Console.console.log (index.js:4:13)
at foo (index.js:10:13)
at Object.<anonymous> (index.js:12:1)
...
A lot of noise in there but the second line in the call stack, at foo (index.js:10:13)
, should point you to the right place.
那里有很多噪音,但是调用堆栈中的第二行,在foo(index.js:10:13),应该指向正确的位置。
#2
9
Having full stack trace for each call is a bit noisy. I've just improved the @noppa's solution to print only the initiator:
每个呼叫都有完整的堆栈跟踪有点吵。我刚刚改进了@noppa的解决方案,只打印启动器:
['log', 'warn', 'error'].forEach((methodName) => {
const originalMethod = console[methodName];
console[methodName] = (...args) => {
let initiator = 'unknown place';
try {
throw new Error();
} catch (e) {
if (typeof e.stack === 'string') {
let isFirst = true;
for (const line of e.stack.split('\n')) {
const matches = line.match(/^\s+at\s+(.*)/);
if (matches) {
if (!isFirst) { // first line - current function
// second line - caller (what we are looking for)
initiator = matches[1];
break;
}
isFirst = false;
}
}
}
}
originalMethod.apply(console, [...args, '\n', ` at ${initiator}`]);
};
});
It also patches other methods (useful for Nodejs, since warn
and error
don't come with a stack trace as in Chrome).
它还修补了其他方法(对Nodejs很有用,因为警告和错误不会像Chrome一样带有堆栈跟踪)。
So your console would look something like:
所以你的控制台看起来像:
Loading settings.json
at fs.readdirSync.filter.forEach (.../settings.js:21:13)
Server is running on http://localhost:3000 or http://127.0.0.1:3000
at Server.app.listen (.../index.js:67:11)
#3
0
I found Dmitry Druganov's answer really nice, but I tried it on Windows 10 (with Node 8.9.4) and it didn't work well. It was printing the full path, something like:
我发现德米特里·德鲁加诺夫的答案非常好,但我在Windows 10(使用Node 8.9.4)上尝试过它并且效果不佳。它打印了完整的路径,如:
Loading settings.json
at fs.readdirSync.filter.forEach (D:\Users\Piyin\Projects\test\settings.js:21:13)
Server is running on http://localhost:3000 or http://127.0.0.1:3000
at Server.app.listen (D:\Users\Piyin\Projects\test\index.js:67:11)
So I took said answer and made these improvements (from my point of view):
所以我接受了所说的答案并做了这些改进(从我的角度来看):
- Assume the important line of the stack trace is the third one (the first one is the word
Error
and the second one is where you place this script) - Remove the current script folder path (given by __dirname, which in my case is
D:\Users\Piyin\Projects\test
). Note: For this to work well, the script should be on the project's main Javascript - Remove the starting
at
- Place the file information before the actual log
- Format the information as
Class.method at path/to/file:line:column
假设堆栈跟踪的重要行是第三行(第一行是单词Error,第二行是放置此脚本的位置)
删除当前脚本文件夹路径(由__dirname给出,在我的例子中是D:\ Users \ Piyin \ Projects \ test)。注意:为了使其正常工作,脚本应该在项目的主要Javascript上
删除起点
将文件信息放在实际日志之前
将信息格式化为Class.method在path / to / file:line:column
Here it is:
这里是:
['log','warn','error'].forEach((methodName) => {
const originalMethod = console[methodName];
console[methodName] = (...args) => {
try {
throw new Error();
} catch (error) {
originalMethod.apply(
console,
[
error
.stack // Grabs the stack trace
.split('\n')[2] // Grabs third line
.trim() // Removes spaces
.substring(3) // Removes three first characters ("at ")
.replace(__dirname, '') // Removes script folder path
.replace(/\s\(./, ' at ') // Removes first parentheses and replaces it with " at "
.replace(/\)/, '') // Removes last parentheses
),
'\n',
...args
]
);
}
};
});
And here's the new output:
这是新的输出:
fs.readdirSync.filter.forEach at settings.js:21:13
Loading settings.json
Server.app.listen at index.js:67:11
Server is running on http://localhost:3000 or http://127.0.0.1:3000
Here's the minified-by-hand code (240 bytes):
这是手工编写的代码(240字节):
['log','warn','error'].forEach(a=>{let b=console[a];console[a]=(...c)=>{try{throw new Error}catch(d){b.apply(console,[d.stack.split('\n')[2].trim().substring(3).replace(__dirname,'').replace(/\s\(./,' at ').replace(/\)/,''),'\n',...c])}}});
#1
3
For a temporary hack to find the log statements that you want to get rid of, it's not too difficult to override console.log
yourself.
对于临时hack来找到你想要删除的日志语句,自己覆盖console.log并不困难。
var log = console.log;
console.log = function() {
log.apply(console, arguments);
// Print the stack trace
console.trace();
};
// Somewhere else...
function foo(){
console.log('Foobar');
}
foo();
That will print something like
这将打印出类似的东西
Foobar
Trace
at Console.console.log (index.js:4:13)
at foo (index.js:10:13)
at Object.<anonymous> (index.js:12:1)
...
A lot of noise in there but the second line in the call stack, at foo (index.js:10:13)
, should point you to the right place.
那里有很多噪音,但是调用堆栈中的第二行,在foo(index.js:10:13),应该指向正确的位置。
#2
9
Having full stack trace for each call is a bit noisy. I've just improved the @noppa's solution to print only the initiator:
每个呼叫都有完整的堆栈跟踪有点吵。我刚刚改进了@noppa的解决方案,只打印启动器:
['log', 'warn', 'error'].forEach((methodName) => {
const originalMethod = console[methodName];
console[methodName] = (...args) => {
let initiator = 'unknown place';
try {
throw new Error();
} catch (e) {
if (typeof e.stack === 'string') {
let isFirst = true;
for (const line of e.stack.split('\n')) {
const matches = line.match(/^\s+at\s+(.*)/);
if (matches) {
if (!isFirst) { // first line - current function
// second line - caller (what we are looking for)
initiator = matches[1];
break;
}
isFirst = false;
}
}
}
}
originalMethod.apply(console, [...args, '\n', ` at ${initiator}`]);
};
});
It also patches other methods (useful for Nodejs, since warn
and error
don't come with a stack trace as in Chrome).
它还修补了其他方法(对Nodejs很有用,因为警告和错误不会像Chrome一样带有堆栈跟踪)。
So your console would look something like:
所以你的控制台看起来像:
Loading settings.json
at fs.readdirSync.filter.forEach (.../settings.js:21:13)
Server is running on http://localhost:3000 or http://127.0.0.1:3000
at Server.app.listen (.../index.js:67:11)
#3
0
I found Dmitry Druganov's answer really nice, but I tried it on Windows 10 (with Node 8.9.4) and it didn't work well. It was printing the full path, something like:
我发现德米特里·德鲁加诺夫的答案非常好,但我在Windows 10(使用Node 8.9.4)上尝试过它并且效果不佳。它打印了完整的路径,如:
Loading settings.json
at fs.readdirSync.filter.forEach (D:\Users\Piyin\Projects\test\settings.js:21:13)
Server is running on http://localhost:3000 or http://127.0.0.1:3000
at Server.app.listen (D:\Users\Piyin\Projects\test\index.js:67:11)
So I took said answer and made these improvements (from my point of view):
所以我接受了所说的答案并做了这些改进(从我的角度来看):
- Assume the important line of the stack trace is the third one (the first one is the word
Error
and the second one is where you place this script) - Remove the current script folder path (given by __dirname, which in my case is
D:\Users\Piyin\Projects\test
). Note: For this to work well, the script should be on the project's main Javascript - Remove the starting
at
- Place the file information before the actual log
- Format the information as
Class.method at path/to/file:line:column
假设堆栈跟踪的重要行是第三行(第一行是单词Error,第二行是放置此脚本的位置)
删除当前脚本文件夹路径(由__dirname给出,在我的例子中是D:\ Users \ Piyin \ Projects \ test)。注意:为了使其正常工作,脚本应该在项目的主要Javascript上
删除起点
将文件信息放在实际日志之前
将信息格式化为Class.method在path / to / file:line:column
Here it is:
这里是:
['log','warn','error'].forEach((methodName) => {
const originalMethod = console[methodName];
console[methodName] = (...args) => {
try {
throw new Error();
} catch (error) {
originalMethod.apply(
console,
[
error
.stack // Grabs the stack trace
.split('\n')[2] // Grabs third line
.trim() // Removes spaces
.substring(3) // Removes three first characters ("at ")
.replace(__dirname, '') // Removes script folder path
.replace(/\s\(./, ' at ') // Removes first parentheses and replaces it with " at "
.replace(/\)/, '') // Removes last parentheses
),
'\n',
...args
]
);
}
};
});
And here's the new output:
这是新的输出:
fs.readdirSync.filter.forEach at settings.js:21:13
Loading settings.json
Server.app.listen at index.js:67:11
Server is running on http://localhost:3000 or http://127.0.0.1:3000
Here's the minified-by-hand code (240 bytes):
这是手工编写的代码(240字节):
['log','warn','error'].forEach(a=>{let b=console[a];console[a]=(...c)=>{try{throw new Error}catch(d){b.apply(console,[d.stack.split('\n')[2].trim().substring(3).replace(__dirname,'').replace(/\s\(./,' at ').replace(/\)/,''),'\n',...c])}}});