Ubuntu下Node.js日志管理指南
在Ubuntu系统中,Node.js日志管理可通过系统级工具(如logrotate)或应用层库(如winston、pino)实现,核心目标是日志分割、压缩、归档及进程监控,避免日志文件过大占用磁盘空间,同时便于故障排查。以下是具体方法:
logrotate是Ubuntu自带的日志管理工具,可自动处理Node.js日志的轮转、压缩、删除,无需修改应用代码。
sudo apt-get update && sudo apt-get install logrotate
创建/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
}
手动触发轮转(验证配置是否正确):
sudo logrotate -f /etc/logrotate.d/nodejs
日志将按/var/log/nodejs/application-2025-11-11.log.gz格式存储,保留7天。
PM2是Node.js常用进程管理工具,内置日志管理功能,支持实时查看、轮转、远程存储。
sudo npm install pm2 -g
pm2 start app.js --name "my-app" \
--log /var/log/nodejs/my-app.log \ # 统一日志路径
--error /var/log/nodejs/my-app-error.log # 错误日志单独存储
pm2 logs my-app(按Ctrl+C退出)pm2 logs my-app --lines 100pm2 logs my-app > my-app.log通过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是Node.js最流行的结构化日志库,支持多传输(文件、控制台、数据库)、日志分级、轮转,适合需要自定义日志格式的场景。
npm install winston winston-daily-rotate-file
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');
winston-elasticsearch库)。logger.level = 'debug'修改当前级别。Pino是Node.js高性能日志库(比Winston快5倍以上),支持JSON格式、流式传输、轮转,适合对性能要求高的应用。
npm install pino pino-pretty pino-daily-rotate-file
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 });
若需完全控制日志逻辑,可通过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(进程管理+日志管理一体化)。winston或pino(应用层控制,支持结构化日志)。pino(低开销、高吞吐量)。根据应用规模、性能需求选择合适的方法,确保日志管理高效、可靠。