Hugo博客公告弹窗

轻量级 Nginx 日志中心搭建:Rsync 同步 + 自动轮转

方案介绍

本文档介绍一种 基于 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
CC BY-NC-SA 4.0 转载请注明
最后更新于 2026-01-22 14:49