温馨提示×

Linux系统中Node.js日志如何管理

小樊
38
2025-12-30 03:36:04
栏目: 编程语言

Linux系统中Node.js日志管理

一 核心方案与工具

  • 日志库选型:优先使用结构化日志库,便于检索与分析。常见选择包括:Winston(多传输、易配置)、Pino(高性能)、Bunyan(默认 JSON 输出)、Log4js(功能丰富、可配置多输出与轮转)。
  • 运行与系统层:使用 PM2 做进程守护与日志聚合/轮转;在 systemd 场景用 journalctl 查看与过滤服务日志;使用 rsyslog 将日志发往远程日志服务器。
  • 系统级轮转:用 logrotate 按天/按大小切割、压缩与清理日志,避免磁盘被占满。
  • 集中式与可视化:小规模可用 ELK Stack(Elasticsearch、Logstash、Kibana);轻量方案可用 Grafana Loki + Promtail;也可选 Graylog 或商业 Splunk

二 快速落地示例

  • 使用 Winston 输出到控制台与文件(按级别分流)

    // logger.js
    const winston = require('winston');
    
    const logger = winston.createLogger({
      level: process.env.LOG_LEVEL || 'info',
      format: winston.format.combine(
        winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),
        winston.format.errors({ stack: true }),
        winston.format.splat(),
        winston.format.json()
      ),
      transports: [
        new winston.transports.File({ filename: 'logs/error.log', level: 'error' }),
        new winston.transports.File({ filename: 'logs/combined.log' })
      ]
    });
    
    if (process.env.NODE_ENV !== 'production') {
      logger.add(new winston.transports.Console({
        format: winston.format.combine(
          winston.format.colorize(),
          winston.format.simple()
        )
      }));
    }
    
    module.exports = logger;
    

    运行与级别控制:LOG_LEVEL=debug node app.js

  • 使用 Pino 高性能输出(开发环境美化)

    // logger-pino.js
    const pino = require('pino');
    
    const logger = pino(
      {
        level: process.env.LOG_LEVEL || 'info',
        timestamp: pino.stdTimeFunctions.isoTime
      },
      pino.destination('./logs/app.log')
    );
    
    // 开发时可在控制台美化输出
    if (process.env.NODE_ENV !== 'production') {
      const pretty = require('pino-pretty');
      logger.info = (...args) => require('pino').info(pretty({ colorize: true }), ...args);
    }
    
    module.exports = logger;
    
  • 使用 Log4js 按日期滚动

    // logger-log4js.js
    const log4js = require('log4js');
    
    log4js.configure({
      appenders: {
        out: { type: 'stdout' },
        app: {
          type: 'dateFile',
          filename: 'logs/app',
          pattern: 'yyyy-MM-dd.log',
          alwaysIncludePattern: true,
          daysToKeep: 90,
          compress: true
        }
      },
      categories: {
        default: { appenders: ['out', 'app'], level: 'info' }
      }
    });
    
    const logger = log4js.getLogger();
    module.exports = logger;
    

三 日志轮转与保留策略

  • 系统级方案 logrotate(推荐与 Node.js 解耦)
    创建配置 /etc/logrotate.d/nodejs-app

    /path/to/your/nodejs/logs/*.log {
      daily
      rotate 7
      compress
      delaycompress
      missingok
      notifempty
      create 640 root adm
      sharedscripts
      postrotate
        # 若你的进程支持 USR1 触发重新打开日志,可在此发送信号
        # [ ! -f /var/run/nodeapp.pid ] || kill -USR1 $(cat /var/run/nodeapp.pid)
      endscript
    }
    

    测试与强制执行:
    sudo logrotate -d /etc/logrotate.d/nodejs-app(语法检查)
    sudo logrotate -f /etc/logrotate.d/nodejs-app(强制执行一次)

  • 应用内方案(库自带轮转)
    Winston + winston-daily-rotate-file:

    const DailyRotateFile = require('winston-daily-rotate-file');
    const transport = new DailyRotateFile({
      filename: 'logs/application-%DATE%.log',
      datePattern: 'YYYY-MM-DD',
      zippedArchive: true,
      maxSize: '20m',
      maxFiles: '14d'
    });
    

    Log4js dateFile 已在上一节示例中展示(支持 daysToKeepcompress 等)。

  • 何时选择哪种方案

    • 系统级:与运行时解耦、统一运维策略、适合多进程/多实例
    • 应用级:更细粒度控制(按大小/时间/压缩策略)、便于随应用打包与迁移。

四 运行方式与系统日志集成

  • 使用 PM2 管理进程与日志
    安装与启动:sudo npm install -g pm2,然后 pm2 start app.js --name my-app
    查看日志:pm2 logs my-app;按文件输出可在配置中指定 error_fileout_file
    内置日志轮转插件:
    pm2 install pm2-logrotate
    常用设置示例:
    pm2 set pm2-logrotate:max_size 10M
    pm2 set pm2-logrotate:retain 5
    pm2 set pm2-logrotate:workerInterval 2

  • 使用 systemd + journalctl
    以服务运行 Node.js 应用后,使用 journalctl -u nodeapp 查看日志,-f 实时跟踪,--since/--until 时间过滤。

五 生产实践与注意事项

  • 始终使用结构化日志(JSON),便于 ELK/EFK/Loki 等系统解析与检索;在开发环境可接入美化工具提升可读性。
  • 采用按级别分流:将 error 单独写入错误日志,便于告警与快速定位;info/warn 写入综合日志。
  • 规范日志字段:包含 timestamp、level、service/name、trace_id/request_id、msg、err.stack 等上下文,避免记录敏感信息(如密码、密钥)。
  • 做好保留与压缩策略:结合磁盘容量设置 rotate 7/14/30、compress,定期清理历史日志。
  • 避免仅用 console.log:在生产使用成熟日志库,确保可配置、可扩展、可观测性一致。
  • 若应用为多进程/多实例,优先采用系统级 logrotatePM2 日志机制,减少应用内文件句柄竞争与轮转不一致问题。

0