Preamble
A known library Winston has the same issue as many other different libraries that serve the purpose of multi-transport logging. When one of the transports is console
the reported message in debugger console (browser or any environment for Node.js) misses very powerful information: the place where the initial call was initiated (developer's file) and instead the place of call inside the library is displayed. In this case multiple calls from different files/places are all reported as if logged from one same place.
Solutions tried
I've research two approaches. One was trick on browser/Node when they infer the place of call to console.log
. The only way i found it can be done is via source maps. This is a technology that allows to map minified js sources to original sources and debug it while looking at the full source. However, this assumes that there is one transition from real (minified) source to original. And in case of substituting source for console.log
in potential library mylogger
should be dynamic and reflect the multiple places where mylogger.log
is called. I haven't found a way to do this dynamically since browser loads the map file just once.
Another one was to substitute the call of console.log
and inside of custom function call all other transports (this can be the same Winston). However, if we do a simple replace like below
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/>';
};
the place of call to originalLog
will always be the same and it will be reported accordingly in console output. So I thought of intercepting the call to console.log
but leaving the original native function in place. But I failed to get the parameters of call.
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;
}
}
});
}
Question in short
Does anybody know a different approach to logging or a way to trick on browser/Node.js when calling console.log
? The goal is to have a multi-level multi-transport logger which would allow to switch verbosity and transports in configuration (which will be different for development and production), have full power of console.log
and at the same time neat syntax, i.e. a single function call at a place where developer needs to log something. Thanks for reading :)