Debian JS日志自动化处理方案
一 架构与总体思路
二 应用侧结构化与本地轮转
// logger.js
const { createLogger, format, transports } = require('winston');
const { combine, timestamp, errors, json } = format;
const logger = createLogger({
level: 'info',
format: combine(timestamp(), errors({ stack: true }), json()),
transports: [
new transports.File({ filename: 'logs/app.log', maxsize: 10*1024*1024, maxFiles: 7 }), // 10MB/文件,保留7个
new transports.File({ filename: 'logs/error.log', level: 'error', maxsize: 10*1024*1024, maxFiles: 30 })
],
exceptionHandlers: [new transports.File({ filename: 'logs/exceptions.log' })],
rejectionHandlers: [new transports.File({ filename: 'logs/rejections.log' })]
});
module.exports = logger;
sudo npm i -g pm2
pm2 start app.js -o out.log -e err.log --name myapp
pm2 logs myapp
三 系统级轮转与清理
/path/to/nodejs/logs/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0644 node node
sharedscripts
postrotate
systemctl reload myapp >/dev/null 2>&1 || true
endscript
}
sudo logrotate -d /etc/logrotate.d/nodejs # 语法检查
sudo logrotate -f /etc/logrotate.d/nodejs # 强制执行一次
sudo journalctl --vacuum-time=7d
sudo journalctl --vacuum-size=500M
四 集中式采集与分析
:programname, isequal, "nodejs" /var/log/nodejs/app.log
& stop
sudo systemctl restart rsyslog<source>
@type tail
path /path/to/nodejs/logs/app.log
pos_file /var/log/fluentd-nodejs.log.pos
tag nodejs
<parse>
@type json
</parse>
</source>
<match nodejs>
@type stdout
</match>
input { file { path => "/path/to/nodejs/logs/app.log" start_position => "beginning" } }
filter { }
output { elasticsearch { hosts => ["localhost:9200"] index => "js-logs-%{+YYYY.MM.dd}" } }
五 定时分析与告警脚本
// analyze.js
const fs = require('fs');
const path = require('path');
const file = path.join(__dirname, 'logs', 'app.log');
const out = path.join(__dirname, 'reports', `err-summary-${Date.now()}.txt`);
fs.readFile(file, 'utf8', (err, data) => {
if (err) return console.error('Read error:', err);
const errs = data.split('\n').filter(l => l && l.includes('"level":"error"'));
const summary = [`[${new Date().toISOString()}] 错误数: ${errs.length}`];
if (errs.length) summary.push(...errs.slice(0, 50));
fs.mkdirSync(path.dirname(out), { recursive: true });
fs.writeFileSync(out, summary.join('\n'));
// 可扩展:集成邮件/企业微信/钉钉 Webhook 推送
});
# 每天 02:00 分析,00:00 清理7天前报告
0 2 * * * /usr/bin/node /opt/scripts/analyze.js >> /var/log/log-analyze.log 2>&1
0 0 * * * find /opt/scripts/reports -type f -mtime +7 -delete