I would like to log some message text and keep original context (class, line number). Just on console output that works fine with console.log.bind(console). Problem is I want to send message also to some http server for logging.
Example 1. Using a getter & bind I can pass console.log to caller and get message and context (class, line number). But then getter function won't have arguments at runtime as those have been passed to console directly. So I can't log the message.
Example 2. If I change from getter to function I have arguments (aka message), can send it somewhere and console.log it in parallel. But console.log line will show my logger class as it's used there and not bound.
Example 1
get debug() {
let message = Array.prototype.slice.call(arguments);
// send message over to some http server
// ...
return console.log.bind(console);
}
Example 2
public debug() {
let message = Array.prototype.slice.call(arguments);
// send message over to some http server
// ...
console.log.apply(console, args);
}
Is there a way I can keep context for console.log but at the same time get log message for further manipulation (sending it to http server)?
First of all the context (the value of this
when console.log
is running) is meaningless here. This does not affect the reported file/line being logged in any way.
All that matters for the file/line reported by console.log
is where the function is invoked. And since it's a built in function of native code, you can't replace it and have it still work.
All this means that if you wrap console.log
, in order to do something arbitrary with its arguments, you are obscuring what you intend to be the call site.
So I think the best you can get is to derive the stack trace yourself and report it alongside where the JS interpreter thinks is right. You can do this by instantiating an Error
and asking for its stack
.
function debug(...args: any[]) {
// Do your stuff here...
sendArgsToServer(args)
// Get the line from the stack trace that is the previous caller.
const callSite = new Error().stack!.split('\n')[2].trim()
// Call console.log with the call site you want also reported on the end.
console.log(...args, callSite)
}
function foo() {
debug('my debug line')
}
foo()
When I run that in Chrome, I get this in the console:
The index.ts:132
on the right is the location of console.log()
, in the debug function. But the index.ts:135:5
immediately after what you logged is where debug()
was called from.
And it least in Chrome, those links both work! Clicking either takes you to the relevant bit of source mapped code in the sources pane.
I'm pretty sure that's the best you'll get here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With