一、选择合适的日志库
日志库是日志分析的基础,需根据应用场景(如性能、结构化需求)选择。常用库包括:
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({ format: winston.format.simple() }) // 开发环境输出到控制台
]
});
二、规范日志级别与格式
logger.error('Database connection failed'); // 关键错误
logger.warn('High memory usage detected'); // 潜在问题
logger.info('User logged in successfully'); // 常规操作
{
"timestamp": "2025-11-05T12:00:00Z",
"level": "error",
"message": "Failed to fetch user data",
"userId": "123",
"requestId": "abc-xyz",
"stack": "Error: ENOENT, open '/data/user/123.json'"
}
Winston和Bunyan默认支持JSON格式,Pino则强制使用JSON,确保日志一致性。三、实施日志轮换与管理
日志文件过大会占用大量磁盘空间,需通过日志轮换(Log Rotation)定期分割、压缩和删除旧日志。常用工具:
/etc/logrotate.d/nodejs):/var/log/nodejs/*.log {
daily # 每天轮换
missingok # 忽略缺失文件
rotate 7 # 保留7天日志
compress # 压缩旧日志(gzip)
notifempty # 空日志不轮换
create 0640 root adm # 新日志权限
sharedscripts # 所有日志轮换完成后执行脚本
postrotate
systemctl restart myapp > /dev/null 2>&1 || true # 重启应用(如PM2)以重新打开日志文件
endscript
}
pm2 logs命令实时查看日志,或用pm2-logrotate插件自动轮换:pm2 install pm2-logrotate
pm2 set pm2-logrotate:max_size 10M # 单个日志文件最大10MB
pm2 set pm2-logrotate:retain 7 # 保留7个日志文件
日志轮换可防止日志文件无限增长,确保系统稳定。四、集中式日志存储与分析
对于分布式系统或多节点应用,需将日志集中存储以便统一分析。常用方案:
nodejs.conf):input {
file {
path => "/var/log/nodejs/*.log"
start_position => "beginning"
sincedb_path => "/dev/null" # 测试环境忽略sincedb
}
}
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:loglevel} %{GREEDYDATA:message}" }
}
date {
match => ["timestamp", "ISO8601"]
target => "@timestamp"
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "nodejs-logs-%{+YYYY.MM.dd}"
}
stdout { codec => rubydebug } # 测试环境输出到控制台
}
五、实时监控与告警
实时监控日志可快速发现系统问题(如错误激增、性能下降),常用工具:
sudo apt install logwatch
sudo logwatch --output mail --mailto admin@example.com --service all # 每日发送报告
六、自动化与性能优化
0 2 * * * find /var/log/nodejs -name "*.log" -mtime +7 -exec rm {} \;
Async传输或Pino的异步模式,避免日志写入阻塞主线程,提升应用性能。例如Winston的Async配置:const { createAsyncLogger } = require('winston');
const asyncTransport = new winston.transports.File({ filename: 'async.log' });
const logger = createAsyncLogger({
transports: [asyncTransport]
});
七、敏感信息处理
日志中可能包含敏感信息(如用户密码、信用卡号),需进行脱敏处理:
app.use((req, res, next) => {
if (req.body.password) {
req.body.password = '*****'; // 替换密码
}
next();
});
const winston = require('winston');
const sanitize = require('sanitize-json');
const logger = winston.createLogger({
transports: [new winston.transports.Console()],
format: winston.format.combine(
winston.format.json(),
winston.format((info) => {
info.message = sanitize(info.message); // 脱敏处理
return info;
})()
)
});
敏感信息处理可避免日志泄露,符合安全规范。