Kir*_*tin 12 javascript logging
一个已知的库Winston与许多其他不同的库有相同的问题,这些库用于多传输日志记录.当其中一个传输是console调试器控制台(浏览器或Node.js的任何环境)中报告的消息时,错过了非常强大的信息:启动初始调用的位置(开发人员的文件),而不是显示库内的调用位置.在这种情况下,来自不同文件/地点的多个呼叫都被报告为从同一个地方记录.
我研究了两种方法.当他们推断出呼叫的地点时,一个是浏览器/节点上的技巧console.log.我发现它的唯一方法是通过源地图.这是一种技术,允许将缩小的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/>';
};
Run Code Online (Sandbox Code Playgroud)
呼叫的位置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;
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
在调用时,是否有人知道不同的日志记录方法或浏览器/ Node.js的方法console.log?我们的目标是拥有一个多级多传输记录器,它可以在配置中切换冗长和传输(对于开发和生产来说会有所不同),具有完整的功能console.log并且同时具有整洁的语法,即单个功能在开发人员需要记录某事的地方打电话.谢谢阅读 :)
到目前为止,这是我能想到的最好的解决方案。我认为它不干净,因为它强制调用行上的特定语法。但它有效。
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(){};
}
}
Run Code Online (Sandbox Code Playgroud)
用法
...
logInfo('My message:', {foo:true, count: 100})();
...
Run Code Online (Sandbox Code Playgroud)
技巧是返回console.log与传递给主日志记录函数的参数绑定的值,并在调用主日志记录函数的同一位置调用它。这样我们就避免了重复代码:只记录指定的参数一次。主日志记录功能后面的括号()表示是否有输出到控制台。如果配置指示不输出到控制台,我们将返回一个空函数。
PS
我会考虑使用clean来替代console.log. 因此,您可以应用补丁,而无需通过调用修改现有代码console.log。但如果不重载就不可能实现这一点(),这在 ES5 中是不可能的。
使用参数数组调用的功劳bind转到@FelixKling /sf/answers/1505522931/
| 归档时间: |
|
| 查看次数: |
180 次 |
| 最近记录: |