Debian Node.js 日志备份与恢复策略
一 策略总览与分层
二 本地轮转与保留
/var/log/nodejs/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 root adm
sharedscripts
postrotate
# 若以 systemd 管理,推荐:systemctl reload node-app.service
# 若以 PID 文件管理,可用:kill -USR1 $(cat /var/run/node.pid 2>/dev/null) || true
endscript
}
sudo logrotate -d /etc/logrotate.d/nodejssudo logrotate -f /etc/logrotate.d/nodejs三 本地归档与远程备份
#!/usr/bin/env bash
set -Eeuo pipefail
LOG_DIR="/var/log/nodejs"
BACKUP_BASE="/backup/logs"
DATE=$(date +%F)
mkdir -p "$BACKUP_BASE/$DATE"
# 仅归档已轮转的旧日志(避免与正在写入的 current 冲突)
find "$LOG_DIR" -maxdepth 1 -name "*.gz" -mtime -1 -exec cp -p {} "$BACKUP_BASE/$DATE/" \;
# 可选:打包归档
tar -czf "$BACKUP_BASE/nodejs-$DATE.tar.gz" -C "$BACKUP_BASE/$DATE" .
# 清理超过14天的归档
find "$BACKUP_BASE" -maxdepth 1 -type d -mtime +14 -delete
find "$BACKUP_BASE" -maxdepth 1 -name "nodejs-*.tar.gz" -mtime +14 -delete
# 简单成功标记
echo "$(date -Iseconds) backup success" >> "$BACKUP_BASE/backup.log"
rsync -avz --delete /backup/logs/ backup@192.0.2.10:/data/backups/nodejs/
duplicity --full-if-older-than 7D \
--no-encryption \
/backup/logs/ rsync://backup@192.0.2.10//data/backups/nodejs-duplicity/
# 每日 02:00 本地归档
0 2 * * * /usr/local/bin/backup_nodejs_logs.sh
# 每日 03:00 远程同步
0 3 * * * rsync -avz --delete /backup/logs/ backup@192.0.2.10:/data/backups/nodejs/
四 恢复流程与校验
chmod 644 /var/log/nodejs/*.log)。DATE="2025-12-10"
tar -xzf /backup/logs/nodejs-$DATE.tar.gz -C /tmp/restore
cp -p /tmp/restore/*.gz /var/log/nodejs/
# 若应用使用文件句柄写入,必要时触发日志重新打开:
# systemctl reload node-app.service 或 kill -USR1 <node_pid>
rsync -av /backup/logs/nodejs/ /var/log/nodejs/
zcat /var/log/nodejs/app.log.*.gz | head/tail 检查是否可读、时间线是否连续。五 监控告警与演练
groups:
- name: nodejs_logs
rules:
- alert: LargeLogFileSize
expr: nodejs_log_file_size_bytes > 100000000
for: 1h
labels:
severity: warning
annotations:
summary: "日志文件过大"
description: "实例 {{ $labels.instance }} 日志超过 100MB。"
- alert: LogBackupFailed
expr: nodejs_backup_success{job="nodejs-backup"} == 0
for: 15m
labels:
severity: critical
annotations:
summary: "日志备份失败"
description: "节点 {{ $labels.instance }} 最近一次备份未成功。"