HAProxy日志配置指南:Rocky Linux 8下rsyslog集成与排错
1. 为什么默认日志“看不见”——HAProxy在Rocky Linux 8上的日志静默真相
你刚在Rocky Linux 8上跑起HAProxy,配置文件写得严丝合缝,systemctl start haproxy返回active (running),浏览器访问后端服务一切正常。可当你兴冲冲地执行tail -f /var/log/haproxy.log,屏幕却一片死寂——连一行日志都没有。不是权限问题,不是路径错误,/var/log/haproxy.log文件甚至根本没被创建。你翻遍官方文档,只看到一句轻描淡写的“HAProxy does not write logs by itself”,然后就没了下文。
这绝不是你的配置有误,而是HAProxy从设计之初就拒绝当一个“自说自话”的日志生产者。它不直接写磁盘,不管理日志轮转,更不关心日志该存哪儿、存多久。它的哲学是:我只负责生成结构化、高精度的原始日志事件,把日志的存储、过滤、归档、分析这些重活,全权交给专业的系统日志守护进程去干。这种解耦,让HAProxy保持极致轻量和高性能,但也意味着——在Rocky Linux 8上,你必须亲手把它和rsyslog这条“日志高速公路”接通,否则所有请求、错误、连接状态,都只存在于内存里,一闪即逝。
而Rocky Linux 8的默认日志架构,正是rsyslog。它不像旧版syslog那样简单粗暴,而是支持模块化、TCP/UDP传输、数据库写入,以及最关键的——Unix domain socket(UDS)通信。这个UDS,就是我们打通HAProxy与rsyslog之间那堵墙的唯一钥匙。它比网络套接字更快、更安全、更可靠,没有网络协议栈开销,也没有防火墙策略干扰,是本地服务间日志传递的黄金标准。那些搜索“haproxy logging not working”、“no logs in /var/log/haproxy.log”的人,90%都卡在了这一步:他们以为改个log指令就能搞定,却不知道HAProxy的log指令,本质上只是在告诉它:“把日志发给这个socket地址,剩下的,你别管。”
提示:HAProxy的
log指令语法是log <address> [format <format>],其中<address>必须是一个有效的rsyslog监听地址。在Rocky Linux 8上,这个地址几乎总是/dev/log,一个指向rsyslog Unix domain socket的符号链接。如果你强行填/var/log/haproxy.log,HAProxy会启动失败,并报错unable to resolve address '/var/log/haproxy.log'——因为它根本不是网络地址,也不是文件路径,而是一个内核级的IPC通道。
我第一次部署时也栽在这儿。我把log 127.0.0.1:514写进global段,心想UDP总能通吧?结果日志全丢了。抓包一看,rsyslog压根没在514端口监听UDP。查rsyslog.conf才发现,默认配置里imudp模块是注释掉的,而imuxsock(Unix socket输入模块)才是默认启用的。这个认知偏差,让我多花了整整一个下午。所以,理解“HAProxy不写日志”和“rsyslog才是日志管家”这两个前提,是你整个配置成功的逻辑起点。跳过这一步,后面所有操作都是在沙上筑塔。
2. 三步打通数据链路——从HAProxy到rsyslog的完整握手流程
打通HAProxy与rsyslog,不是一蹴而就的魔法,而是一个清晰、可验证的三步握手过程。每一步都有其不可替代的作用,漏掉任何一环,日志就会在半路消失。我把它拆解为“HAProxy声明出口”、“rsyslog声明入口”、“系统级权限校验”三个环节,每个环节都附带实测命令和预期输出,你可以像调试代码一样,逐行验证。
2.1 HAProxy声明出口:告诉它“日志该往哪儿发”
这一步在HAProxy的配置文件中完成,通常是/etc/haproxy/haproxy.cfg。关键在于global段中的log指令。很多人误以为要在这里指定一个文件路径,但正确做法是:
# 编辑HAProxy主配置 sudo vi /etc/haproxy/haproxy.cfg在global段内,添加或修改这一行:
log /dev/log local2这里有两个核心参数需要精确理解:
/dev/log:这是Rocky Linux 8上rsyslog默认监听的Unix domain socket路径。它不是一个普通文件,而是一个内核IPC节点。你可以用ls -l /dev/log确认它指向/run/systemd/journal/dev-log,这是systemd-journald和rsyslog协同工作的桥梁。local2:这是一个facility(设施),是syslog标准中定义的日志分类标签。它就像一个邮件分拣中心的“收件部门”。HAProxy默认使用local2,而rsyslog默认会接收所有facility的日志,但为了后续精准过滤和归档,我们必须在rsyslog端明确告诉它:“把发给local2的所有日志,都送到/var/log/haproxy.log这个专属邮箱里。”
注意:
local2不是随便选的。syslog标准定义了local0到local7共8个用户自定义facility。HAProxy官方文档明确推荐local2,以避免与系统其他服务(如local0常被network服务占用)冲突。如果你硬要改成local3,那么rsyslog的规则也必须同步改成local3.*,否则日志依然会丢失。
配置完后,不要急着重启HAProxy。先做语法检查:
sudo haproxy -c -f /etc/haproxy/haproxy.cfg如果输出Configuration file is valid,说明HAProxy已经“知道”该往哪儿发了。但这只是第一步,它现在还只是个“知道地址的邮递员”,还没开始送信。
2.2 rsyslog声明入口:告诉它“谁的信该收,收到后放哪儿”
rsyslog的配置分散在多个文件中,但核心入口在/etc/rsyslog.conf。不过,Rocky Linux 8遵循模块化最佳实践,我们绝不直接修改rsyslog.conf,而是创建一个独立的、可管理的配置片段。这样做有两个巨大好处:一是升级rsyslog时,你的自定义配置不会被覆盖;二是便于故障隔离,删掉这个文件,日志立刻恢复默认行为,无需大海捞针。
# 创建HAProxy专用的rsyslog配置文件 sudo vi /etc/rsyslog.d/99-haproxy.conf在这个文件里,写入以下三行:
# 加载Unix socket输入模块(确保已启用) module(load="imuxsock" SysSock.Use="off") # 声明:接收所有来自local2 facility的日志 local2.* /var/log/haproxy.log # 可选:同时将local2日志转发给systemd journal,实现双写 local2.* ~我们来逐行解析这个精炼的配置:
- 第一行
module(load="imuxsock" ...):imuxsock是rsyslog的Unix socket输入模块。SysSock.Use="off"是关键!它告诉rsyslog:“别用systemd-journald提供的那个/dev/logsocket,我自己来监听一个全新的、专属于HAProxy的socket。” 为什么?因为systemd-journald默认的/dev/log是面向所有服务的“公共邮箱”,而HAProxy日志量大且格式特殊,混在里面会污染journal查询。我们稍后会为HAProxy创建一个独享的socket。 - 第二行
local2.* /var/log/haproxy.log:这是最核心的路由规则。“local2.*”表示所有local2设施下的所有优先级(debug, info, warning, error...)日志;/var/log/haproxy.log是目标文件路径。rsyslog会自动创建这个目录和文件,并处理权限。 - 第三行
local2.* ~:这个波浪号~是rsyslog的“丢弃”操作符。它表示:把匹配到的local2日志,在写入/var/log/haproxy.log之后,立即停止处理,不再向下传递给其他规则(比如默认的*.info;mail.none;authpriv.none;cron.none /var/log/messages)。这是防止HAProxy日志在messages里泛滥的关键一招。
保存后,重启rsyslog以加载新规则:
sudo systemctl restart rsyslog此时,rsyslog已经“竖起耳朵”,准备接收来自local2的任何声音。但它还在等一个信号:那个专属于HAProxy的socket,到底在哪儿?
2.3 系统级权限校验:创建并授权专属Unix Domain Socket
这才是整个链条中最容易被忽略、也最致命的一环。HAProxy进程是以haproxy用户身份运行的,而rsyslog默认是以root或syslog用户运行。如果它们之间通信的socket文件权限不对,数据包就会被内核无情丢弃,且不报任何错误——日志就这么无声无息地消失了。
我们需要为HAProxy创建一个它能读写、rsyslog能监听的专属socket。Rocky Linux 8的rsyslog配置默认不启用这个功能,所以我们得手动开启。
首先,编辑rsyslog的主配置,启用imuxsock模块并指定socket路径:
sudo vi /etc/rsyslog.conf找到#module(load="imuxsock")这一行,取消注释,并在其下方添加:
module(load="imuxsock" SysSock.Name="/run/rsyslog/haproxy.sock" SysSock.Group="haproxy" SysSock.Perm="0660")这里指定了:
SysSock.Name:socket文件的绝对路径,我们将它放在/run/rsyslog/这个tmpfs内存目录下,避免磁盘I/O。SysSock.Group:允许哪个用户组可以访问这个socket。我们将haproxy用户加入syslog组,这样它就有权限向socket写入日志。SysSock.Perm:socket文件的权限掩码,0660意味着只有属主和属组可读写。
接下来,创建socket目录并设置权限:
sudo mkdir -p /run/rsyslog sudo chown root:syslog /run/rsyslog sudo chmod 0755 /run/rsyslog然后,将haproxy用户加入syslog组:
sudo usermod -a -G syslog haproxy最后,也是最关键的一步:修改HAProxy的配置,让它把日志发往我们刚刚创建的这个专属socket,而不是默认的/dev/log。回到/etc/haproxy/haproxy.cfg,把global段的log指令改为:
log /run/rsyslog/haproxy.sock local2现在,整个数据链路才真正闭合:
- HAProxy(以
haproxy用户) → 向/run/rsyslog/haproxy.sock(属组syslog,权限0660)写入日志; - rsyslog(以
root或syslog用户) → 监听/run/rsyslog/haproxy.sock,接收日志,并根据99-haproxy.conf规则,将其路由至/var/log/haproxy.log。
验证这三步是否成功?执行以下命令:
# 检查socket文件是否存在且权限正确 ls -l /run/rsyslog/haproxy.sock # 检查haproxy用户是否在syslog组 groups haproxy # 重启两个服务 sudo systemctl restart rsyslog sudo systemctl restart haproxy # 实时观察日志文件是否开始滚动 sudo tail -f /var/log/haproxy.log当你看到类似Dec 25 10:30:45 localhost haproxy[1234]: Proxy http-in started这样的行出现时,恭喜你,握手成功。这不是运气,而是三步逻辑严密的工程实践。
3. 日志内容深度解析——读懂HAProxy每一行日志背后的业务真相
一旦日志开始稳定流入/var/log/haproxy.log,你面对的就不再是一堆杂乱无章的字符,而是一份实时更新的、关于你整个应用交付基础设施的“健康体检报告”。HAProxy日志的格式高度结构化,每一列都承载着不可替代的业务信息。我把它比作一张精密的“交通监控摄像头”画面:时间戳是快门,前端IP是车牌号,后端服务器是目的地,响应码是通行状态,耗时是拥堵指数。下面,我们以一条典型的、包含丰富信息的HAProxy日志为例,逐字段拆解其含义,并告诉你如何从中快速定位性能瓶颈、安全攻击和配置错误。
假设你在/var/log/haproxy.log中看到这样一行:
Dec 25 10:30:45 localhost haproxy[1234]: 192.168.1.100:54321 [25/Dec/2023:10:30:45.123] http-in~ http-out/backend1 0/0/1/42/43 200 12345 - - ---- 1/1/1/1/0 0/0 "GET /api/v1/users HTTP/1.1"我们按空格分割,逐一解读这14个字段(HAProxy默认log-format):
| 字段序号 | 值 | 含义 | 业务价值 |
|---|---|---|---|
| 1-3 | Dec 25 10:30:45 | 日志生成时间(rsyslog时间) | 这是rsyslog接收到日志的时间,而非HAProxy处理请求的时间。它用于排查rsyslog自身延迟。 |
| 4 | localhost | 主机名 | 在集群中,用于区分是哪台HAProxy节点处理的请求。 |
| 5 | haproxy[1234] | 进程名与PID | PID可用于strace -p 1234进行深度调试,或关联/proc/1234/stack查看线程栈。 |
| 6 | 192.168.1.100:54321 | 客户端IP与端口 | 安全审计的核心。大量来自同一IP的403或404,可能是扫描器;200但User-Agent为空,可能是爬虫。 |
| 7 | [25/Dec/2023:10:30:45.123] | 请求到达HAProxy时间(精确到毫秒) | 这是真正的“业务时间戳”,用于计算端到端延迟。 |
| 8 | http-in~ | 前端(frontend)名称 | 表明该请求是通过名为http-in的frontend进入的。这是流量入口的“门牌号”。 |
| 9 | http-out/backend1 | 后端(backend)与服务器(server)名称 | http-out是backend名,backend1是具体选中的server名。这是故障定位的“终点站”。 |
| 10 | 0/0/1/42/43 | 5个耗时(微秒),用/分隔 | 性能分析的金矿: - 0: 请求队列等待时间(queue time)- 0: 连接到frontend的时间(connection time)- 1: HAProxy内部处理时间(request time)- 42: 与后端服务器建立TCP连接的时间(backend connect time)- 43: 总耗时(total time)关键洞察:如果 42(backend connect)远大于43(total),说明后端服务器本身响应极慢,问题不在HAProxy。 |
| 11 | 200 | HTTP响应状态码 | 最直观的健康指标。5xx代表后端故障;4xx代表客户端错误或恶意请求。 |
| 12 | 12345 | 响应体大小(字节) | 结合状态码看:200但大小为0,可能后端返回了空响应;404但大小很大,可能是自定义错误页。 |
| 13-14 | - - | 上游代理信息与HTTP Referer | 通常为-,除非你配置了option forwardfor和capture request header。 |
| 15 | ---- | 4位标志位 | 每一位代表一个状态:-: 无重试-: 无重定向-: 无cookie插入-: 无SSL如果某位是 R,表示发生了重试(retry),这是后端不稳定的强烈信号。 |
| 16 | 1/1/1/1/0 | 连接统计 | act/fe/be/srv/retr,分别代表活跃连接数、frontend连接数、backend连接数、server连接数、重试次数。retr非零需警惕。 |
| 17 | 0/0 | 队列统计 | qcur/qmax,当前/最大排队请求数。qcur > 0说明前端压力过大,需要扩容或限流。 |
| 18 | "GET /api/v1/users HTTP/1.1" | 原始HTTP请求行 | 安全与合规的最终证据。可用来审计是否有人在调用未授权API,或检测SQL注入特征(如' OR '1'='1)。 |
提示:这个默认格式(
%ci:%cp [%t] %ft %b/%s %Tq/%Tw/%Tc/%Tr/%Tt %st %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs "%r")虽然全面,但对新手过于冗长。我建议在frontend或listen段中,用log-format指令定制一个更聚焦的版本,例如:log-format "%t %ci:%cp [%tr] %ft %b/%s %ST %B %U %TR %TRd %HR %HS %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs \"%r\""这个格式移除了部分不常用字段,增加了
%U(URL路径)、%TR(总响应时间,毫秒)、%TRd(总响应时间,微秒),让性能分析更直观。
读懂日志,就是拥有了上帝视角。我曾用第10字段(耗时)发现一个隐藏的性能杀手:backend connect time平均高达800ms,而total time只有850ms。这意味着HAProxy花50ms处理请求,却花了800ms才连上后端。排查后发现,后端数据库的连接池配置过小,导致HAProxy每次都要排队等待数据库连接。这个结论,完全是从日志的数字里“算”出来的,而不是靠猜。
4. 生产环境避坑指南——那些让你深夜加班的rsyslog与HAProxy配置陷阱
在Rocky Linux 8上配置HAProxy日志,看似只有几行配置,但生产环境的复杂性,会让无数细节成为“深水炸弹”。我踩过的每一个坑,都伴随着凌晨三点的咖啡和满屏的journalctl -u rsyslog --since "2 hours ago"。下面列出的,不是教科书里的理论,而是我在真实线上环境中,用血泪换来的、最值得警惕的五大陷阱。每一个,都附带了复现方法、根本原因和一劳永逸的解决方案。
4.1 陷阱一:rsyslog的“静默丢包”——UDP日志的不可靠性幻觉
现象:你配置了log 127.0.0.1:514 udp,netstat -uln | grep :514显示rsyslog确实在监听,logger -n 127.0.0.1 -P 514 "test"也能看到日志,但HAProxy日志就是不来。
复现与诊断:
# 强制HAProxy使用UDP发送(临时测试) sudo sed -i 's|/run/rsyslog/haproxy.sock|127.0.0.1:514|g' /etc/haproxy/haproxy.cfg sudo systemctl restart haproxy # 发送一个测试请求 curl -I http://localhost # 查看rsyslog的UDP接收统计 sudo rsyslogd -N1 | grep -i udp # 输出可能包含:imudp: statistics: received=0, dropped=1234dropped计数器飙升,就是罪魁祸首。
根本原因:UDP是无连接、不可靠的协议。rsyslog的UDP接收缓冲区(net.core.rmem_default)默认只有212992字节(约208KB)。当HAProxy在高并发下瞬间涌出大量日志包,缓冲区溢出,内核就会静默丢弃后续所有UDP包,且不通知rsyslog。这就像一个容量200人的礼堂,来了300人,后面100人连门都进不去,更别说被登记了。
解决方案:永远不要在生产环境用UDP传HAProxy日志。这是原则,不是建议。如果非要网络传输(比如集中式日志),请务必使用TCP,并启用reliable模式:
# 在rsyslog端 (/etc/rsyslog.d/99-haproxy.conf) module(load="imtcp") input(type="imtcp" port="514" ruleset="haproxy-ruleset") # 在HAProxy端 log 127.0.0.1:514 tcpTCP的三次握手和滑动窗口机制,能保证日志100%送达,代价是微乎其微的几毫秒延迟。
4.2 陷阱二:SELinux的“隐形防火墙”——日志路径的权限迷宫
现象:/var/log/haproxy.log文件存在,权限是644,haproxy用户能读,rsyslog能写,但日志就是不写入。sestatus显示SELinux是enforcing模式。
复现与诊断:
# 查看最近的SELinux拒绝日志 sudo ausearch -m avc -ts recent | grep haproxy # 典型输出: # type=AVC msg=audit(1703502645.123:456): avc: denied { write } for pid=1234 comm="haproxy" name="haproxy.log" dev="dm-0" ino=123456 scontext=system_u:system_r:haproxy_t:s0 tcontext=system_u:object_r:var_log_t:s0 tclass=file permissive=0avc: denied { write },清晰地表明SELinux阻止了haproxy进程向var_log_t类型的文件写入。
根本原因:Rocky Linux 8默认启用SELinux,它有一套比传统Linux DAC(自主访问控制)更严格的MAC(强制访问控制)策略。haproxy_t域的进程,默认只能向haproxy_log_t类型的文件写入,而/var/log/haproxy.log被标记为通用的var_log_t类型,因此被拒绝。
解决方案:有两种方式,我推荐第一种,因为它更安全、更符合SELinux设计哲学:
为日志文件打上正确的SELinux标签:
# 创建日志文件并打标签 sudo touch /var/log/haproxy.log sudo semanage fcontext -a -t haproxy_log_t "/var/log/haproxy\.log" sudo restorecon -v /var/log/haproxy.logsemanage fcontext命令将正则表达式/var/log/haproxy\.log与haproxy_log_t类型永久绑定,restorecon则立即应用该标签。临时禁用SELinux(仅用于测试,切勿在生产环境使用):
sudo setenforce 0这只是临时切换到
permissive模式,重启后失效。它能帮你快速验证是否是SELinux问题,但绝不能作为长期方案。
4.3 陷阱三:rsyslog的“日志风暴”——无限递归的自我引用
现象:/var/log/haproxy.log文件以每秒几百MB的速度疯狂增长,内容全是重复的、关于rsyslog自身配置错误的日志,例如:
Dec 25 11:00:00 localhost rsyslogd: error during parsing file /etc/rsyslog.d/99-haproxy.conf, on or before line 5: invalid character 'x' [v8.1911.0-6.el8]根本原因:你在/etc/rsyslog.d/99-haproxy.conf中,不小心写了一条规则,把rsyslog自己的错误日志(rsyslogd进程产生的日志)也路由到了/var/log/haproxy.log。而写入haproxy.log这个动作,又触发了rsyslog的文件监控,再次产生日志……如此循环,形成指数级爆炸。
解决方案:在99-haproxy.conf的开头,添加一个排除规则,确保rsyslog自身的日志永远不会进入HAProxy日志:
# 排除rsyslog自身日志,防止无限递归 if $programname == 'rsyslogd' then stop # 你的HAProxy日志规则 local2.* /var/log/haproxy.log & stop$programname是rsyslog的内置属性,stop是终止处理的指令。这个if...then stop必须放在所有其他规则之前,它是整个日志流的“守门员”。
4.4 陷阱四:HAProxy的“日志饥饿”——全局日志级别设置过高
现象:/var/log/haproxy.log里只有INFO级别的日志(如Proxy started),但你期望看到的DEBUG级别的详细连接信息(如SSL握手细节、ACL匹配过程)完全缺失。
根本原因:HAProxy的log指令本身不控制日志级别,它只控制日志的“目的地”。真正的日志级别,由global段的log指令后的level参数,或defaults段的option http-log等指令控制。默认情况下,HAProxy只记录INFO及以上级别。
解决方案:在global段,为log指令显式指定level:
# 记录所有级别,包括debug(仅在调试时启用,生产环境慎用) log /run/rsyslog/haproxy.sock local2 debug # 或者,更实用的:记录warning和error,用于告警 log /run/rsyslog/haproxy.sock local2 warning此外,option http-log(在defaults或frontend中)会启用详细的HTTP事务日志,而option tcp-check会记录TCP健康检查日志。这些选项是“开关”,log level是“音量旋钮”,两者配合才能得到你想要的详细程度。
4.5 陷阱五:日志轮转的“定时炸弹”——logrotate的权限错配
现象:logrotate每天凌晨执行,/var/log/haproxy.log被重命名为/var/log/haproxy.log-20231225,但新的/var/log/haproxy.log文件创建后,HAProxy无法再写入,日志停止。
根本原因:logrotate默认以root身份运行,它创建的新日志文件,属主是root:root,权限是600。而HAProxy进程是以haproxy用户运行的,它没有权限向root拥有的文件写入。
解决方案:在/etc/logrotate.d/haproxy配置中,明确指定新日志文件的属主和权限:
/var/log/haproxy.log { daily missingok rotate 52 compress delaycompress notifempty create 644 haproxy haproxy # 关键!指定属主和权限 sharedscripts postrotate /bin/kill -USR1 `cat /run/haproxy.pid 2>/dev/null` 2>/dev/null || true endscript }create 644 haproxy haproxy这一行,确保了每次轮转后,新创建的haproxy.log文件,其属主是haproxy,属组是haproxy,权限是644,HAProxy进程可以无缝写入。postrotate脚本中的kill -USR1,则是通知HAProxy重新打开日志文件句柄,这是日志轮转后必须的“热重载”步骤。
这些陷阱,每一个都曾让我在深夜的服务器前枯坐良久。它们不是配置错误,而是对Rocky Linux 8、rsyslog、HAProxy三者底层交互机制理解不足所导致的必然结果。避开它们,不是靠运气,而是靠对每个组件工作原理的敬畏和深挖。
5. 超越基础:用rsyslog构建HAProxy日志的智能分析管道
当HAProxy日志稳定、可靠、结构化地流入/var/log/haproxy.log后,你的工作才刚刚开始。日志的价值,不在于“有”,而在于“用”。Rocky Linux 8自带的rsyslog,其能力远不止于简单的文件写入。它是一个强大的、可编程的日志处理引擎,我们可以利用它的模块和规则,将原始日志流,实时转化为可操作的业务洞察。下面,我将分享三个经过生产环境验证的、即插即用的高级技巧,它们能让你的日志从“记录仪”升级为“预警雷达”和“决策仪表盘”。
5.1 技巧一:基于日志内容的实时告警——当5xx错误超过阈值时发邮件
想象一下,你的网站正在经历一次流量高峰,HAProxy日志里500、502、503错误码开始密集出现。你希望在错误率超过1%的瞬间,就收到一封邮件告警,而不是等到运维同学第二天早上巡检时才发现。rsyslog的ommail模块,可以完美实现这一点。
步骤1:安装并配置ommail模块
# 安装mailx(用于发送邮件) sudo dnf install mailx -y # 配置mailx,使用本地sendmail或外部SMTP echo "set smtp=smtp://localhost:25" | sudo tee -a /etc/mail.rc步骤2:创建告警规则(/etc/rsyslog.d/99-haproxy-alert.conf)
# 加载邮件输出模块 module(load="ommail") # 定义邮件模板 template(name="AlertMailSubject" type="string" string="ALERT: HAProxy High Error Rate on %hostname%") template(name="AlertMailBody" type="string" string=" To: admin@example.com From: haproxy-alert@%hostname% Subject: ALERT: HAProxy High Error Rate on %hostname% Time: %timereported% Host: %hostname% Error Count: %$!count% Error Rate: %$!rate% Log Sample: %$!sample% Please check HAProxy and backend services immediately. ") # 使用mmnormalize模块解析日志,提取状态码 module(load="mmnormalize") action(type="mmnormalize" ruleBase="/etc/rsyslog.d/haproxy-ruleset.rb") # 定义一个规则集,用于统计5xx错误 ruleset(name="haproxy-error-counter") { # 如果状态码是5xx,增加计数器 if $msg contains ' 5' then { set $!count = exec_template("getcounter", "haproxy-5xx"); set $!count = $!count + 1; set $!rate = $!count / 100; # 假设我们统计最近100条日志 if $!rate > 0.01 then { # 错误率>1% action(type="ommail" server="localhost" port="25" from="haproxy-alert@%hostname%" to="admin@example.com" subject="ALERT: HAProxy High Error Rate" template="AlertMailBody" ) } } } # 将local2日志路由到这个规则集 local2.* :ruleset, haproxy-error-counter这个配置的核心在于mmnormalize模块,它能像正则表达式一样,从日志文本中精准提取status code字段。exec_template("getcounter", ...)则调用一个外部脚本(你需要自己编写)来维护一个内存中的计数器。虽然配置略显复杂,但它实现了真正的“实时流式告警”,比任何基于cron+grep的脚本都要精准和及时。
5.2 技巧二:日志结构化入库——将HAProxy日志导入MySQL进行SQL分析
对于需要长期留存、多维分析(如按地域、按URL路径、按响应时间分桶)的场景,纯文本日志力不从心。rsyslog的ommysql模块,可以将每一条HAProxy日志,作为一行记录,实时插入到MySQL数据库中。
步骤1:在MySQL中创建表
CREATE DATABASE haproxy_logs