在分布式系统运维中,日志的可靠性和可追溯性直接影响故障排查与安全审计的效率。当单台服务器出现硬件故障或遭受攻击时,如果关键日志仅存储在本地,可能面临永久丢失的风险。本文将深入探讨如何利用rsyslog构建轻量级日志互备方案,实现多节点间的日志实时同步与冗余存储。
相比ELK等重型日志系统,rsyslog在中小规模环境中展现出独特优势:
典型应用场景:
根据不同的可靠性需求,可选择以下架构模式:
| 模式类型 | 节点数量 | 数据流向 | 适用场景 | 优缺点对比 |
|---|---|---|---|---|
| 点对点互备 | 2节点 | A↔B双向同步 | 核心业务系统日志互备 | 配置简单,但扩展性差 |
| 星型集中 | N+1节点 | N节点→中心节点 | 中小规模日志集中 | 中心节点单点风险 |
| 多级转发 | ≥3节点 | 层级式转发 | 大型分布式系统 | 复杂度高,延迟累积 |
bash复制# 点对点模式的网络连接验证(需在所有节点执行)
ping -c 3 192.168.1.131 # 测试到对端节点的连通性
telnet 192.168.1.131 514 # 测试syslog端口可达性
现代rsyslog采用模块化架构,需特别注意以下模块的加载顺序:
text复制#### MODULES ####
module(load="imuxsock" SysSock.Use="off") # 禁用传统Unix socket
module(load="imjournal" StateFile="imjournal.state") # 读取systemd日志
module(load="imtcp" KeepAlive="on") # TCP传输模块
input(type="imtcp" port="514" Ruleset="remote") # 定义输入规则集
重要参数说明:
KeepAlive="on":保持TCP长连接,减少握手开销Ruleset="remote":将远程日志处理与本地日志分离SysSock.Use="off":避免与systemd-journald的端口冲突为每个远程节点创建独立的日志目录,建议采用以下模板:
bash复制# 动态路径模板(按IP+日期分类)
template(name="RemoteDailyLog" type="string"
string="/var/log/remote/%FROMHOST-IP%/%$YEAR%-%$MONTH%-%$DAY%.log")
# 权限设置(防止日志被篡改)
mkdir -p /var/log/remote
chmod 750 /var/log/remote
setfacl -Rm g:adm:rx /var/log/remote
存储策略对比:
| 策略类型 | 路径示例 | 优点 | 缺点 |
|---|---|---|---|
| 按IP分类 | /var/log/remote/192.168.1.131/syslog.log | 查找方便 | 大文件难维护 |
| 按日期滚动 | /var/log/remote/2023-08-20/192.168.1.131.log | 便于归档 | 跨天查询复杂 |
| 混合模式 | /var/log/remote/192.168.1.131/2023-08-20.log | 平衡性最好 | 目录结构复杂 |
在启用SELinux的环境下,需要额外策略调整:
bash复制# 防火墙永久开放514/TCP端口
firewall-cmd --permanent --add-port=514/tcp
firewall-cmd --reload
# SELinux策略调整(CentOS/RHEL系列)
semanage port -a -t syslogd_port_t -p tcp 514
setsebool -P rsyslog_remote_tcp_connect 1
常见权限问题排查:
bash复制# 检查rsyslog进程权限
ps auxZ | grep rsyslog
# 查看SELinux拒绝日志
ausearch -m avc -ts recent | grep rsyslog
rsyslog的队列机制是保障日志不丢失的核心,推荐以下配置:
text复制action(
type="omfwd"
target="192.168.1.132"
port="514"
protocol="tcp"
queue.type="linkedList" # 内存队列
queue.size="100000" # 10万条内存缓存
queue.filename="fwdq" # 磁盘备份队列名
queue.maxdiskspace="1g" # 最大磁盘用量
queue.saveonshutdown="on" # 关机时保存队列
action.resumeRetryCount="-1" # 无限重试
)
队列状态监控命令:
bash复制rsyslogd -N1 | grep -A 10 "queue"
qshape -c /var/lib/rsyslog/fwdq # 需安装rsyslog-utils包
为确保日志传输无遗漏,可采用以下校验方案:
序列号标记法:
bash复制# 发送端注入序列号
seq 1 1000 | while read n; do logger "SEQ_TEST:$n"; done
# 接收端检查缺失
grep "SEQ_TEST" /var/log/remote/*.log | awk -F: '{print $NF}' | sort -n | uniq
时间窗口比对:
bash复制# 获取发送端最后日志时间
tail -1 /var/log/messages | awk '{print $1,$2,$3}'
# 对比接收端最后记录时间
find /var/log/remote -type f -exec tail -1 {} \; | awk '{print $1,$2,$3}'
针对高负载环境的推荐配置:
text复制# 全局性能参数
$WorkDirectory /var/lib/rsyslog # 队列存储位置
$MainMsgQueueSize 50000 # 主队列大小
$MainMsgQueueWorkerThreads 4 # 工作线程数
# 异步写入优化
$ActionQueueType LinkedList # 内存队列
$ActionQueueFileName actq # 队列文件名前缀
$ActionQueueMaxDiskSpace 1g # 最大磁盘用量
$ActionQueueSaveOnShutdown on # 关闭时保存队列
$ActionQueueTimeoutEnqueue 0 # 永不丢弃消息
资源监控指标:
| 指标项 | 健康阈值 | 检查命令 |
|---|---|---|
| 内存队列使用率 | <70% | `rsyslogctl query queue |
| 磁盘队列文件数 | <1000 | `ls /var/lib/rsyslog/ |
| 工作线程阻塞 | 0 | grep "worker thread" /var/log/rsyslog/stat.log |
TLS加密传输(需证书支持):
text复制module(load="gtls")
input(type="imtcp" port="6514" StreamDriver.Name="gtls"
StreamDriver.Mode="1" StreamDriver.AuthMode="x509/name"
PermittedPeer=["syslog.example.com"])
日志防篡改:
bash复制# 启用日志文件属性保护
chattr +a /var/log/remote/*.log
# 安装logcheck工具监控异常变更
yum install logcheck
logcheck -t /var/log/remote
审计日志特别处理:
text复制# 单独处理audit.log确保优先级
if $programname == 'auditd' then {
action(type="omfwd" target="logserver" Priority="0")
stop
}
| 故障现象 | 可能原因 | 排查步骤 |
|---|---|---|
| 日志传输延迟 | 网络拥塞/队列积压 | 1. qshape查看队列状态2. iftop检查网络流量3. 调整 queue.workerThreads |
| 磁盘空间不足 | 日志轮转失效 | 1. 检查logrotate配置2. 验证 df -h /var/log3. 清理过期日志 |
| 部分日志丢失 | 权限问题/过滤规则错误 | 1. ausearch -m avc查SELinux2. rsyslogd -N1验证配置3. 检查 stop语句误用 |
日志清理与归档的推荐方案:
bash复制#!/bin/bash
# 保留最近30天日志,压缩归档旧日志
LOG_DIR="/var/log/remote"
find $LOG_DIR -type f -mtime +30 -name "*.log" -exec gzip {} \;
find $LOG_DIR -type f -mtime +90 -name "*.log.gz" -delete
# 生成日报(示例输出)
echo "==== $(date +%F) 日志统计 ===="
du -sh $LOG_DIR/*
echo "各节点日志量:"
find $LOG_DIR -type f -name "*.log" -exec stat -c "%n %s" {} \; | awk '{sum[$1]+=$2} END{for(i in sum)print i,sum[i]/1024"KB"}'
将此脚本加入cron定时任务:
bash复制0 2 * * * /usr/local/bin/log_clean.sh >> /var/log/log_maintenance.log 2>&1
通过rsyslog的impstats模块暴露监控指标:
text复制module(load="impstats" interval="60" format="json" log.file="/var/log/rsyslog_stats.log")
# Prometheus exporter配置示例:
input {
file {
path => "/var/log/rsyslog_stats.log"
codec => json
}
}
filter {
mutate { convert => { "[metrics][name]" => "string" } }
}
output {
prometheus {
metric => {
"[metrics][name]" => "[metrics][value]"
}
}
}
关键监控指标包括:
mainq队列积压量action转发延迟worker线程活跃数为后续迁移到ELK栈设计的日志格式优化:
text复制template(name="ELK_Ready" type="list") {
property(name="timereported" dateFormat="rfc3339")
constant(value=" ")
property(name="hostname")
constant(value=" ")
property(name="syslogtag")
constant(value=" ")
property(name="msg" spifno1stsp="on")
constant(value=" ")
property(name="$.!metadata!ip" position.from="2")
}
此模板确保日志包含: