1. 选择合适的日志库
Node.js生态中有多个成熟的日志库,可根据需求选择:
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(), // 结构化日志
transports: [
new winston.transports.Console(), // 控制台输出
new winston.transports.File({ filename: 'error.log', level: 'error' }), // 错误日志单独存储
new winston.transports.File({ filename: 'combined.log' }) // 所有日志合并
]
});
2. 配置合理的日志级别
根据环境调整日志级别,避免无关日志占用资源:
debug或trace级别,记录详细信息(如请求参数、数据库查询),便于调试;error或warn级别,仅记录错误和警告信息,减少日志体积。const logger = winston.createLogger({
level: process.env.NODE_ENV === 'production' ? 'error' : 'debug', // 生产环境仅记录error
// ...其他配置
});
3. 实现日志轮转与压缩
防止日志文件过大导致磁盘空间耗尽,推荐使用winston-daily-rotate-file库或Ubuntu系统工具logrotate:
const { DailyRotateFile } = require('winston-daily-rotate-file');
const logger = winston.createLogger({
transports: [
new DailyRotateFile({
filename: 'application-%DATE%.log', // 按日期命名(如application-2025-11-04.log)
datePattern: 'YYYY-MM-DD', // 日期格式
zippedArchive: true, // 自动压缩旧日志(.gz格式)
maxSize: '20m', // 单个日志文件最大20MB
maxFiles: '14d' // 保留14天内的日志
})
]
});
/etc/logrotate.d/nodejs文件,添加以下内容:/var/log/nodejs/*.log {
daily # 每天轮转
rotate 7 # 保留7天
compress # 压缩旧日志
missingok # 文件不存在时不报错
notifempty # 日志为空时不轮转
create 0640 root adm # 新日志文件权限
}
4. 集中式日志管理
将日志发送到集中式系统(如ELK Stack、Graylog),便于统一存储、搜索和分析:
const { ElasticsearchTransport } = require('winston-elasticsearch');
const logger = winston.createLogger({
transports: [
new ElasticsearchTransport({
client: {
host: 'http://localhost:9200', // Elasticsearch地址
logLevel: 'info'
}
})
]
});
pm2 logs命令实时查看所有应用的日志。5. 异步日志记录
避免同步日志写入阻塞主线程,影响应用性能。大多数日志库(如Winston、Pino)默认支持异步,无需额外配置。示例(Winston异步写入):
const logger = winston.createLogger({
transports: [
new winston.transports.File({ filename: 'async.log' }) // 默认异步
]
});
6. 结构化日志格式
使用JSON格式记录日志,便于后续通过工具(如ELK、Grafana)解析和分析。示例(Winston JSON格式化):
const logger = winston.createLogger({
format: winston.format.combine(
winston.format.timestamp(), // 添加时间戳
winston.format.json() // 转换为JSON格式
),
transports: [
new winston.transports.File({ filename: 'structured.log' })
]
});
// 输出示例:{"timestamp":"2025-11-04T12:00:00.000Z","level":"info","message":"Server started"}
7. 监控与报警
结合监控工具(如Prometheus+Grafana、ELK Alerts)实时监控日志,设置报警阈值(如错误日志数量超过10条/分钟时触发邮件报警)。示例(Prometheus监控Node.js指标):
const promClient = require('prom-client');
const httpRequestDurationMicroseconds = new promClient.Histogram({
name: 'http_request_duration_ms',
help: 'Duration of HTTP requests in ms',
buckets: [0.1, 5, 15, 50, 100, 200, 500] // 桶边界
});
// 在路由中记录指标
app.use((req, res, next) => {
const start = Date.now();
res.on('finish', () => {
httpRequestDurationMicroseconds.observe({
method: req.method,
path: req.path,
status: res.statusCode
}, Date.now() - start);
});
next();
});
8. 安全性保障
winston-deny库过滤特定字段;0640),仅允许必要用户访问日志文件;