javascript中console.log的实际拦截器

An actual interceptor for console.log in javascript

本文关键字:console log javascript      更新时间:2023-09-26

通常的建议(捕获javascript console.log?)对于js console.log拦截器有两个不足,都很严重:

(i)实际浏览器控制台中所有的调用现在看起来都来自同一行——定义新函数的地方——而不是执行调用的地方

(ii)截获的参数还没有像console.log那样格式化(即%的替代商品,特别是%o):

(function() {
  function send_stuff(){ /* Deal with console arguments. */ }
  
  var oldLog=console.log;
  console.log=function(msg) {
    oldLog.apply(this,arguments);
    send_stuff(Array.prototype.slice.call(arguments).join());
  }
}())
console.log("test");
console.log("Hello %s", "Bob");
console.log("Here is an object %o", { stuff: "thing" });

也许已经设计出更好的东西(例如能够捕获console.log的实际缓冲区内容的东西)。

编辑:

为了澄清多参数失败:除了扩展文件/行信息外,console.log还对%序列进行了一些巧妙的替换- a-la-printf。特别令人感兴趣的是%o序列,其中扩展了后续对象的深层转储,并由浏览器的控制台窗口充分利用。这是无法复制的,除非你愿意基本上重新实现它的逻辑(不必要的,而且很可能是低效的)

欢呼,

看起来console.log的行为改变了一点,现在遮罩正在工作,但您仍然在控制台中获得oldLog.apply(this,arguments);的行。您可以做的一件事是使用console.error代替,这将显示调用堆栈,您可以使用它来查看最初调用修改后的日志方法的行。

另一个解决方案是抛出一个错误以从调用堆栈中获取行号,如下所示

(function () {
  function origin() {
    try {
      throw Error('');
    } catch (err) {
      return err.stack.split(''n').slice(-1)[0];
    }
  }
  function send_stuff() { /* Deal with console arguments. */ }
  var oldLog = console.log;
  console.log = function (msg) {
    oldLog.call(this, ...arguments, origin());
    send_stuff(Array.prototype.slice.call(arguments).join());
  };
})();
console.log("test");
console.log("Hello %s", "Bob");
console.log("Here is an object %o", {
  stuff: "thing"
});