温馨提示×

Node.js在Linux上的错误处理如何配置

小樊
45
2025-12-06 13:07:47
栏目: 编程语言

Node.js 在 Linux 上的错误处理与日志配置

一 日志框架与输出策略

  • 使用成熟的日志库,例如 WinstonPinoBunyan,便于设置日志级别(如 error、warn、info、debug)、统一结构化格式(如 JSON)以及多目标输出(控制台、文件、远程)。
  • 在代码层面统一错误日志写法,区分业务日志与错误日志,示例(Winston):
    • 安装:npm i winston
    • 配置:
      • 日志目录:sudo mkdir -p /var/log/nodejs && sudo touch /var/log/nodejs/error.log
      • 权限:sudo chown <nodejs_user>:<nodejs_group> /var/log/nodejs/error.log
    • 代码示例:
      • const winston = require('winston');
        const logger = winston.createLogger({
          level: process.env.LOG_LEVEL || 'error',
          format: winston.format.combine(
            winston.format.timestamp(),
            winston.format.json()
          ),
          transports: [
            new winston.transports.File({ filename: '/var/log/nodejs/error.log', level: 'error' }),
            new winston.transports.File({ filename: '/var/log/nodejs/combined.log' })
          ]
        });
        if (process.env.NODE_ENV !== 'production') {
          logger.add(new winston.transports.Console({ format: winston.format.simple() }));
        }
        // 使用
        logger.error('Unhandled error', { err: err.stack || err });
        
  • Linux 上建议将日志写入 /var/log/nodejs/ 并由应用运行用户持有写权限,便于集中采集与审计。

二 进程管理与标准输出重定向

  • 使用 PM2 管理进程并集中输出日志:
    • 安装:sudo npm i -g pm2
    • 启动:pm2 start app.js --name my_node_app
    • 配置文件 ecosystem.config.js
      • module.exports = {
          apps: [{
            name: 'my_node_app',
            script: 'app.js',
            autorestart: true,
            max_memory_restart: '1G',
            log_date_format: 'YYYY-MM-DD HH:mm:ss',
            out_file: '/var/log/nodejs/my_node_app-out.log',
            error_file: '/var/log/nodejs/my_node_app-error.log',
            combine_logs: false,
            log_level: 'error'
          }]
        };
        // 启动:pm2 start ecosystem.config.js
        
  • PM2 会自动捕获 stdout/stderr,将 console.error 等输出写入指定的 error_file,便于与业务日志分离与检索。

三 未捕获异常与 Promise 拒绝

  • 全局兜底事件(仅用于记录与优雅退出,切勿继续执行业务逻辑):
    • const logger = require('./logger'); // 前述 winston logger
      
      process.on('unhandledRejection', (reason, promise) => {
        logger.error('Unhandled Rejection at:', promise, 'reason:', reason);
        // 重要:记录后退出,避免状态不一致
        process.exit(1);
      });
      
      process.on('uncaughtException', (error) => {
        logger.error('Uncaught Exception:', error);
        // 重要:记录后退出,由进程管理器(如 PM2)重启
        process.exit(1);
      });
      
  • 建议始终配合 PM2autorestart 使用,确保异常退出后自动拉起。

四 日志轮转与保留策略

  • 使用系统自带的 logrotate 做按日/按大小轮转与压缩,避免日志无限增长:
    • 新建配置:/etc/logrotate.d/nodejs-app
    • 示例:
      • /var/log/nodejs/*.log {
          daily
          missingok
          rotate 7
          compress
          notifempty
          create 0640 <nodejs_user> <nodejs_group>
        }
        
  • 可按需调整为 size 100M、保留 30 天等策略,并配合监控告警观察日志增长与写入异常。

五 常见 Linux 层错误与排查要点

  • 资源限制导致的异常(如 EMFILE/ENFILE 打开文件过多、ENOBUFS 缓冲区不足):
    • 检查:ulimit -a
    • 永久调整(示例):编辑 /etc/systemd/system.conf/etc/systemd/user.conf,设置如
      • DefaultLimitNOFILE=1048576
      • DefaultLimitNPROC=65535
      • 修改后执行:sudo systemctl daemon-reexec 或重启系统生效。
  • 子进程输出过多引发 ENOBUFS
    • 避免使用 execSync/spawnSync 处理大输出;改用 spawn 异步流式处理,必要时减少冗余输出(如去掉 tar -v),或设置合适的 stdio
  • 权限与环境问题:
    • 全局安装或写系统目录遇到 EACCES 时,优先修复目录权限或使用 nvm 管理本地 Node;必要时检查 PATH 与运行用户。
  • 版本与依赖不兼容:
    • 使用 nvm 切换合适 Node.js 版本;遇到原生模块编译失败,安装 gcc/开发工具链;依赖缺失执行 npm install <module>

0