logrotate 本身不支持直接上传,必须通过 postrotate 脚本调用 aws s3 cp 等命令实现切后上传;脚本需处理权限、错误忽略、文件名安全、并发与时间戳一致性。

logrotate 本身不支持直接上传,得靠 postrotate 脚本补位
logrotate 的核心职责是切割、压缩、轮转日志,它没有内置 FTP/S3/OSS 等上传能力。真正实现“切完就传”,必须在配置中使用 postrotate 段落执行自定义命令。这个脚本会在每次成功切割后运行,是唯一可靠的上传入口点。
注意:脚本里不能用 sleep 或阻塞操作,否则会拖慢整个 logrotate 流程;也不建议在 prerotate 里上传旧日志——那时文件还没归档,内容可能被应用继续写入,导致上传不完整。
- 确保上传命令(如
aws s3 cp、ossutil cp)已安装且权限可用 - 脚本需以 root 或日志属主身份运行,避免因权限不足跳过上传
- 上传失败不应影响日志切割本身,建议用
|| true或显式忽略错误 - 上传目标路径建议包含日期变量,例如
$(date -d yesterday +\%Y\%m\%d),避免覆盖
配置示例:切割 Nginx 日志并上传到 AWS S3
在 /etc/logrotate.d/nginx 中添加:
/var/log/nginx/*.log {
daily
missingok
rotate 7
compress
delaycompress
notifempty
create 644 www-data www-data
sharedscripts
postrotate
# 仅对刚生成的 .gz 文件上传(避免重复传)
for f in /var/log/nginx/*.log.[0-9]*.gz; do
[ -f "$f" ] && aws s3 cp "$f" s3://my-log-bucket/nginx/$(basename "$f") --quiet || true
done
endscript
}
关键点:sharedscripts 保证所有匹配日志共用一次 postrotate,而不是每个文件都触发一遍;--quiet 避免日志刷屏;$(basename "$f") 保留原始归档名,便于后续按名检索。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
上传失败时怎么排查?别只看 logrotate 输出
logrotate 默认静默运行,postrotate 报错不会打到终端或 syslog,容易误以为“上传成功了”。实际常见问题包括:
-
aws命令未找到:检查PATH,建议写绝对路径/usr/bin/aws - 凭证失效或权限不足:用
sudo -u www-data aws sts get-caller-identity手动验证 - 文件名含空格或特殊字符:用双引号包裹变量,如
"$f",否则 shell 展开会出错 - 上传并发冲突:多个日志同时切割时,
postrotate并发执行,S3 不会报错但可能漏传——加简单锁或改用单次遍历更稳妥
上传后要不要本地清理?取决于云存储 SLA 和恢复需求
默认情况下,logrotate 保留 rotate N 份本地归档。上传完成后是否删本地,得看你的 RTO/RPO 要求:
- 若云存储是唯一备份源,且你信任其持久性(如 S3 Standard),可加
olddir /tmp/logarchive配合rotate 0,让旧日志切完即移走,再由单独脚本统一上传+清理 - 若需本地快速回溯,建议保留至少 1–2 份,上传成功后再用
find /var/log/nginx -name "*.log.*.gz" -mtime +1 -delete定期清理 - 切忌在
postrotate里直接rm刚上传的文件——万一上传中途断网,文件就丢了
最易被忽略的是时区和时间戳错位:logrotate 使用系统本地时间判断 daily,但云存储目录按 UTC 命名可能导致归档混乱。统一用 date -u 或明确指定时区变量,比依赖默认行为更可靠。










