用绑定包装consol.log以保留调用方上下文

时间:2019-08-09 19:25:23

标签: typescript console.log

我想记录一些消息文本并保留原始上下文(类,行号)。只是在与console.log.bind(console)正常工作的控制台输出上。问题是我也想将消息发送到某些http服务器进行记录。

示例1.使用获取和绑定,我可以将console.log传递给调用者,并获取消息和上下文(类,行号)。但是然后,getter函数在运行时将没有参数,因为这些参数已直接传递到控制台。所以我无法记录该消息。

示例2。如果我从getter更改为函数,则我有参数(又称消息),可以将其发送到某个地方并进行console.log并行记录。但是console.log行将显示在那里使用的我的logger类,而不是绑定类。

示例1


get debug() {
    let message = Array.prototype.slice.call(arguments);
    // send message over to some http server
    // ...

    return console.log.bind(console);
}

示例2


public debug() {
    let message = Array.prototype.slice.call(arguments);
    // send message over to some http server
    // ...
    console.log.apply(console, args);
}

有没有一种方法可以保留console.log的上下文,但同时获取日志消息以进行进一步操作(将其发送到http服务器)?

1 个答案:

答案 0 :(得分:1)

首先,上下文(运行this时如果console.log的值)在这里没有意义。这不会影响以任何方式记录的报告文件/行。

对于由console.log报告的文件/行而言,所有重要的地方就是调用函数的位置。而且由于它是本机代码的内置函数,因此您无法替换它并使其仍然起作用。

这一切意味着,如果包装console.log,以便对其参数进行任意处理,则会使您打算成为呼叫站点的事情变得模糊。


因此,我认为最好的方法是自己获取堆栈跟踪并在JS解释器认为正确的地方报告它。您可以通过实例化Error并要求其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()

当我在Chrome中运行该代码时,我会在控制台中看到它:

Chrome Console

右侧的index.ts:132是调试功能中console.log()的位置。但是,您登录后的index.ts:135:5是调用debug()的地方。

至少在Chrome中,这些链接都可以正常工作!单击任一,将转到源窗格中源映射代码的相关位。

我很确定那是你能得到的最好的东西。