一个基于 WordPress 搭建的个人技术博客,专注于 Linux 运维、网络架构、自动化运维、虚拟化、GPU 服务器部署及企业级基础设施实践经验分享。
使用systemd定时清理Nginx日志并自动归档到S3
使用systemd定时清理Nginx日志并自动归档到S3

使用systemd定时清理Nginx日志并自动归档到S3

使用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%时触发告警)。
  • 线上指标:
    • S3存储桶文件增长:通过AWS控制台或CLI命令aws s3 ls s3://your-bucket-name/nginx-logs/ --recursive | wc -l 检查文件总数是否按时增加。
    • 系统资源占用:监控脚本运行时的CPU和内存使用,通过systemd-cgtop 查看cgroups资源消耗。

8. 常见坑与排查

  1. S3权限配置错误:脚本上传失败,错误如”Access Denied”。
    • 排查步骤:
      • 运行aws configure list 检查凭证是否正确配置。
      • 测试S3连接:aws s3 ls s3://your-bucket-name,若失败,检查IAM用户权限(需s3:PutObject权限)和桶策略。
      • 使用aws sts get-caller-identity 验证当前身份。
    • 解决:更新AWS凭证或桶策略,确保脚本运行用户有写入权限。
  2. 日志清理时机不当导致数据丢失:误删未归档的新日志。
    • 排查步骤:
      • 在测试环境先运行find /var/log/nginx -name "*.log" -mtime +7find /var/log/nginx -name "*.gz" -mtime +7 预览将被删除的文件列表。
      • 调整LOCAL_RETENTION_DAYS值,确保只删除超过保留天数的旧文件。
    • 解决:在脚本中添加-delete前先打印文件列表,确认无误后再执行删除操作。
  3. systemd timer时间设置错误:任务未按时运行。
    • 排查步骤:
      • 检查timer的OnCalendar格式,使用systemd-analyze calendar "*-*-* 02:00:00" 验证时间表达式。
      • 运行sudo systemctl list-timers --all 查看所有timer状态和下次触发时间。
    • 解决:调试时可将timer改为OnBootSec=5min 测试启动后运行,确认正常后改回定时设置。
  4. 脚本权限问题:以非root用户运行时无法访问日志目录。
    • 排查步骤:
      • 检查service文件中User设置,若为非root,运行sudo -u username ls /var/log/nginx 测试目录访问权限。
      • 查看AWS CLI配置:sudo -u username aws configure list 确保凭证可访问。
    • 解决:保持root用户或为指定用户添加日志目录读权限和AWS配置访问权。

9. 总结(一段)

本文提供了基于systemd的Nginx日志自动化清理与归档方案,通过bash脚本和timer配置,实现定时清理本地旧日志、归档到S3,有效管理磁盘空间并确保数据备份。关键实施建议包括:在测试环境验证清理逻辑避免数据丢失、配置AWS CLI权限后测试S3上传、监控归档文件数和磁盘使用率设置告警。下一步怎么接入业务:将此方案部署到生产服务器,并集成到现有监控系统(如Prometheus)告警中。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

+ 41 = 47