日志管理是每个运维工程师的必修课。当服务器数量超过两位数时,分散在各主机上的日志文件就会变成运维人员的噩梦。我曾经经历过一次线上事故排查,为了追查一个分布式系统的异常,不得不在7台服务器之间来回切换,用grep命令在海量日志中寻找线索,整整耗费了3个小时。这次经历让我下定决心实施日志集中化管理。
Rsyslog作为Linux系统自带的日志服务,具有以下不可替代的优势:
在开始前需要确认:
bash复制# 检查rsyslog版本(要求v8+)
rsyslogd -v
# 检查系统日志服务状态
systemctl status rsyslog
常见问题处理:
如果系统使用syslog-ng或journald:
bash复制# 停用现有服务
systemctl stop syslog-ng
systemctl disable syslog-ng
# 安装rsyslog
yum install -y rsyslog # CentOS
apt-get install -y rsyslog # Ubuntu
防火墙配置(以CentOS 7为例):
bash复制firewall-cmd --permanent --add-port=514/tcp
firewall-cmd --permanent --add-port=514/udp
firewall-cmd --reload
计算公式:
code复制预估日志量 = 主机数 × 日均日志量 × 保留天数 × 压缩比(0.3)
示例:50台主机,每台每天产生100MB日志,保留30天:
code复制50 × 100MB × 30 × 0.3 = 45GB
关键配置项:
bash复制# 启用TCP/UDP模块
module(load="imudp")
input(type="imudp" port="514")
module(load="imtcp")
input(type="imtcp" port="514")
# 定义日志模板
template(name="RemoteLogs" type="string"
string="/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log")
# 应用模板规则
:fromhost-ip, !isequal, "127.0.0.1" ?RemoteLogs
日志过滤(只收集error级别以上日志):
bash复制:syslogtag, contains, "error" ?RemoteLogs
& stop
日志压缩归档(添加至/etc/rsyslog.conf末尾):
bash复制# 每天压缩一次日志
$ActionQueueType LinkedList
$ActionQueueFileName logq
$ActionResumeRetryCount -1
$ActionQueueSaveOnShutdown on
$ActionQueueMaxDiskSpace 1g
编辑/etc/rsyslog.d/forward.conf:
bash复制# 转发所有日志到中心服务器
*.* @@192.168.1.100:514 # TCP方式
*.* @192.168.1.100:514 # UDP方式
# 重要:添加转发失败本地保存规则
$ActionQueueFileName queue
$ActionQueueMaxDiskSpace 1g
$ActionQueueSaveOnShutdown on
$ActionQueueType LinkedList
$ActionResumeRetryCount -1
建议为每台主机添加标识:
bash复制# 在/etc/rsyslog.conf中添加
$LocalHostName your-hostname
$PreserveFQDN on
安装Logstash输入插件:
bash复制input {
tcp {
port => 514
type => "syslog"
}
udp {
port => 514
type => "syslog"
}
}
日志解析规则:
bash复制filter {
if [type] == "syslog" {
grok {
match => { "message" => "%{SYSLOGTIMESTAMP:timestamp} %{SYSLOGHOST:hostname} %{DATA:program}(?:\[%{POSINT:pid}\])?: %{GREEDYDATA:message}" }
}
}
}
bash复制# 生成证书
openssl req -x509 -newkey rsa:2048 -keyout /etc/rsyslog.key -out /etc/rsyslog.crt -days 3650 -nodes
# 配置rsyslog
$DefaultNetstreamDriver gtls
$DefaultNetstreamDriverCAFile /etc/rsyslog.crt
$DefaultNetstreamDriverCertFile /etc/rsyslog.crt
$DefaultNetstreamDriverKeyFile /etc/rsyslog.key
关键指标监控命令:
bash复制# 查看队列积压
rsyslogd -N1 | grep queue
# 实时日志吞吐量
watch -n 1 'netstat -an | grep 514 | wc -l'
/etc/rsyslog.d/performance.conf:
bash复制# 提高工作线程数
$WorkDirectory /var/spool/rsyslog
$MainMsgQueueSize 100000
$MainMsgQueueWorkerThreads 4
$ActionQueueWorkerThreads 2
| 现象 | 排查命令 | 解决方案 |
|---|---|---|
| 日志未转发 | tcpdump -i eth0 port 514 -vv |
检查防火墙/网络连通性 |
| 日志格式乱码 | rsyslogd -N1 |
检查模板定义语法 |
| 服务崩溃 | journalctl -u rsyslog -f |
检查/var/log/messages |
/etc/logrotate.d/rsyslog-remote:
bash复制/var/log/remote/*/*.log {
daily
missingok
rotate 30
compress
delaycompress
sharedscripts
postrotate
/usr/lib/rsyslog/rsyslog-rotate
endscript
}
动态字段提取(解析Nginx日志):
bash复制template(name="NginxLog" type="list") {
property(name="msg" field.delimiter=" " field.number="1")
constant(value=" ")
property(name="msg" field.delimiter=" " field.number="2")
}
多目标路由配置:
bash复制if $fromhost-ip == '192.168.1.10' then {
action(type="omfile" file="/var/log/important.log")
action(type="omfwd" target="backup.logserver.com" port="514")
}
日志采样配置(降低流量):
bash复制if $syslogseverity <= 4 then {
if $syslogtag contains 'nginx' then {
if $msg contains 'GET /api' then /var/log/api-traces.log
}
}