方案介绍
本文档介绍一种 基于 Rsync 的集中式 Nginx 日志中心方案,适用于多台业务服务器统一收集访问日志,并在日志中心完成自动轮转与留存。
整体思路:
日志中心部署 rsync daemon,仅负责接收与存储日志
客户端周期性推送指定日志文件
日志轮转仅在日志中心执行,避免多端轮转冲突
一键脚本设置
curl -sS -O https://raw.githubusercontent.com/woniu336/open_shell/main/nginx_log_manager.sh && chmod +x nginx_log_manager.sh && ./nginx_log_manager.sh
客户端主机名
hostname -s
客户端查看日志
cd /var/log/nginx
du -h * | sort -h
日志中心服务器配置
放行防火墙,例如
ufw allow 8873/tcp
然后执行以下脚本
curl -sS -O https://raw.githubusercontent.com/woniu336/open_shell/main/rsync-log.sh && chmod +x rsync-log.sh && ./rsync-log.sh
⚠️ 脚本执行完成后,请 记录生成的 rsync 密码,客户端需要使用。
日志存储目录结构说明
日志中心统一使用如下目录结构:
/data/nginx_logs/
└── active/
├── hostA/
│ ├── xxx-access.log
│ └── yyy-access.log
└── hostB/
└── ...
active/:所有客户端实时写入目录- 子目录以 客户端主机名 区分
创建客户端目录脚本
nano /usr/local/bin/create_rsync_host_dir.sh
内容
#!/bin/bash
# 用法: ./create_rsync_host_dir.sh <hostname>
[ -z "$1" ] && { echo "请提供客户端主机名"; exit 1; }
mkdir -p /data/nginx_logs/active/"$1"
chown nobody:nogroup /data/nginx_logs/active/"$1"
chmod 750 /data/nginx_logs/active/"$1"
echo "目录 /data/nginx_logs/active/$1 已创建并设置权限"
给执行权限
chmod +x /usr/local/bin/create_rsync_host_dir.sh
新客户端上线时执行
/usr/local/bin/create_rsync_host_dir.sh 客户端主机名
日志轮转
日志轮转 只在日志中心执行,客户端不做轮转处理。
nano /etc/logrotate.d/nginx-rsync-logs
内容如下
/data/nginx_logs/active/**/*.log {
daily
rotate 14
maxage 14
missingok
notifempty
copytruncate
compress
delaycompress
dateext
dateformat -%Y%m%d
create 640 nobody nogroup
}
配置说明:
daily:每天轮转一次rotate 14/maxage 14:保留 14 天copytruncate:适合 rsync 持续写入场景dateext:使用日期作为后缀,便于排查
查看 rsync 写入情况
tail -f /var/log/rsyncd.log
手动测试 logrotate(不破坏)
logrotate -d /etc/logrotate.d/nginx-rsync-logs
强制轮转一次(上线前)
logrotate -f /etc/logrotate.d/nginx-rsync-logs
查看进程
ps -C rsync -o pid,state,cmd
查看日志大小
cd /data/nginx_logs/active
du -h * | sort -h
或者
du -sh /data/nginx_logs/active
客户端推送
创建推送脚本
nano /usr/local/bin/sync_nginx_logs.sh
内容, 添加你的日志路径,以及修改日志中心ip
#!/bin/bash
# /usr/local/bin/sync_nginx_logs.sh
set -e
CENTER_IP="日志中心IP"
PORT=8873
RSYNC_USER="log_sync"
PASSFILE="/root/.rsync_pass"
LOG_BASE="/var/log/nginx"
HOSTNAME=$(hostname -s)
# 要同步的日志
LOGS=(
www.1234.cc-access.log
www.5678.cc-access.log
)
for log in "${LOGS[@]}"; do
SRC="$LOG_BASE/$log"
if [ ! -f "$SRC" ]; then
echo "[$(date '+%F %T')] 文件不存在: $SRC"
continue
fi
echo "[$(date '+%F %T')] 开始同步: $SRC"
/usr/bin/rsync -avz \
--inplace \
--timeout=180 \
--bwlimit=2000 \
--password-file="$PASSFILE" \
"$SRC" \
"rsync://$RSYNC_USER@$CENTER_IP:$PORT/active/$HOSTNAME/$log"
if [ $? -eq 0 ]; then
echo "[$(date '+%F %T')] 同步完成: $SRC"
else
echo "[$(date '+%F %T')] 同步失败: $SRC"
fi
done
给与权限
chmod +x /usr/local/bin/sync_nginx_logs.sh
配置 Rsync 密码
echo '日志中心密码' > /root/.rsync_pass
chmod 600 /root/.rsync_pass
客户端与日志中心对齐校验
获取客户端主机名
hostname -s
在日志中心创建对应目录
注意:以下命令 在日志中心服务器执行
/usr/local/bin/create_rsync_host_dir.sh 客户端主机名
定时任务(客户端)
crontab -e
写入
*/5 * * * * flock -n /tmp/sync_nginx_logs.lock /bin/bash /usr/local/bin/sync_nginx_logs.sh >> /var/log/sync_nginx_logs.log 2>&1
说明:
- 每 5 分钟同步一次 Nginx 日志
flock防止脚本并发执行- 同步过程日志写入
/var/log/sync_nginx_logs.log
同步到windows
下载安装rclone,配置rclone.conf,模板如下,假设日志中心ip:3.3.3.3,ssh端口22,本地通信密钥~/.ssh/xxxxx
[ovh]
type = sftp
host = 3.3.3.3
user = root
port = 22
key_file = ~/.ssh/xxxxx
shell_type = unix
md5sum_command = md5sum
sha1sum_command = sha1sum
然后新建bat脚本
@echo off
cd /d D:\rclone-v1.68.0-windows-amd64
rclone sync ovh:/data/nginx_logs/active D:\logs ^
-u -v -P ^
--transfers=20 ^
--checkers=10 ^
--check-first ^
--ignore-errors ^
--buffer-size=128M
pause