温馨提示×

Ubuntu下Node.js日志如何管理

小樊
38
2025-11-11 02:45:25
栏目: 编程语言

Ubuntu下Node.js日志管理指南

在Ubuntu系统中,Node.js日志管理可通过系统级工具(如logrotate)或应用层库(如winstonpino)实现,核心目标是日志分割、压缩、归档进程监控,避免日志文件过大占用磁盘空间,同时便于故障排查。以下是具体方法:

一、使用logrotate系统工具(推荐)

logrotate是Ubuntu自带的日志管理工具,可自动处理Node.js日志的轮转、压缩、删除,无需修改应用代码。

1. 安装logrotate

sudo apt-get update && sudo apt-get install logrotate

2. 配置Node.js日志轮转

创建/etc/logrotate.d/nodejs文件,添加以下内容(按需调整路径):

/var/log/nodejs/*.log {
    daily                # 每天轮转
    missingok            # 日志文件不存在时不报错
    rotate 7             # 保留7个轮转文件
    compress             # 压缩旧日志(gzip)
    delaycompress        # 延迟压缩(避免当天日志被压缩)
    notifempty           # 日志为空时不轮转
    create 640 root adm  # 新日志文件权限(属主root,属组adm)
    sharedscripts        # 所有日志轮转完成后执行脚本
    postrotate
        systemctl restart your-nodejs-app  # 可选:重启应用以释放日志句柄
    endscript
}

3. 测试配置

手动触发轮转(验证配置是否正确):

sudo logrotate -f /etc/logrotate.d/nodejs

日志将按/var/log/nodejs/application-2025-11-11.log.gz格式存储,保留7天。

二、使用PM2进程管理器(适合生产环境)

PM2是Node.js常用进程管理工具,内置日志管理功能,支持实时查看、轮转、远程存储

1. 安装PM2

sudo npm install pm2 -g

2. 启动应用并配置日志

pm2 start app.js --name "my-app" \
    --log /var/log/nodejs/my-app.log \  # 统一日志路径
    --error /var/log/nodejs/my-app-error.log  # 错误日志单独存储

3. 日志管理命令

  • 实时查看日志pm2 logs my-app(按Ctrl+C退出)
  • 查看最近100行pm2 logs my-app --lines 100
  • 导出日志到文件pm2 logs my-app > my-app.log

4. 配置日志轮转

通过ecosystem.config.js自定义轮转策略(推荐):

module.exports = {
  apps: [{
    name: 'my-app',
    script: 'app.js',
    log_date_format: 'YYYY-MM-DD HH:mm Z',  // 日志时间格式
    out_file: '/var/log/nodejs/my-app.log',  // 标准输出路径
    error_file: '/var/log/nodejs/my-app-error.log',  // 错误输出路径
    log_rotation: {  // 轮转配置
      interval: '1d',    // 每天轮转
      size: '10M',       // 单个文件最大10MB
      retain: 7          // 保留7个文件
    }
  }]
};

启动应用:

pm2 start ecosystem.config.js

PM2会自动管理日志轮转,无需额外配置。

三、使用Winston日志库(应用层控制)

Winston是Node.js最流行的结构化日志库,支持多传输(文件、控制台、数据库)、日志分级、轮转,适合需要自定义日志格式的场景。

1. 安装依赖

npm install winston winston-daily-rotate-file

2. 配置日志轮转

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

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }),  // 时间戳
    winston.format.json()  // JSON格式(便于后续分析)
  ),
  transports: [
    // 错误日志(单独文件)
    new DailyRotateFile({
      filename: '/var/log/nodejs/error-%DATE%.log',
      datePattern: 'YYYY-MM-DD',
      zippedArchive: true,  // 压缩旧日志
      maxSize: '20m',       // 单个文件最大20MB
      maxFiles: '14d'       // 保留14天
    }),
    // 普通日志(合并文件)
    new DailyRotateFile({
      filename: '/var/log/nodejs/combined-%DATE%.log',
      datePattern: 'YYYY-MM-DD',
      zippedArchive: true,
      maxSize: '20m',
      maxFiles: '14d'
    }),
    // 开发环境输出到控制台
    process.env.NODE_ENV !== 'production' ? 
      new winston.transports.Console({
        format: winston.format.simple()  // 简单文本格式
      }) : null
  ].filter(Boolean)  // 过滤null值
});

// 使用示例
logger.info('Application started');
logger.error('Database connection failed');

3. 高级配置(可选)

  • 添加自定义传输:如将日志发送到Elasticsearch(需配合winston-elasticsearch库)。
  • 动态调整日志级别:通过logger.level = 'debug'修改当前级别。

四、使用Pino高性能日志库(适合高并发场景)

Pino是Node.js高性能日志库(比Winston快5倍以上),支持JSON格式、流式传输、轮转,适合对性能要求高的应用。

1. 安装依赖

npm install pino pino-pretty pino-daily-rotate-file

2. 配置日志轮转

const pino = require('pino');
const pinoRotate = require('pino-rotate');

const logger = pino({
  level: 'info',
  transport: {
    target: 'pino-rotate',  // 使用pino-rotate插件
    options: {
      period: '1d',         // 每天轮转
      path: '/var/log/nodejs/pino.log',  // 日志路径
      maxsize: '10m',       // 单个文件最大10MB
      maxfiles: '7d',       // 保留7天
      gzip: true            // 压缩旧日志
    }
  }
}, pinoPretty({  // 控制台美化输出(开发环境)
  colorize: true,
  translateTime: 'SYS:standard'
}));

// 使用示例
logger.info('User logged in', { userId: 123 });
logger.error('Invalid request', { statusCode: 400 });

3. 特点

  • 高性能:JSON格式日志可直接被ELK、Splunk等工具解析。
  • 低开销:适合每秒数千次请求的高并发应用。

五、自定义日志分割(高级用法)

若需完全控制日志逻辑,可通过fs模块手动实现(不推荐,仅适用于简单场景)。

示例代码

const fs = require('fs');
const path = require('path');
const moment = require('moment');

const logDir = '/var/log/nodejs';
const logFile = path.join(logDir, 'application.log');

// 确保日志目录存在
if (!fs.existsSync(logDir)) {
  fs.mkdirSync(logDir, { recursive: true });
}

// 轮转函数
function rotateLogs() {
  const now = moment();
  const rotatedFile = path.join(logDir, `application-${now.format('YYYY-MM-DD')}.log`);
  
  if (fs.existsSync(logFile)) {
    fs.renameSync(logFile, rotatedFile);  // 重命名旧日志
  }
  
  // 创建新日志文件
  fs.writeFileSync(logFile, `Log rotated at ${now.format('YYYY-MM-DD HH:mm:ss')}\n`);
}

// 每天00:00执行轮转
setInterval(rotateLogs, 24 * 60 * 60 * 1000);
rotateLogs();  // 立即执行一次

注意事项

  • 需手动处理日志压缩、删除(如调用child_process.exec执行gzip命令)。
  • 不推荐用于生产环境,建议使用logrotate或日志库。

总结

  • 简单场景:使用logrotate(系统级,无需改代码)。
  • 生产环境:使用PM2(进程管理+日志管理一体化)。
  • 自定义需求:使用winstonpino(应用层控制,支持结构化日志)。
  • 高性能场景:优先选择pino(低开销、高吞吐量)。

根据应用规模、性能需求选择合适的方法,确保日志管理高效、可靠。

0