使用systemd定时清理Nginx日志并自动归档到S3
1. 业务场景与目标
企业Nginx服务器每天产生大量访问日志和错误日志,本地存储空间有限,若不定期清理易导致磁盘满,影响服务。同时,日志需长期归档到S3(如AWS S3)备份,供后续审计、安全分析或机器学习使用。目标:自动化执行日志清理与归档,减少人工干预,确保数据不丢失。
2. 环境准备(uv + 依赖)
本方案基于Linux系统(如Ubuntu 20.04+或CentOS 7+),使用systemd和AWS CLI工具。无需uv,直接安装依赖:
- systemd(通常系统自带)
- AWS CLI v2(用于S3操作)
- Nginx(已安装并运行)
安装AWS CLI(如果未安装):
# 下载并安装AWS CLI v2
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install
# 配置AWS凭证(替换your-access-key和your-secret-key)
aws configure set aws_access_key_id your-access-key
aws configure set aws_secret_access_key your-secret-key
aws configure set default.region us-east-1 # 根据实际S3区域设置
3. 数据说明(真实数据口径或模拟数据生成逻辑)
数据为Nginx日志文件,通常位于/var/log/nginx/目录下,包括:
access.log:访问日志,记录每个HTTP请求,格式如$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent"。error.log:错误日志,记录Nginx错误信息。 日志文件可能按天轮转(如access.log-20231001.gz),本方案处理所有.log和.gz文件。假设每天日志量约1GB,需保留最近7天本地日志,更早的归档到S3。
4. 训练/实现步骤(完整代码)
任务类型说明:这是运维自动化任务(非机器学习任务),实现一个bash脚本和systemd配置。
创建脚本/usr/local/bin/nginx-log-archive.sh:
#!/bin/bash
# 脚本:清理并归档Nginx日志到S3
# 作者:实战运维
# 日期:2023-10-01
# 配置变量
LOG_DIR="/var/log/nginx" # Nginx日志目录
S3_BUCKET="s3://your-bucket-name/nginx-logs/" # S3存储桶路径,替换为实际值
LOCAL_RETENTION_DAYS=7 # 本地保留天数
ARCHIVE_DAYS=30 # 归档最近多少天的日志(例如归档30天内未处理的旧日志)
# 步骤1:检查目录和权限
if [ ! -d "$LOG_DIR" ]; then
echo "错误:日志目录 $LOG_DIR 不存在"
exit 1
fi
if ! command -v aws &> /dev/null; then
echo "错误:AWS CLI未安装,请先安装"
exit 1
fi
# 步骤2:清理旧日志文件(保留最近LOCAL_RETENTION_DAYS天)
find "$LOG_DIR" -name "*.log" -mtime +$LOCAL_RETENTION_DAYS -delete
find "$LOG_DIR" -name "*.gz" -mtime +$LOCAL_RETENTION_DAYS -delete
echo "已清理 $LOG_DIR 中超过 $LOCAL_RETENTION_DAYS 天的日志文件"
# 步骤3:归档日志到S3(处理最近ARCHIVE_DAYS天内未归档的.gz文件)
ARCHIVE_COUNT=0
for file in $(find "$LOG_DIR" -name "*.gz" -mtime -$ARCHIVE_DAYS); do
# 提取文件名和日期(假设文件名如access.log-20231001.gz)
filename=$(basename "$file")
# 上传到S3,使用日期子目录
aws s3 cp "$file" "$S3_BUCKET$(date -r "$file" +%Y/%m/%d)/$filename"
if [ $? -eq 0 ]; then
echo "已归档: $file 到 S3"
ARCHIVE_COUNT=$((ARCHIVE_COUNT + 1))
# 可选:上传后删除本地文件以节省空间(谨慎操作)
# rm "$file"
else
echo "警告:归档失败: $file"
fi
done
# 步骤4:输出指标
echo "归档完成。本次归档文件数: $ARCHIVE_COUNT"
# 记录到系统日志,供监控
logger -t nginx-log-archive "归档Nginx日志到S3,处理文件数: $ARCHIVE_COUNT"
exit 0
设置脚本权限:
sudo chmod +x /usr/local/bin/nginx-log-archive.sh
创建systemd service文件/etc/systemd/system/nginx-log-archive.service:
[Unit]
Description=Archive Nginx logs to S3
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/nginx-log-archive.sh
User=root
# 限制资源使用(可选)
MemoryLimit=100M
CPUQuota=50%
[Install]
WantedBy=multi-user.target
创建systemd timer文件/etc/systemd/system/nginx-log-archive.timer:
[Unit]
Description=Run nginx-log-archive daily
Requires=nginx-log-archive.service
[Timer]
# 每天凌晨2点运行
OnCalendar=*-*-* 02:00:00
Persistent=true
[Install]
WantedBy=timers.target
启用并启动timer:
sudo systemctl daemon-reload
sudo systemctl enable nginx-log-archive.timer
sudo systemctl start nginx-log-archive.timer
# 检查timer状态
sudo systemctl status nginx-log-archive.timer
5. 调用方式(离线批量 + 单条示例,至少一种)
- 离线批量:通过systemd timer自动定时调用,如上配置每天凌晨2点运行。
- 单条示例:手动执行脚本进行测试或立即归档。
# 手动运行一次归档 sudo /usr/local/bin/nginx-log-archive.sh # 或通过systemd service sudo systemctl start nginx-log-archive.service
6. 指标说明(运维自动化指标)
本任务使用以下运维指标:
- 归档文件数:每次脚本运行时成功归档到S3的日志文件数量,直接反映任务执行效果,目标应大于0(表示有文件处理)。
- 归档成功率:成功归档文件数 / 尝试归档文件总数,用于监控S3连接或权限问题,目标接近100%。
- 磁盘使用率:Nginx日志目录所在磁盘的使用百分比,通过清理旧日志控制,目标低于阈值(如80%)。 适用场景:监控自动化任务是否正常运行,确保日志备份和磁盘空间管理。
7. 上线后评估
- 离线监控:
- 检查systemd timer和service状态:
sudo systemctl status nginx-log-archive.timer应显示active,上次运行时间正常;sudo systemctl list-timers查看下次运行时间。 - 查看脚本日志:通过
journalctl -u nginx-log-archive.service -f实时跟踪,或journalctl -u nginx-log-archive.service --since "2023-10-01"查看历史,确认归档文件数和错误信息。 - 监控磁盘使用率:使用
df -h /var/log定期检查,设置告警阈值(如>85%时触发告警)。
- 检查systemd timer和service状态:
- 线上指标:
- S3存储桶文件增长:通过AWS控制台或CLI命令
aws s3 ls s3://your-bucket-name/nginx-logs/ --recursive | wc -l检查文件总数是否按时增加。 - 系统资源占用:监控脚本运行时的CPU和内存使用,通过
systemd-cgtop查看cgroups资源消耗。
- S3存储桶文件增长:通过AWS控制台或CLI命令
8. 常见坑与排查
- S3权限配置错误:脚本上传失败,错误如”Access Denied”。
- 排查步骤:
- 运行
aws configure list检查凭证是否正确配置。 - 测试S3连接:
aws s3 ls s3://your-bucket-name,若失败,检查IAM用户权限(需s3:PutObject权限)和桶策略。 - 使用
aws sts get-caller-identity验证当前身份。
- 运行
- 解决:更新AWS凭证或桶策略,确保脚本运行用户有写入权限。
- 排查步骤:
- 日志清理时机不当导致数据丢失:误删未归档的新日志。
- 排查步骤:
- 在测试环境先运行
find /var/log/nginx -name "*.log" -mtime +7和find /var/log/nginx -name "*.gz" -mtime +7预览将被删除的文件列表。 - 调整
LOCAL_RETENTION_DAYS值,确保只删除超过保留天数的旧文件。
- 在测试环境先运行
- 解决:在脚本中添加
-delete前先打印文件列表,确认无误后再执行删除操作。
- 排查步骤:
- systemd timer时间设置错误:任务未按时运行。
- 排查步骤:
- 检查timer的
OnCalendar格式,使用systemd-analyze calendar "*-*-* 02:00:00"验证时间表达式。 - 运行
sudo systemctl list-timers --all查看所有timer状态和下次触发时间。
- 检查timer的
- 解决:调试时可将timer改为
OnBootSec=5min测试启动后运行,确认正常后改回定时设置。
- 排查步骤:
- 脚本权限问题:以非root用户运行时无法访问日志目录。
- 排查步骤:
- 检查service文件中
User设置,若为非root,运行sudo -u username ls /var/log/nginx测试目录访问权限。 - 查看AWS CLI配置:
sudo -u username aws configure list确保凭证可访问。
- 检查service文件中
- 解决:保持root用户或为指定用户添加日志目录读权限和AWS配置访问权。
- 排查步骤:
9. 总结(一段)
本文提供了基于systemd的Nginx日志自动化清理与归档方案,通过bash脚本和timer配置,实现定时清理本地旧日志、归档到S3,有效管理磁盘空间并确保数据备份。关键实施建议包括:在测试环境验证清理逻辑避免数据丢失、配置AWS CLI权限后测试S3上传、监控归档文件数和磁盘使用率设置告警。下一步怎么接入业务:将此方案部署到生产服务器,并集成到现有监控系统(如Prometheus)告警中。