已知库Winston与许多其他用于多传输日志记录的不同库具有相同的问题。当其中一个传输是console
时,调试器控制台(浏览器或Node.js的任何环境)中报告的消息错过了非常强大的信息:启动初始调用的位置(开发人员的文件),而不是显示库内的呼叫位置。在这种情况下,来自不同文件/地点的多个调用都会被报告,就像从同一个地方记录一样。
我研究了两种方法。一个是浏览器/节点上的技巧,当他们推断出console.log
的呼叫位置时。我发现它的唯一方法是通过source maps。这是一种技术,允许将缩小的js源映射到原始源并在查看完整源时进行调试。但是,这假设从实际(缩小)源到原始的一个过渡。如果在潜在库console.log
中替换mylogger
的来源,则应该是动态的,并反映调用mylogger.log
的多个位置。由于浏览器只加载一次地图文件,我还没有找到一种动态执行此操作的方法。
另一个是替换console.log
的调用,并在自定义函数内调用所有其他传输(这可以是相同的Winston)。但是,如果我们进行如下的简单替换
var originalLog = console.log;
console.__proto__.log = function(message){
message = [new Date().toISOString(), message].join(' ');
originalLog.call(console, message);
//here send via other transports
body.innerHTML = body.innerHTML + message + '<br/>';
};
originalLog
的呼叫位置始终相同,并在控制台输出中相应地报告。所以我想到拦截对console.log
的调用,但保留了原始的原生函数。但是我没有得到呼叫的参数。
function interceptGettingLog(){
var originalLog = console.log;
Object.defineProperties(console.__proto__, {
log: {
get: function(){
//arguments is always empty here, which is not a big surprise
originalLog.call(console, 'log accessed ' + JSON.stringify(arguments));
return originalLog;
}
}
});
}
在调用console.log
时,是否有人知道不同的日志记录方法或浏览器/ Node.js上的欺骗方法?我们的目标是拥有一个多级多传输记录器,它可以在配置中切换冗长和传输(对于开发和生产而言会有所不同),具有console.log
的全部功能,同时还具有整洁的语法,即在开发人员需要记录某些内容的地方进行单个函数调用。感谢您阅读:)
答案 0 :(得分:1)
到目前为止,这是我可以弥补的最佳解决方案。我假设它不是 clean ,因为它强制调用行上的特定语法。 但它确实有效。
function logInfo(){
//do multitransport multilevel logging on your decision
// for example, Winston
var args = Array.prototype.slice.call(arguments);
winston.log.apply(winston, args);
if(levels.contains('console')){
//return a console.log function to call it in the 'right' place
return console.log.bind.apply(console.log, [console].concat(args));
}else{
//return a no-operation function to skip output to console
return function nop(){};
}
}
用法
...
logInfo('My message:', {foo:true, count: 100})();
...
诀窍是返回console.log
与传递给主日志记录函数的参数绑定,并在调用主日志记录函数的同一位置调用它。这样我们就可以避免重复代码:只记录指定一次的参数。主日志记录功能后的括号()
表示是否会输出到控制台。如果配置指示不输出到控制台,我们返回一个空函数。
<强> PS 强>
我会考虑 clean 替换console.log
的那个。因此,您无需修改即可应用补丁
现有代码console.log
次调用。但是如果不重载()
就不可能实现这一点,这在ES5中是不可行的。
使用参数数组调用的bind
的信用转到@FelixKling https://stackoverflow.com/a/21507470/4573999
答案 1 :(得分:1)
在Chrome开发工具中,您可以“封装”包装器脚本,chrome会报告调用黑盒子脚本中的函数的位置。
右键单击开发工具源中的源脚本,然后选择“Blackbox脚本”。