Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 节点:登录文件而不是控制台_Node.js - Fatal编程技术网

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

Node.js 节点:登录文件而不是控制台,node.js,Node.js,我是否可以配置console.log,以便将日志写入文件而不是在控制台中打印?更新2013-这是围绕节点v0.2和v0.4编写的;现在在日志记录方面有了更好的实用程序。我极力推荐 2013年末更新-我们仍然使用winston,但现在有了一个日志库,可以围绕自定义对象和格式的日志记录来包装功能。下面是logger.js的一个示例 应该是这么简单 var access = fs.createWriteStream(dir + '/node.access.log', { flags: 'a' })

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

更新2013-这是围绕节点v0.2和v0.4编写的;现在在日志记录方面有了更好的实用程序。我极力推荐

2013年末更新-我们仍然使用winston,但现在有了一个日志库,可以围绕自定义对象和格式的日志记录来包装功能。下面是logger.js的一个示例


应该是这么简单

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);

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

  • 温斯顿
  • log4js

    • 如果您正在寻找生产中的产品,这可能是最佳选择

      如果您只想快速完成开发工作,请直接输出到文件(我认为这只适用于*nix系统):

      您现在可以使用它,它是一个基于流的日志系统,允许您登录到它,然后通过管道将输出输出输出到不同的变换和位置

      输出到文件非常简单,如下所示:

      var logger = new (require('./').Logger)();
      logger.pipe(require('fs').createWriteStream('./debug.log'));
      logger.log('your log message');
      

      上完成示例您也可以重载默认的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


      编辑:也在本页上。

      我经常使用许多参数来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;
      

      覆盖console.log是一种方法。但要使其在所需的模块中工作,还需要将其导出

      module.exports = console;
      
      < >为了节省你自己编写日志文件、旋转和填充的麻烦,你可以考虑使用一个简单的记录器模块,比如温斯顿:

      // 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;
      

      您还可以查看此npm模块:

      简单明了…

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

      以下是操作指南。
      在项目中安装winston的方式为:

      npm install winston --save
      
      下面是一个现成的配置,我在项目中经常使用它作为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
      };
      
      然后只需在需要时导入,如下所示:

      const errorLog = require('../util/logger').errorlog;
      const successlog = require('../util/logger').successlog;
      
      然后,您可以将成功记录为:

      successlog.info(`Success Message and variables: ${variable}`);
      
      错误如下:

      errorlog.error(`Error Message : ${error}`);
      
      它还将所有成功日志和错误日志记录在日志目录日期下的文件中,如您所见。

      另一个尚未提及的解决方案是通过在
      进程.stdout
      进程.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')
      
      c
      d
      
      它应该在控制台中打印

      a
      b
      c
      d
      e
      f
      
      在日志文件中:

      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')
      
      c
      d
      
      有关更多信息,请查看此

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

      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
      

      直接从nodejs的API文档开始


      我接受了将输出流交换为my流的想法

      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;
      

      改进Andres Riofrio,以处理任意数量的参数

      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(...args) {
          var output = args.join(' ');
          log_file.write(util.format(output) + '\r\n');
          log_stdout.write(util.format(output) + '\r\n');
      };
      

      我只是做了一个包,希望你喜欢;)
      我自己只是简单地从温斯顿那里拿了个例子,添加了
      log(…)
      方法(因为温斯顿把它命名为
      info(…)

      Console.js:

      然后只需在代码中使用:


      现在,您可以简单地使用文件中的普通日志函数,它将创建一个文件并将其记录到您的控制台(在调试/开发时)。由于
      if(process.env.NODE_env!=“production”){
      (如果您希望它也在生产中使用).

      对于简单的情况,我们可以重定向标准输出(STDOUT)和标准错误(STDERR)使用'>''2>&1'

      例如:

      // 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");
      })();
      
      节点test.js>test.log 2>&1

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

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

      步骤2:'>'将从1(stdout)重定向到文件(test.log


      方法标准和标准

      这种方法可以帮助您(我在我的项目中使用类似的方法)并适用于所有方法,包括console.log、console.warn、console.error、console.info

      此方法将stdout和stderr中写入的字节写入文件。这比更改console.log、console.warn、console.error和console.info方法要好,因为输出将与此方法的输出完全相同

      
      var fs= require("fs")
      var os= require("os")
      var HOME= os.homedir()
      var stdout_r = fs.createWriteStream(HOME + '/node.stdout.log', { flags: 'a' })
      var stderr_r = fs.createWriteStream(HOME + '/node.stderr.log', { flags: 'a' })
      
      var attachToLog= function(std, std_new){
      
          var originalwrite= std.write
          std.write= function(data,enc){
              try{
                  var d= data
                  if(!Buffer.isBuffer(d))
                      d= Buffer.from(data, (typeof enc === 'string') ? enc : "utf8")
                  std_new.write.apply(std_new, d)
              }catch(e){}
              return originalwrite.apply(std, arguments)
          }
      
      
      }
      attachToLog(process.stdout, stdout_r)
      attachToLog(process.stderr, stderr_r)
      
      // recommended catch error on stdout_r and stderr_r
      // stdout_r.on("error", yourfunction)
      // stderr_r.on("error", yourfunction)
      

      适用于未来用户。@KeshavDural不适用于最新版本。对于最新版本
      3.3.3
      中报告的问题,我找不到合适的解决方案

      无论如何,我在研究了一点之后终于修复了它。下面是winston版本
      3.3.3

      安装winston和winston每日轮换文件

      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');
      

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

      node server.js >> file.log 2>> file.log
      
      >file.log
      标准输出重定向到文件

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

      其他人对
      stdout
      stderr
      都使用速记
      &>
      ,但我的mac和ubuntu都不接受:(

      额外:
      覆盖,而
      >
      追加


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

      在上面的答案中添加了一个简短而高效的代码覆盖
      console.log
      。小的添加:用日期设置文件名,包装器函数,也做ori
      const logger = require('./utils/logger').logger;
      
      logger.info('Info service started');
      logger.error('Service crashed');
      
      node server.js >> file.log 2>> file.log
      
      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');
          };
      }
      
      import { consoleLogToFile } from "console-log-to-file";
      // or `const { consoleLogToFile } = require("console-log-to-file/dist/index.cjs.js")`
      
      consoleLogToFile({
        logFilePath: "/log/default.log",
      });
      
      // all of your console.log/warn/error/info will work as it does and save to file now.