开发者问题收集

在 JavaScript 中覆盖 console.log

2016-02-22
6869

我想覆盖 console.log 方法,以便在调用 console.log 时调用一组任务。我参考了其他 Stackoverflow 答案,但结果却给出错误:

Uncaught RangeError: Maximum call stack size exceeded.

这就是我想要做的:

backupconsolelog = console.log;

console.log = function(arguments)
{
    //do my tasks;

    backupconsolelog(arguments);
}

更新 1 :不知何故成功覆盖了 console.log,但现在我无法在完成覆盖的同一 .js 文件中执行 console.log(displaySomethingInConsole) 。这不知何故导致对 console.log 的递归调用,并再次给出 Uncaught RangeError: Maximum call stack size reached.

如何在同一个 .js 文件中使用 console.log()?

更新 2 :我有一个 check() 函数,它由覆盖的 console.log 调用。但是, check() 函数内部有一个 console.log 调用,导致 Maximum call stack size reached. 错误。

更新 3 :再次出错! :(

Uncaught TypeError: Illegal invocation

var _log = window.console.log;
window.console.log = function () {
_log.apply(this, arguments);
check();
};

_log("aaa");
check() {};

更新 4 console 绑定到 _log ,即 console.log.bind(console) 将其清除。

3个回答

如果您收到 超出最大调用堆栈大小 错误,则几乎肯定意味着您的函数 无限递归调用自身 。您找到的解决方案以及 RaraituL 展示的解决方案应该可以完美运行。您可能不止一次调用了设置调用重定向的代码部分。

// First time:
backupconsolelog = console.log.bind(console);
console.log = function() {
    backupconsolelog.apply(this, arguments);
    /* Do other stuff */
}
// console.log is now redirected correctly

// Second time:
backupconsolelog = console.log;
// Congratulations, you now have infinite recursion

您可以在设置重定向的位置添加一些调试信息 (显然不是使用 console.log ,而是尝试使用 debugger; 来创建自动断点) ,以查看代码在何处被调用。

更新

这可能属于注释: 您的 console.log 重定向函数显然调用了某个名为 check 的函数。然后,此 check 函数调用 console.log ,它是 您的 函数,而不是原始函数。让 check 函数调用 原始 实现。

backupconsolelog = console.log.bind(console);

console.log = function() {
    check();
    backupconsolelog.apply(this, arguments);
}

function check() {
    // This will call your function above, so don't do it!
    console.log('Foo');

    // Instead call the browser's original implementation:
    backupconsolelog('Foo');
}

更新 2

浏览器 console.log 实现的内部工作可能依赖于或不依赖于为 this 引用设置的 console 。因此,您应该将 console.log 存储为 绑定 console ,就像在我的代码中一样。

Anders Marzi Tornblad
2016-02-22
// keep reference to original function
var _log = window.console.log;

// overwrite function
window.console.log = function () {
    _log.apply(this, arguments);
    alert(arguments);
};

console.log("hello world");
Catalin
2016-02-22

在遇到一些问题之后,我设法用 winston + express 替换了 console.log。

我使用 winston-sugar,因为它使配置更容易,但任何东西都应该可以工作。(执行 npm install winston-sugar 时会创建 .config/winston.json) 想要用其他东西替换 console.log 的人只需查看最后 5 行,因为它提供了非常干净的代码。

我认为这是一种非常巧妙的方法,可以将 express 与 console.log 一起登录到文件中

const morgan = require('morgan');
const winstonLoader = require('winston-sugar');
winstonLoader.config('./config/winston.json');
const log = winstonLoader.getLogger('app');
log.stream = {
  write: function (message, encoding) {
    log.info(message);
  },
};

// Add some lines indicating that the program started to track restarts.
log.info('----------------------------------');
log.info('--');
log.info('-- Starting program');
log.info('--');
log.info('----------------------------------');

console.log = (...args) => log.info(...args);
console.info = (...args) => log.info(...args);
console.warn = (...args) => log.warn(...args);
console.error = (...args) => log.error(...args);
console.debug = (...args) => log.debug(...args);

如果您正在运行 express,则在代码的后面。

// app.use(morgan('combined')); //replaced with the next line to get morgan logs into the winston logfiles.
app.use(morgan('combined', { stream: log.stream }));
Griffin
2020-06-01