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


当前回答

如果你正在使用forever来保持节点应用程序运行,那么输入forever list将显示console.log正在写入的日志文件的路径

其他回答

对于未来的用户。@keshavDulal答案不适用于最新版本。而且我无法找到针对最新版本3.3.3中报告的问题的适当修复。

不管怎样,在研究了一下之后,我终于把它修好了。下面是温斯顿3.3.3版本的解决方案

安装winston和winston-daily-rotate-file

npm install winston 
npm install winston-daily-rotate-file

创建一个新文件utils/logger.js

const winston = require('winston');
const winstonRotator = require('winston-daily-rotate-file');

var logger = new winston.createLogger({
  transports: [
    new (winston.transports.DailyRotateFile)({
      name: 'access-file',
      level: 'info',
      filename: './logs/access.log',
      json: false,
      datePattern: 'yyyy-MM-DD',
      prepend: true,
      maxFiles: 10
    }),
    new (winston.transports.DailyRotateFile)({
      name: 'error-file',
      level: 'error',
      filename: './logs/error.log',
      json: false,
      datePattern: 'yyyy-MM-DD',
      prepend: true,
      maxFiles: 10
    })
  ]
});


module.exports = {
  logger
};

然后在任何你想要使用日志导入模块的文件

const logger = require('./utils/logger').logger;

像下面这样使用记录器:

logger.info('Info service started');
logger.error('Service crashed');

你也可以重载默认的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');
};

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

编辑:在本页上也可以看到Clément的多参数版本。

除了上面的答案之外,还对覆盖console.log的简短而有效的代码进行了一点扩展。小增加:设置文件名与日期,包装功能,也做原来的控制台。日志记录以保持控制台使用该信息处于活动状态。

用法:在代码的开头,运行setConsoleLogToFile([FILENAME])。

const fs = require("fs"),
    util = require('util');


const getPrettyDate = ()=> new Date().toString().replace(":","-").replace(/00\s\(.*\)/, "").replace(` ${new Date().getFullYear()}`, ",").replace(/:\d\d\s/, " ");

module.exports.getPrettyDate = getPrettyDate;

module.exports.setConsoleLogToFile = (filename) => {
    const log_file = fs.createWriteStream(`${__dirname}/${filename} -  ${getPrettyDate()}.log`, { flags: 'w' }),
        log_stdout = process.stdout;

    const origConsole = console.log;
    console.log = (d) => { 
        origConsole(d);
        log_file.write(util.format(d) + '\n');
        log_stdout.write(util.format(d) + '\n');
    };
}

基于多参数版本的Clément,只是没有颜色代码的文本文件

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 () {
  // Storing without color codes
  logFile.write(util.format.apply(null,arguments).replace(/\033\[[0-9;]*m/g,"") + '\n');
  // Display normally, with colors to Stdout
  logStdout.write(util.format.apply(null, arguments) + '\n');
}

注:回答因为我不能评论

我采用了将输出流交换为我的流的想法。

const LogLater                = require ('./loglater.js');
var logfile=new LogLater( 'log'+( new Date().toISOString().replace(/[^a-zA-Z0-9]/g,'-') )+'.txt' );


var PassThrough = require('stream').PassThrough;

var myout= new PassThrough();
var wasout=console._stdout;
myout.on('data',(data)=>{logfile.dateline("\r\n"+data);wasout.write(data);});
console._stdout=myout;

var myerr= new PassThrough();
var waserr=console._stderr;
myerr.on('data',(data)=>{logfile.dateline("\r\n"+data);waserr.write(data);});
console._stderr=myerr;

loglater.js:

const fs = require('fs');

function LogLater(filename, noduplicates, interval) {
    this.filename = filename || "loglater.txt";
    this.arr = [];
    this.timeout = false;
    this.interval = interval || 1000;
    this.noduplicates = noduplicates || true;
    this.onsavetimeout_bind = this.onsavetimeout.bind(this);
    this.lasttext = "";
    process.on('exit',()=>{ if(this.timeout)clearTimeout(this.timeout);this.timeout=false; this.save(); })
}

LogLater.prototype = {
    _log: function _log(text) {
        this.arr.push(text);
        if (!this.timeout) this.timeout = setTimeout(this.onsavetimeout_bind, this.interval);
    },
    text: function log(text, loglastline) {
        if (this.noduplicates) {
            if (this.lasttext === text) return;
            this.lastline = text;
        }
        this._log(text);
    },
    line: function log(text, loglastline) {
        if (this.noduplicates) {
            if (this.lasttext === text) return;
            this.lastline = text;
        }
        this._log(text + '\r\n');
    },
    dateline: function dateline(text) {
        if (this.noduplicates) {
            if (this.lasttext === text) return;
            this.lastline = text;
        }
        this._log(((new Date()).toISOString()) + '\t' + text + '\r\n');
    },
    onsavetimeout: function onsavetimeout() {
        this.timeout = false;
        this.save();
    },
    save: function save() { fs.appendFile(this.filename, this.arr.splice(0, this.arr.length).join(''), function(err) { if (err) console.log(err.stack) }); }
}

module.exports = LogLater;