正确备份 Nginx 日志:从基础到自动化

发布: (2025年12月16日 GMT+8 11:18)
5 min read
原文: Dev.to

I’m happy to help translate the article, but I’ll need the full text you’d like translated. Could you please paste the article content (excluding the source line you already provided) here? Once I have that, I’ll translate it into Simplified Chinese while preserving the formatting, markdown, and code blocks as requested.

什么是 Nginx 日志以及它们为何重要

Nginx 为它处理的每个请求生成日志。默认情况下,这些日志存储在:

/var/log/nginx/

最重要的两个文件是:

  • access.log – 记录 Nginx 提供的每个 HTTP 请求。
  • error.log – 记录 Nginx 在处理请求时遇到的问题。

访问日志

示例条目:

43.202.80.217 - - [16/Dec/2025:02:14:10 +0000] "GET /news/latest HTTP/1.1" 200 5421 "-" "Mozilla/5.0"

它告诉你的信息:

字段含义
客户端 IP 地址请求来源
日期和时间接收请求的时间
请求的 URL被访问的资源
HTTP 状态码请求结果(200、404、…)
响应大小发送给客户端的字节数
用户代理浏览器、机器人或爬虫

用途: 流量分析、带宽估算、机器人检测、页面浏览量分析、成本估算等。

错误日志

示例条目:

connect() failed (111: Connection refused) while connecting to upstream

用途: 调试后端故障、查找配置错误、诊断宕机和性能问题。

为什么日志轮转至关重要

日志会持续增长。如果不加管理:

  • 磁盘空间被占满 → 服务器性能下降。
  • 历史数据丢失 → 失去宝贵的审计信息。

日志轮转:

  • 将日志拆分为每日(或基于大小)的块。
  • 压缩旧日志。
  • 删除非常旧的日志。

在大多数 Linux 系统中,这由 logrotate 处理。一个典型的 Nginx 配置(/etc/logrotate.d/nginx)如下所示:

/var/log/nginx/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    postrotate
        invoke-rc.d nginx rotate
    endscript
}

这意味着什么

  • 日志每日轮转。
  • 旧日志被压缩(.gz)。
  • 保留 14 天的日志。
  • 轮转后会通知 Nginx。

轮转后的文件示例:

access.log.1
access.log.2.gz
access.log.3.gz

备份策略

手动复制(小型项目)

scp user@server:/var/log/nginx/access.log.2.gz .

限制: 手动、不可扩展、容易丢失。

云存储(推荐)

耐用、低成本、易于检索。常见选项:

  • Amazon S3
  • Google Cloud Storage
  • Azure Blob Storage

如果你的服务器运行在 AWS 上,将日志上传到同一区域的 S3 成本极低,并提供 11 个 9 的耐久性以及生命周期规则实现自动删除。

建议的 S3 结构

s3://nginx-logs/
└── 16-12-2025/
    └── ip-172-31-44-115/
        ├── access.log.2.gz
        ├── access.log.3.gz
        └── error.log.2.gz
  • 按日期分组日志。
  • 支持多台服务器。
  • 简化自动化。

自动备份到 S3

创建脚本,例如 /usr/local/bin/nginx_log_backup.sh

#!/bin/bash
set -e

LOG_DIR="/var/log/nginx"
BUCKET="s3://nginx-logs"
DATE=$(date +%d-%m-%Y)
HOST=$(hostname)

aws s3 sync "$LOG_DIR" \
  "$BUCKET/$DATE/$HOST/" \
  --exclude "*" \
  --include "*.gz"

使其可执行:

sudo chmod +x /usr/local/bin/nginx_log_backup.sh

使用 cron 调度

由于 logrotate 在 00:00 UTC 运行,请在稍后安排备份:

sudo crontab -e

添加以下行:

30 0 * * * /usr/local/bin/nginx_log_backup.sh >> /var/log/nginx_backup.log 2>&1

此操作的作用

  • 每日 00:30 UTC 运行,确保日志已完成轮转。
  • 将标准输出和错误同时记录到 /var/log/nginx_backup.log

验证备份

# 列出本地已轮转的日志
ls -lh /var/log/nginx/*.gz

# 手动运行脚本(用于测试)
sudo /usr/local/bin/nginx_log_backup.sh

# 列出已上传的对象
aws s3 ls s3://nginx-logs/$(date +%d-%m-%Y)/$(hostname)/ --recursive

# 检查 cron 活动
grep CRON /var/log/syslog

# 查看备份日志
tail /var/log/nginx_backup.log

常见的陷阱及避免方法

陷阱解决办法
备份活动的 access.log 而不是已旋转的 .gz 文件在日志轮转后进行备份(例如,00:30 UTC)。
忘记在类似 cron 的环境中测试脚本手动执行脚本并检查日志。
未捕获 cron 输出如上所示,将输出重定向到日志文件。
缺少 S3 生命周期规则配置生命周期策略以删除超过所需保留时间的日志。

设置的优势

  • 可靠、低成本且可审计的日志存储。
  • 支持流量分析、成本估算、滥用检测和可靠性提升。
  • 使用最小化技术栈:Nginx → logrotate → shell 脚本 → cron → Amazon S3。

日志不是噪声——它们是有价值的数据。请相应地对待它们。

Back to Blog

相关文章

阅读更多 »