节点:登录文件而不是控制台

Ran*_*lue 153 node.js

我可以配置console.log以便将日志写入文件而不是在控制台中打印吗?

小智 165

您也可以重载默认的console.log函数:

var fs = require('fs');
var util = require('util');
var log_file = fs.createWriteStream(__dirname + '/debug.log', {flags : 'w'});
var log_stdout = process.stdout;

console.log = function(d) { //
  log_file.write(util.format(d) + '\n');
  log_stdout.write(util.format(d) + '\n');
};
Run Code Online (Sandbox Code Playgroud)

上面的示例将记录到debug.log和stdout.

编辑: 请参阅此页面上的Clément多参数版本.

  • 很棒的答案!此外,如果要捕获多个console.log参数,只需在"d"的位置抓取"Arguments"对象 - https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/参数 (9认同)
  • 我不打扰覆盖console.log.只需创建自己的函数即可记录到特定文件. (7认同)
  • 但我需要在每个js文件中都有这个,有可能使它全局化吗? (5认同)
  • 要记录所有参数,您可以这样做: ```sh console.log = function (...d) { log_file.write(util.format(...d) + '\n'); log_stdout.write(util.format(...d) + '\n'); }; ```` (3认同)
  • 此外,这不适用于多个参数。例如 console.log(p1, p2, p3) (2认同)

Rya*_*ons 67

2013年更新 -这是围绕Node v0.2和v0.4编写的; 现在有更好的实用程序围绕日志记录.我强烈推荐温斯顿

更新2013年末 -我们仍然使用winston,但现在使用记录器库来包装自定义对象和格式的记录功能.以下是我们的logger.js示例 https://gist.github.com/rtgibbons/7354879


应该这么简单.

var access = fs.createWriteStream(dir + '/node.access.log', { flags: 'a' })
      , error = fs.createWriteStream(dir + '/node.error.log', { flags: 'a' });

// redirect stdout / stderr
proc.stdout.pipe(access);
proc.stderr.pipe(error);
Run Code Online (Sandbox Code Playgroud)

  • 就个人而言,我还要远离温斯顿.我们已经使用它超过一年了,并且最终决定完全删除它,因为它在我们的生产环境中引起了许多问题.该项目现在似乎维护得非常糟糕.只要你的手臂有一个问题列表.许多问题都有其他用户提交的pull请求,但项目维护者甚至没有花时间合并这些.对于替代节点bunyan和caterpillar可能值得一看. (13认同)
  • 由于最近的更改,你不能再调用stderr.pipe() - 它现在需要:`process .__ defineGetter __('stderr',function(){return fs.createWriteStream(__ dirname +'/ error.log', {flags:'a'})})` (10认同)
  • Nvm,这意味着我认为的过程......这是如何工作的?`console.log(whatever);` 仍然进入控制台,而不是文件。 (2认同)
  • 截至 2015 年 4 月,Winston 似乎已更新并收到大量活动。 (2认同)

ale*_*lex 57

如果您正在寻找生产中的东西,温斯顿可能是最好的选择.

如果你只是想快速做dev开发,直接输出到文件(我认为这只适用于*nix系统):

nohup node simple-server.js > output.log &
Run Code Online (Sandbox Code Playgroud)

  • 使用`>`重定向STDOUT也适用于Windows.`nohup`没有. (6认同)
  • 在 *nix 上,无需 `nohup` 即可正常工作,即 `node simple-server.js > output.log`。然后,如果您想跟踪日志,只需“tail -f output.log” (4认同)
  • 最后一个“&”代表什么? (2认同)

小智 52

我经常使用console.log()console.error()的许多参数,所以我的解决方案是:

var fs = require('fs');
var util = require('util');
var logFile = fs.createWriteStream('log.txt', { flags: 'a' });
  // Or 'w' to truncate the file every time the process starts.
var logStdout = process.stdout;

console.log = function () {
  logFile.write(util.format.apply(null, arguments) + '\n');
  logStdout.write(util.format.apply(null, arguments) + '\n');
}
console.error = console.log;
Run Code Online (Sandbox Code Playgroud)


kes*_*lal 28

Winston是一个非常流行的npm模块,用于日志记录.

这是一个操作方法.
在您的项目中安装winston:

npm install winston --save
Run Code Online (Sandbox Code Playgroud)

这是一个可以在我的项目中经常使用的开箱即用的配置,如utils下的logger.js.

 /**
 * Configurations of logger.
 */
const winston = require('winston');
const winstonRotator = require('winston-daily-rotate-file');

const consoleConfig = [
  new winston.transports.Console({
    'colorize': true
  })
];

const createLogger = new winston.Logger({
  'transports': consoleConfig
});

const successLogger = createLogger;
successLogger.add(winstonRotator, {
  'name': 'access-file',
  'level': 'info',
  'filename': './logs/access.log',
  'json': false,
  'datePattern': 'yyyy-MM-dd-',
  'prepend': true
});

const errorLogger = createLogger;
errorLogger.add(winstonRotator, {
  'name': 'error-file',
  'level': 'error',
  'filename': './logs/error.log',
  'json': false,
  'datePattern': 'yyyy-MM-dd-',
  'prepend': true
});

module.exports = {
  'successlog': successLogger,
  'errorlog': errorLogger
};
Run Code Online (Sandbox Code Playgroud)

然后只需在需要的地方导入:

const errorLog = require('../util/logger').errorlog;
const successlog = require('../util/logger').successlog;
Run Code Online (Sandbox Code Playgroud)

然后您可以将成功记录为:

successlog.info(`Success Message and variables: ${variable}`);
Run Code Online (Sandbox Code Playgroud)

和错误:

errorlog.error(`Error Message : ${error}`);
Run Code Online (Sandbox Code Playgroud)

它还会将所有成功日志和错误日志记录在日志目录下的日志目录中,如此处所示.
log direcotry

  • 日志在控制台中可见。并且不会立即创建文件!我错过了什么吗? (2认同)

ric*_*mer 13

const fs = require("fs");
const {keys} = Object;
const {Console} = console;

/**
 * Redirect console to a file.  Call without path or with false-y
 * value to restore original behavior.
 * @param {string} [path]
 */
function file(path) {
    const con = path ? new Console(fs.createWriteStream(path)) : null;

    keys(Console.prototype).forEach(key => {
        if (path) {
            this[key] = (...args) => con[key](...args);
        } else {
            delete this[key];
        }
    });
};

// patch global console object and export
module.exports = console.file = file;
Run Code Online (Sandbox Code Playgroud)

要使用它,请执行以下操作:

require("./console-file");
console.file("/path/to.log");
console.log("write to file!");
console.error("also write to file!");
console.file();    // go back to writing to stdout
Run Code Online (Sandbox Code Playgroud)


Mon*_*Mon 11

如果您使用的是 Linux,还可以使用输出重定向。不确定 Windows 的情况。

node server.js >> file.log 2>> file.log
Run Code Online (Sandbox Code Playgroud)

>> file.log重定向stdout到该文件

2>> file.log重定向stderr到该文件

其他人都使用and&>>的简写,但我的 mac 和 ubuntu 都不接受它:(stdoutstderr

extra: >覆盖,同时>>追加。

顺便说一句,关于 NodeJS 记录器,我使用pino+pino-pretty记录器


Mar*_*rco 10

如果这是针对应用程序的,那么最好使用日志记录模块.它会给你更多的灵活性.一些建议.

  • 你的log4js链接现在已经破了.这个怎么样?https://github.com/nomiddlename/log4js-node (3认同)
  • 是的,我猜这个项目已经转手了。谢谢。 (2认同)

Mr.*_* 14 9

直接来自控制台上的 Nodejs API 文档

const output = fs.createWriteStream('./stdout.log');
const errorOutput = fs.createWriteStream('./stderr.log');
// custom simple logger
const logger = new Console(output, errorOutput);
// use it like console
const count = 5;
logger.log('count: %d', count);
// in stdout.log: count 5
Run Code Online (Sandbox Code Playgroud)


Sri*_*tha 9

对于简单的情况,我们可以使用'>''2>&1'标准输出 (STDOUT) 和标准错误 (STDERR)流直接重定向到文件(例如 test.log)

例子:

// test.js
(function() {
    // Below outputs are sent to Standard Out (STDOUT) stream
    console.log("Hello Log");
    console.info("Hello Info");
    // Below outputs are sent to Standard Error (STDERR) stream
    console.error("Hello Error");
    console.warn("Hello Warning");
})();
Run Code Online (Sandbox Code Playgroud)

节点 test.js > test.log 2>&1

根据 POSIX 标准,“输入”、“输出”和“错误”流由正整数文件描述符(0、1、2)标识。即,stdin 为 0,stdout 为 1,stderr 为 2。

第 1 步:'2>&1'将从 2 ( stderr )重定向到 1 ( stdout )

第 2 步:“>”将从 1 ( stdout )重定向到文件 ( test.log )


Sim*_*gét 5

覆盖 console.log 是要走的路。但是为了让它在所需的模块中工作,您还需要导出它。

module.exports = console;
Run Code Online (Sandbox Code Playgroud)

为了省去编写日志文件、旋转等的麻烦,你可以考虑使用一个简单的记录器模块,比如 winston:

// Include the logger module
var winston = require('winston');
// Set up log file. (you can also define size, rotation etc.)
winston.add(winston.transports.File, { filename: 'somefile.log' });
// Overwrite some of the build-in console functions
console.error = winston.error;
console.log = winston.info;
console.info = winston.info;
console.debug = winston.debug;
console.warn = winston.warn;
module.exports = console;
Run Code Online (Sandbox Code Playgroud)


rel*_*asn 5

另一个尚未提及的解决方案是将Writable流挂在process.stdout和中process.stderr。这样,您无需覆盖输出到stdout和stderr的所有控制台功能。此实现将stdout和stderr都重定向到日志文件:

var log_file = require('fs').createWriteStream(__dirname + '/log.txt', {flags : 'w'})

function hook_stream(stream, callback) {
    var old_write = stream.write

    stream.write = (function(write) {
        return function(string, encoding, fd) {
            write.apply(stream, arguments)  // comments this line if you don't want output in the console
            callback(string, encoding, fd)
        }
    })(stream.write)

    return function() {
        stream.write = old_write
    }
}

console.log('a')
console.error('b')

var unhook_stdout = hook_stream(process.stdout, function(string, encoding, fd) {
    log_file.write(string, encoding)
})

var unhook_stderr = hook_stream(process.stderr, function(string, encoding, fd) {
    log_file.write(string, encoding)
})

console.log('c')
console.error('d')

unhook_stdout()
unhook_stderr()

console.log('e')
console.error('f')
Run Code Online (Sandbox Code Playgroud)

它应该在控制台中打印

a
b
c
d
e
f
Run Code Online (Sandbox Code Playgroud)

并在日志文件中:

c
d
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请检查此要点