温馨提示×

Node.js在Debian上日志记录最佳实践

小樊
58
2025-09-27 07:51:31
栏目: 编程语言

Node.js在Debian上日志记录最佳实践

1. 选择合适的日志库

根据项目需求选型:

  • Winston:功能全面,支持多传输(文件、控制台、远程服务)、自定义格式,适合需要灵活配置的场景;
  • Pino:高性能(JSON序列化快),适合高吞吐量生产环境;
  • Bunyan:结构化JSON输出,自带CLI工具,便于日志解析;
  • Log4js:类似Java log4j,支持数据库、邮件等输出,适合复杂需求。
    示例(Winston):
const winston = require('winston');
const logger = winston.createLogger({
  level: 'info',
  format: winston.format.json(),
  transports: [
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' }),
    new winston.transports.Console()
  ]
});

示例(Pino):

const pino = require('pino')();
pino.info({ event: 'user_login', userId: 123 }, 'User logged in');

2. 合理配置日志级别

按环境区分级别,避免不必要的磁盘占用:

  • 开发环境debug(详细调试信息);
  • 测试环境info(关键流程)+ warn(潜在问题);
  • 生产环境warn(错误预警)+ error(实际错误)。
    通过环境变量动态设置:
const level = process.env.NODE_ENV === 'production' ? 'warn' : 'debug';
const logger = winston.createLogger({ level });

3. 实现日志轮转

防止日志文件过大,推荐使用logrotate(Debian自带):

  • 安装:sudo apt-get install logrotate
  • 创建配置文件/etc/logrotate.d/nodejs
    /var/log/nodejs/*.log {
      daily          # 每天轮转
      rotate 7       # 保留7份
      compress       # 压缩旧日志
      delaycompress  # 延迟压缩(避免当天压缩失败)
      missingok      # 文件丢失不报错
      notifempty     # 空文件不轮转
      create 640 root adm  # 新日志权限
      sharedscripts  # 所有日志轮转后执行一次
      postrotate
        systemctl restart your-node-app  # 通知应用重新打开日志(如systemd服务)
      endscript
    }
    
  • 测试配置:sudo logrotate -f /etc/logrotate.d/nodejs

4. 集中式日志管理

对于分布式系统,使用ELK Stack(Elasticsearch+Logstash+Kibana)或Graylog集中存储、分析日志:

  • 通过Winston的winston-elasticsearch传输或Bunyan的bunyan-syslog库,将日志发送至中央服务器;
  • 利用Kibana/Graylog的可视化功能,快速定位问题(如请求延迟、错误趋势)。

5. 异步日志记录

避免日志写入阻塞主线程,影响应用性能:

  • Winston、Pino均默认支持异步(如Winston的transports.File使用fs.createWriteStream异步写入);
  • 避免同步方法(如fs.writeFileSync),除非需要确保日志立即写入(如崩溃前的关键日志)。

6. 结构化日志格式

使用JSON格式,便于后续自动化处理(如解析、过滤、聚合):

logger.info({ 
  event: 'order_created', 
  orderId: 456, 
  amount: 100.00,
  user: 'user123'
}, 'Order created successfully');

结构化日志可通过工具(如Logstash)提取字段,生成报表或告警。

7. 敏感信息过滤

避免日志泄露用户隐私或系统敏感数据(如密码、API密钥):

  • 使用中间件(如Express的helmet)过滤请求体中的敏感字段;
  • 自定义Winston格式,移除敏感信息:
    const sanitize = (info) => {
      if (info.message.includes('password')) {
        info.message = info.message.replace(/password=[^&]+/, 'password=*****');
      }
      return info;
    };
    const logger = winston.createLogger({
      format: winston.format.combine(winston.format.json(), winston.format(customFormat(sanitize)))
    });
    

8. 监控与告警

设置日志监控,及时发现异常:

  • 使用Prometheus+Grafana监控日志指标(如错误率、请求延迟);
  • 通过ELK的告警功能(如Watcher)或Sentry,在出现error级别日志时发送邮件/Slack通知。

9. 进程管理器集成

使用PM2管理Node.js进程,简化日志操作:

  • 安装:npm install pm2 -g
  • 启动应用:pm2 start app.js --name "my-node-app"
  • 日志管理:
    pm2 logs my-node-app          # 查看实时日志
    pm2 logs --lines 100          # 查看最近100行
    pm2 logrotate                 # 执行日志轮转(默认保留7天,每文件10M)
    pm2 save                      # 保存当前进程列表
    

PM2会自动将日志输出到~/.pm2/logs/目录,并支持日志轮转。

10. 系统日志集成

将Node.js日志发送到Debian系统日志(rsyslog/journald),统一管理:

  • 使用winston-syslog库:
    const winston = require('winston');
    require('winston-syslog').Syslog;
    const logger = winston.createLogger({
      transports: [
        new winston.transports.Syslog({
          host: 'localhost',
          port: 514,
          protocol: 'udp',
          facility: 'local0',
          appName: 'my-node-app'
        })
      ]
    });
    
  • 配置rsyslog/etc/rsyslog.conf):
    if $programname == 'my-node-app' then /var/log/nodejs/app.log
    & stop
    

重启rsyslogsudo systemctl restart rsyslog

0