在操作日志数据时,HAProxy提供了丰富的信息。在这篇博文中,我们将演示如何设置HAProxy日志记录,定位Syslog服务器,了解日志字段以及建议一些用于解析日志文件的有用工具。
HAProxy位于基础架构的关键拓扑中。无论是用作load balancer,sidecar还是作为Kubernetes ingress controller,从HAProxy中获取有意义的日志都是必须的。
日志记录可以为你提供有关每个连接和请求的详情。它实现了故障排除所需的可观察性,甚至可以用于及早发现问题。这是从HAProxy获取信息的众多方法之一。其他方法包括使用统计信息页面或runtime API获取指标,设置邮件警报,以及利用各种开源集成来存储日志或统计数据。HAProxy提供非常详细的日志,精确到毫秒级,并生成有关流入基础架构的流量的大量信息。这包括:
- 有关流量的指标:时间数据,连接计数器,流量大小等。
- 有关HAProxy调用信息:内容切换,过滤,持久性等。
- 有关请求和响应的信息:标头,状态代码,有效负载等。
- 会话的终止状态以及跟踪故障发生位置的能力(客户端,服务器端?)
在本文中,你将学习如何配置HAProxy日志记录以及如何读取它生成的日志消息。然后,我们将列出一些在操作日志数据时会发现有用的工具。
Syslog服务器
HAProxy可以发出日志消息以供syslog服务器处理。这与熟悉的系统日志工具(如Rsyslog)以及较新的systemd服务日志兼容。你还可以使用各种日志转发器(如Logstash和Fluentd)从HAProxy接收Syslog消息,并将它们发送到中央日志聚合器。如具代表意义的有ELK等。
如果你在容器环境中工作,HAProxy支持Cloud Native Logging,它允许你将日志消息发送到stdout和stderr。在这种情况下,docker的配置日志)。
在研究如何通过HAProxy配置文件启用日志记录之前,应首先确保已配置Syslog服务器(如rsyslog)以接收日志。在centos7上,你将使用yum包管理器安装rsyslog,如下所示:
[root@www.linuxea.com ~]# yum install rsyslog -y
安装rsyslog后,编辑其配置以处理摄取HAProxy日志消息。将以下内容添加到/etc/rsyslog.conf或rsyslog.d目录中的新文件,如/etc/rsyslog.d/haproxy.conf:
cat > /etc/rsyslog.d/haproxy.conf << EOF
# Collect log with UDP
$ModLoad imudp
$UDPServerAddress 127.0.0.1
$UDPServerRun 514
# Creating separate log files based on the severity
local0.* /var/log/haproxy-traffic-linuxea-com.log
local0.notice /var/log/haproxy-admin-linuxea-com.log
EOF
然后,重新启动rsyslog服务。在上面的示例中,rsyslog侦听默认UDP端口514上的IP环回地址127.0.0.1。此特定配置写入两个日志文件。选择的文件基于记录消息的严重性级别。为了理解这一点,请仔细查看文件中的最后两行。他们这样开始:
local0.* ...
local0.notice ...
Syslog标准规定应为每个记录的消息分配facility code和严重性 级别。鉴于上面的示例rsyslog配置,你可以假设我们将配置HAProxy以使用facility code local0发送其所有日志消息。
严重性级别在facility code之后指定,以点分隔。这里,第一行捕获所有严重性级别的消息,并将它们写入名为haproxy-traffic-linuxea-com.log的文件。第二行仅捕获通知级消息及以上,将它们记录到名为haproxy-admin-linuxea-com.log的文件中。
在发送某些消息时,HAProxy被硬编码为使用某些严重性级别。例如,它将与连接和HTTP请求相关的日志消息与信息严重性级别分类。其他事件使用其他一个较不详细的级别进行分类。从最重要到最不重要,严重性级别为:
| 严重程度 | HAProxy日志
| EMERG: | 诸如用尽操作系统文件描述符之类的错误。
| alert: | 发生意外情况的一些罕见情况,例如无法缓存响应。
| crit: | 不曾用过。
| err: | 诸如无法解析映射文件,无法解析HAProxy配置文件以及粘贴表上的操作失败等错误。
| warning:| 某些重要但非关键的错误,例如未能设置请求标头或未能连接到DNS名称服务器。
| notice: | 更改服务器的状态,例如UP或DOWN或禁用服务器。启动时的其他事件,如启动代理和加载模块也包括在内。运行状况检查日志记录(如果已启用)也使用此级别。
| info: | TCP连接和HTTP请求详细信息和错误。
| debug: | 你可以编写记录调试消息的自定义Lua代码
现Linux发行版随服务管理器systemd一起提供,它引入了用于收集和存储日志的日志。journald服务不是Syslog实现,但它兼容Syslog,因为它将侦听相同的/dev/log套接字。它将收集接收的日志,并允许用户使用等效的日记字段(SYSLOG_FACILITY,PRIORITY)按facility code和/或严重性级别对其进行过滤。
HAProxy日志配置
HAProxy 配置手册解释了可以通过两个步骤启用日志记录:第一步是global
使用log
指令在该部分中指定Syslog服务器:
global
log 127.0.0.1:514 local0
该log
指令指示HAProxy将日志发送到侦听127.0.0.1:514的Syslog服务器。消息与local0一起发送,local0是标准的,用户定义的Syslog Facility之一。它也是我们的rsyslog配置所期望的功能。你可以添加多个log
语句以将输出发送到多个Syslog服务器。
你可以通过将Syslog级别添加到行尾来控制记录的信息量:
log 127.0.0.1:514 local0 info
配置日志记录的第二步是更新不同的代理(frontend
,backend
和listen
部分)以将消息发送到该global
部分中配置的Syslog服务器。这是通过添加log global
指令来完成的。你可以将其添加到该defaults
部分,如下所示:
defaults
log global
option httplog
该log global
指令基本上说,使用log
该global
部分中设置的行。将log global
指令放入该defaults
部分等同于将其放入所有后续代理部分。因此,这将启用所有代理的日志记录。你可以在我们的博客文章“HAProxy配置的四个基本部分”中阅读有关HAProxy配置文件各部分的更多信息。
默认情况下,HAProxy的输出很小。将行添加option httplog
到你的defaults
部分将启用更详细的HTTP日志记录,稍后我们将对此进行更详细的说明。
典型的HAProxy配置如下所示:
global
log 127.0.0.1:514 local0
chroot /usr/local/haproxy
stats socket /var/run/haproxy.sock mode 600 level admin
stats timeout 2m
maxconn 4096 ###每个进程的最大连接数,默认4000
user haproxy #用户组
group haproxy
daemon ###创建1个进程进入deamon模式运行。此参数要求将运行模式设置为"daemon"
nbproc 1 #设置启动进程数,默认是1
nbthread 4 #4个线程
cpu-map auto:1/1-4 0-3 # 绑定cpu
profiling.tasks on
defaults
mode http
log global ###采用全局定义的日志
option dontlognull ###不记录健康检查的日志信息,日志不会记录空连接
option httpclose ###每次请求完毕后主动关闭http通道
option httplog ###访问日志类别http日志格式
option forwardfor ###如果后端服务器需要获得客户端真实ip需要配置的参数,可以从Http Header中获得客户端ip
option abortonclose #当服务器负载很高的时候,自动结束掉当前队列处理比较久的链接
option redispatch
timeout connect 5000ms #default 10 second timeout if a backend is not found
timeout client 500000 ###客户端连接超时
timeout server 500000 ###服务器返回的响应时间
maxconn 100000 ###最大连接数
retries 3 ###。重试时间。3次连接失败就认为服务不可用,也可以通过后面设置
使用全局日志记录规则是最常见的HAProxy设置,但你可以将它们直接放入某个frontend
部分。将不同的日志记录配置作为一次性配置可能很有用。例如,你可能希望指向不同的目标Syslog服务器,使用不同的日志记录工具,或根据后端应用程序的用例捕获不同的严重性级别。请考虑以下示例,其中linuxea.com-fe_site1和linuxea.com-fe_site2的frontend
部分设置不同的IP地址和严重性级别:
frontend linuxea.com-fe_site1
log 127.0.0.1 local0 notice
# other configuration
frontend linuxea.com-fe_site2
log 127.0.0.2 local0 warning
# other configuration
rsyslog示例
当syslog配置完成后重启即可,而后启动haproxy观察日志
-
start haproxy
[root@www.linuxea.com ~]# haproxy -W -S /var/run/haproxy.sock -f /etc/haproxy/haproxy.cfg
-
haproxy-traffic-linuxea-com.log
[root@www.linuxea.com ~]# tail -f /var/log/haproxy-traffic-linuxea-com.log Jun 5 13:40:23 localhost haproxy[31362]: Proxy stats started. Jun 5 13:40:23 localhost haproxy[31362]: Proxy frontend-web.com started. Jun 5 13:40:23 localhost haproxy[31362]: Proxy backend-linuxea.com started. Jun 5 13:40:44 localhost haproxy[31365]: 10.10.0.96:7925 [05/Jun/2019:13:40:44.813] frontend-web.com backend-linuxea.com/etcd1 0/0/0/1/1 200 235 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1" Jun 5 13:40:46 localhost haproxy[31365]: 10.10.0.96:7933 [05/Jun/2019:13:40:46.215] frontend-web.com backend-linuxea.com/etcd2 0/0/0/0/0 200 243 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1" Jun 5 13:40:46 localhost haproxy[31365]: 10.10.0.96:7934 [05/Jun/2019:13:40:46.589] frontend-web.com backend-linuxea.com/etcd3 0/0/1/1/2 200 237 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1" Jun 5 13:40:46 localhost haproxy[31365]: 10.10.0.96:7941 [05/Jun/2019:13:40:46.813] frontend-web.com backend-linuxea.com/etcd1 0/0/0/1/1 200 235 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1" Jun 5 13:40:47 localhost haproxy[31365]: 10.10.0.96:7942 [05/Jun/2019:13:40:47.078] frontend-web.com backend-linuxea.com/etcd2 0/0/0/0/0 200 243 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1" Jun 5 13:40:47 localhost haproxy[31365]: 10.10.0.96:7943 [05/Jun/2019:13:40:47.213] frontend-web.com backend-linuxea.com/etcd3 0/0/1/1/2 200 237 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1" Jun 5 13:40:47 localhost haproxy[31365]: 10.10.0.96:7944 [05/Jun/2019:13:40:47.420] frontend-web.com backend-linuxea.com/etcd1 0/0/0/1/1 200 235 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1"
-
haproxy-admin-linuxea-com.log
[root@www.linuxea.com ~]# tail -f /var/log/haproxy-admin-linuxea-com.log Jun 5 13:40:23 localhost haproxy[31362]: Proxy stats started. Jun 5 13:40:23 localhost haproxy[31362]: Proxy frontend-web.com started. Jun 5 13:40:23 localhost haproxy[31362]: Proxy backend-linuxea.com started.
UNIX套接字日志记录
记录到本地Syslog服务时,写入UNIX套接字可能比定位TCP回送地址更快。通常,在Linux系统上,在/dev/ log中可以使用侦听Syslog消息的UNIX套接字,因为这是GNU C 库的syslog()*函数默认发送消息的位置。像这样定位UNIX套接字:
log /dev/log local0
但是,你应该记住,如果你要使用UNIX套接字进行日志记录,同时在chrooted环境中运行HAProxy,或者让HAProxy chroot
使用chroot配置指令为你创建目录 -然后必须在该chroot目录中提供UNIX套接字。这可以通过两种方式之一完成。
首先,当rsyslog启动时,它可以在chroot文件系统中创建一个新的侦听套接字。将以下内容添加到HAProxy rsyslog配置文件中:
# unix套接字
$ModLoad imuxsock
$AddUnixListenSocket /usr/local/haproxy/dev/log
第二种方法是使用mount
带有该--bind
选项的命令手动将套接字添加到chroot文件系统。
mkdir /usr/local/haproxy/dev/ -p
touch /usr/local/haproxy/dev/log
mount --bind /dev/log /usr/local/haproxy/dev/log
如果使用第二种方法,请务必在/ etc / fstab文件或systemd单元文件中添加一个条目,以便在重新引导后保持挂载状态。配置完日志后,你将需要了解消息的结构。在下一节中,你将看到组成TCP和HTTP级日志的字段。
套接字配置示例
haproxy.cfg中修改为
global
log /dev/log local0
.....
在/etc/rsyslog.d/haproxy.conf中下面这段是必须的,不管是套接字还是UDP
# Creating separate log files based on the severity
local0.* /var/log/haproxy-traffic-linuxea-com.log
local0.notice /var/log/haproxy-admin-linuxea-com.log
而后添加
# unix套接字
$ModLoad imuxsock
$AddUnixListenSocket /usr/local/haproxy/dev/log
完成的文件格式如下:
[root@www.linuxea.com /etc/haproxy]# cat /etc/rsyslog.d/haproxy.conf
# Collect log with UDP
#$ModLoad imudp
#$UDPServerAddress 127.0.0.1
#$UDPServerRun 514
# Creating separate log files based on the severity
local0.* /var/log/haproxy-traffic-linuxea-com.log
local0.notice /var/log/haproxy-admin-linuxea-com.log
# unix套接字
$ModLoad imuxsock
$AddUnixListenSocket /usr/local/haproxy/dev/log
重启
[root@www.linuxea.com /etc/haproxy]# systemctl restart rsyslog.service
在查看即可
[root@host-www.linuxea.com ~]# tail -f /var/log/haproxy-traffic-linuxea-com.log
Jun 5 14:41:20 host-www.linuxea.com haproxy[3872]: 10.10.195.99:42604 [05/Jun/2019:14:41:20.923] frontend-web.com backend-linuxea.com/etcd3 0/0/0/2/2 200 237 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1"
Jun 5 14:41:20 host-www.linuxea.com haproxy[3872]: 10.10.195.99:42606 [05/Jun/2019:14:41:20.930] frontend-web.com backend-linuxea.com/etcd1 0/0/0/1/1 200 235 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1"
Jun 5 14:41:20 host-www.linuxea.com haproxy[3872]: 10.10.195.99:42608 [05/Jun/2019:14:41:20.936] frontend-web.com backend-linuxea.com/etcd2 0/0/0/0/0 200 243 - - ---- 1/1/0/0/0 0/0 "GET / HTTP/1.1"
Jun 5 14:41:20 host-www.linuxea.com haproxy[3872]: 10.10.195.99:42610 [05/Jun/2019:14:41:20.941] frontend-web.com backend-linuxea.com/etcd3 0/0/1/-1/1 400 187 - - CH-- 1/1/0/0/0 0/0 "GET / HTTP/1.1"
日志限制
如果你需要限制存储的数据量,一种方法是仅采样一部分日志消息。对于随机数量的请求,将日志级别设置为静默,如下所示:
frontend website
http-request set-log-level silent unless { rand(100) lt 5 }
请注意,如果可能,最好尽可能多地捕获数据。这样,你最不需要时就不会丢失信息。你还可以修改ACL表达式,以便某些条件覆盖该规则。
http-request set-log-level silent unless { rand(100) lt 5 } OR <SOME_CONDITION>
限制记录消息数量的另一种方法是option dontlog-normal
在你的defaults
或中设置frontend
。这样,只捕获超时,重试和错误。你可能不希望始终启用此功能,但仅限于某些时间,例如执行基准测试时。
- 注意
如果你使用了日志限制,你将无法正常统计,这些限制会做一些过滤。
docker日志格式
如果你在Docker容器内运行HAProxy并且你正在使用HAProxy版本1.9,那么你可以将其发送到stdout和/或stderr,而不是将日志输出发送到Syslog服务器。将地址分别设置为stdout
或stderr
。在这种情况下,最好将消息的格式设置为raw
,如下所示:
global
log stdout format raw local0 info
HAProxy日志格式
你将看到的日志记录类型由你在HAProxy中设置的代理模式决定。HAProxy可以作为第4层(TCP)代理或第7层(HTTP)代理运行。TCP模式是默认模式。在此模式下,将在客户端和服务器之间建立全双工连接,并且不会执行第7层检查。如果你根据我们在第一部分中的讨论设置了rsyslog配置,你将在/var/log/haproxy-traffic-linuxea-com.log.log中找到该日志文件。
在TCP模式下(通过添加设置)mode tcp
,你还应该添加选项tcplog。使用此选项,日志格式默认为提供有用信息的结构,如第4层连接详细信息,计时器,字节数等。如果要重新创建此格式log-format
,用于设置自定义格式,它将看起来像这样:
log-format "%ci:%cp [%t] %ft %b/%s %Tw/%Tc/%Tt %B %ts %ac/%fc/%bc/%sc/%rc %sq/%bq"
这些字段的描述可以在TCP日志格式文档中找到,尽管我们将在下一节中介绍几个。
当HAProxy作为第7层代理运行时mode http
,你应该添加选项httplog指令。它确保深入分析HTTP请求和响应,并且不会破坏与RFC兼容的内容。这种模式真正突出了HAProxy的诊断价值。HTTP日志格式提供与TCP格式相同级别的信息,但具有特定于HTTP协议的其他数据。如果你要使用重新创建此格式log-format
,它将如下所示:
log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"
可以在HTTP日志格式文档中找到不同字段的详细说明。
你还可以定义自定义日志格式,仅捕获所需内容。在你的或中使用log-format
(或log-format-sd
结构化数据系统日志)指令。阅读我们的博客文章HAProxy Log Customization以了解更多信息并查看一些示例。defaults
`frontend`
在接下来的几节中,你将熟悉使用option tcplog
或时包含的字段 option httplog
。
- 添加的字段示例
frontend www.linuxea.com
bind *:2379
mode http
option httplog
log global
# http-request set-log-level silent unless { rand(100) lt 5 }
default_backend backend-linuxea.com
log-format "%ci:%cp [%tr] %ft %b/%s %TR/%Tw/%Tc/%Tr/%Ta %ST %B %CC %CS %tsc %ac/%fc/%bc/%sc/%rc %sq/%bq %hr %hs %{+Q}r"
代理
在生成的日志文件中,每一行都以请求发送到的前端,后端和服务器开头。例如,如果你具有以下HAProxy配置,则会看到将请求描述为通过http-in前端路由到静态后端然后再路由到srv1服务器的行。
frontend www.linuxea.com
bind :80
default_backend static
backend backend-linuxea.com
server srv1 192.168.1.10:80 check
server srv2 192.168.1.11:80 check
当你需要知道发送请求的位置时(例如,当看到仅影响某些服务器的错误时),这将成为重要信息。
计时器
计时器以毫秒为单位提供,涵盖会话期间发生的事件。默认TCP日志格式捕获的定时器为Tw / Tc / Tt。默认HTTP日志格式提供的是TR / Tw / Tc / Tr / Ta。这些翻译为:
计时器 含义
TR:获取客户端请求的总时间(仅限HTTP模式)。
TW:在等待连接槽的队列中花费的总时间。
TC:建立与服务器的TCP连接的总时间。
TR:服务器响应时间(仅限HTTP模式)。
Ta:HTTP请求的总活动时间(仅限HTTP模式)。
TT:代理接受它的时刻与两端结束时刻之间的总TCP会话持续时间。
你可以在HAProxy文档中找到所有可用计时器的详细说明。下图还演示了在单个端到端事务中记录时间的位置。请注意,边缘上的紫色线条表示计时器。
在单个端到端事务期间记录时间。下图
断开连接时的会话状态
TCP和HTTP日志都包含一个终止状态代码,用于告诉你TCP或HTTP会话的结束方式。这是一个双字符代码。第一个字符报告导致会话终止的第一个事件,而第二个字符报告TCP或HTTP会话状态何时关闭。
以下是一些终止代码示例:
双字符代码 含义
- : 双方正常终止。
cd :客户端没有发送或确认任何数据并最终timeout client到期。
sc :服务器明确拒绝TCP连接。
pc :代理拒绝建立与服务器的连接,因为尝试连接时达到了进程的套接字限制
连接可能已被关闭的原因有很多种。有关所有可能的终止代码的详细信息,请参阅HAProxy文档。
计数器
计数器指示请求通过时系统的运行状况。HAProxy为每个连接或请求记录五个计数器。它们在确定系统上放置了多少负载,系统滞后的位置以及是否已达到限制时非常有用。查看日志中的一行时,你会看到列为由斜杠分隔的五个数字的计数器:0/0/0/0/0。
在TCP或HTTP模式下,这些分解为:
- 记录会话时HAProxy进程上的并发连接总数。
frontend
记录会话时通过此路由的并发连接总数。backend
记录会话时路由到此的并发连接总数。server
记录会话时,此时仍然处于活动状态的并发连接总数。- 尝试连接到后端服务器时尝试的重试次数
日志字段
HAProxy不会记录开箱即用的所有内容,但你可以调整它以捕获你需要的内容。
- 可以通过添加
http-request capture
指令来记录HTTP请求标头:
frontend website
bind :80
http-request capture req.hdr(Host) len 10
http-request capture req.hdr(User-Agent) len 100
default_backend webservers
日志将显示花括号之间的标题,并用管道符号分隔。在这里,你可以看到请求的主机和用户代理标头:
Jun 5 14:52:36 host-www.linuxea.com haproxy[4756]: 10.10.0.96:4910 [05/Jun/2019:14:52:36.613] frontend-web.com backend-linuxea.com/etcd1 0/0/0/1/1 200 235 - - ---- 1/1/0/0/0 0/0 {172.25.10.|like Gecko) Chrome/74.0.3729.169 Safari/537.36} "GET / HTTP/1.1"
相比此前,日志中多了头部信息
- 可以通过添加
http-response capture
指令来记录响应头:
frontend website
bind :80
declare capture response len 20
http-response capture res.hdr(Server) id 0
declare capture response len 20
http-response capture res.hdr(Content-Type) id 1
default_backend webservers
在这种情况下,你还必须添加一个declare capture response
指令,该指令分配一个捕获槽,一旦响应头到达,它就可以存储。你添加的每个插槽都会自动分配一个从零开始的ID。在致电时引用此ID http-response capture
。请求标头之后,在一组单独的花括号内记录响应标头。日志表现如下:
Jun 5 14:54:19 host-www.linuxea.com haproxy[4914]: 10.10.0.96:5497 [05/Jun/2019:14:54:19.382] frontend-web.com backend-linuxea.com/etcd1 0/0/1/0/1 200 235 - - ---- 1/1/0/0/0 0/0 {172.25.10.|like Gecko) Chrome/74.0.3729.169 Safari/537.36} {nginx|text/html} "GET / HTTP/1.1"
可以看出,上述的日志中相比此前,多了{nginx|text/html}
- 可以使用与
http-request capture
指令类似的方式记录Cookie值。
frontend website
bind :80
http-request capture req.cook(MyCookie) len 20
default_backend webservers
捕获的任何内容http-request capture
(包括HTTP标头和cookie)都将出现在同一组花括号中。任何捕获的东西都是如此http-response capture
。
Jun 5 14:57:27 host-www.linuxea.com haproxy[4987]: 10.10.0.96:6550 [05/Jun/2019:14:57:27.287] frontend-web.com backend-linuxea.com/etcd1 0/0/0/1/1 304 166 - - ---- 1/1/0/0/0 0/0 {172.25.10.|like Gecko) Chrome/74.0.3729.169 Safari/537.36|} {nginx|} "GET / HTTP/1.1"
- 你还可以使用
http-request capture
记录棒表中的采样数据。如果你使用a 跟踪用户请求率stick-table
,则可以将其记录为:
frontend website
bind :80
stick-table type ip size 1m expire 10s store http_req_rate(10s)
http-request track-sc0 src
http-request capture sc_http_req_rate(0) len 4
default_backend webservers
因此,向包含HTML文档和两个图像的网页发出请求会显示用户的并发请求率增加到三个:
Jun 5 15:13:24 host-www.linuxea.com haproxy[5141]: 10.10.195.99:21260 [05/Jun/2019:15:13:24.290] frontend-web.com backend-linuxea.com/etcd2 0/0/0/0/0 200 243 - - ---- 1/1/0/0/0 0/0 {172.25.10.|curl/7.29.0||1} {nginx|text/html} "GET / HTTP/1.1"
Jun 5 15:13:25 host-www.linuxea.com haproxy[5141]: 10.10.195.99:21584 [05/Jun/2019:15:13:25.298] frontend-web.com backend-linuxea.com/etcd3 0/0/1/1/2 200 237 - - ---- 1/1/0/0/0 0/0 {172.25.10.|curl/7.29.0||2} {nginx|text/html} "GET / HTTP/1.1"
Jun 5 15:13:26 host-www.linuxea.com haproxy[5141]: 10.10.195.99:21738 [05/Jun/2019:15:13:26.308] frontend-web.com backend-linuxea.com/etcd1 0/0/0/1/1 200 235 - - ---- 1/1/0/0/0 0/0 {172.25.10.|curl/7.29.0||3} {nginx|text/html} "GET / HTTP/1.1"
你还可以记录fetch方法的值,例如记录所使用的SSL / TLS的版本(请注意,有一个内置的日志变量用于获取这个名为%sslv):
# logs 'TLSv1.2'
http-request capture ssl_fc_protocol len 10
设置的变量http-request set-var
也可以记录。
frontend website
bind :80
http-request set-var(req.MyVariable) str("My Value") if SOME_CONDITION
http-request capture var(req.MyVariable) len 10
ACL表达式计算为true或false。你无法直接记录它们,但可以根据表达式是否为true来设置变量。例如,如果用户访问/ api,你可以将名为req.is_api的变量设置为Is API的值,然后在日志中捕获该值
acl is_api path_beg /api
http-request set-var(req.is_api) str("Not API")
http-request set-var(req.is_api) str("Is API") if is_api
http-request capture var(req.is_api) len 10
启用HAProxy性能分析
随着HAProxy 1.9的发布,你可以记录在HAProxy中处理请求所花费的CPU时间。将profiling.tasks
指令添加到你的global
部分:
global
profiling.tasks on
有一些新的fetch方法可以公开分析指标:
获取方法 : 描述
date_us : 日期的微秒部分。
cpu_calls : 自分配以来处理流或当前请求的任务的调用次数。它会在同一连接上为每个新请求重置。
cpu_ns_avg : 每次调用处理流或当前请求的任务所花费的平均纳秒数。
cpu_ns_tot : 每次调用处理流或当前请求的任务所花费的总纳秒数。
lat_ns_avg : 在处理流的任务被唤醒的那一刻和它被有效调用的那一刻之间花费的平均纳秒数。
lat_ns_tot : 唤醒流的任务被唤醒的时刻与有效调用流的时刻之间的总纳秒数。
将这些添加到你的日志消息,如下所示:
log-format "%{+Q}r cpu_calls:%[cpu_calls] cpu_ns_tot:%[cpu_ns_tot] cpu_ns_avg:%[cpu_ns_avg] lat_ns_tot:%[lat_ns_tot] lat_ns_avg:%[lat_ns_avg]"
# Outputs: "GET / HTTP/1.1" cpu_calls:2 cpu_ns_tot:7928946 cpu_ns_avg:3964473 lat_ns_tot:49814 lat_ns_avg:24907
这是衡量哪些请求成本最高的好方法。日志就是这样的:
Jun 5 15:16:21 host-www.linuxea.com haproxy[5250]: "GET / HTTP/1.1" cpu_calls:3 cpu_ns_tot:313669 cpu_ns_avg:104556 lat_ns_tot:45154 lat_ns_avg:15051
Jun 5 15:16:23 host-www.linuxea.com haproxy[5250]: "GET / HTTP/1.1" cpu_calls:4 cpu_ns_tot:268475 cpu_ns_avg:67118 lat_ns_tot:52472 lat_ns_avg:13118
Jun 5 15:16:24 host-www.linuxea.com haproxy[5250]: "GET / HTTP/1.1" cpu_calls:3 cpu_ns_tot:236518 cpu_ns_avg:78839 lat_ns_tot:44106 lat_ns_avg:14702
Jun 5 15:16:24 host-www.linuxea.com haproxy[5250]: "GET / HTTP/1.1" cpu_calls:3 cpu_ns_tot:318006 cpu_ns_avg:106002 lat_ns_tot:36628 lat_ns_avg:12209
Jun 5 15:16:24 host-www.linuxea.com haproxy[5250]: "GET / HTTP/1.1" cpu_calls:3 cpu_ns_tot:138176 cpu_ns_avg:46058 lat_ns_tot:31253 lat_ns_avg:10417
解析HAProxy日志
正如你所了解的那样,HAProxy有很多字段可以提供关于连接和请求的大量见解。但是,直接读取它们会导致信息过载。通常,使用外部工具解析和聚合它们更容易。在本节中,你将看到其中一些工具以及它们如何利用HAProxy提供的日志记录信息。
HALog
HALog是一个小而强大的日志分析工具,随HAProxy一起提供。它旨在部署到生产服务器上,可以帮助进行手动故障排除,例如面对实时问题时。它非常快,能够以每秒1到2 GB的速度解析TCP和HTTP日志。通过传递标志组合,你可以从日志中提取统计信息,包括每个URL的请求和每个源IP的请求。然后,你可以按响应时间,错误率和终止代码进行排序。
- 我们先开始讨论如何安装
[root@host-www.linuxea.com ~]# cd /usr/local/haproxy-1.9.0/contrib/halog/
[root@host-www.linuxea.com /usr/local/haproxy-1.9.0/contrib/halog]# make
make: `halog' is up to date.
[root@host-www.linuxea.com /usr/local/haproxy-1.9.0/contrib/halog]# ll
total 108
-rw-rw-r-- 1 root root 7701 Dec 20 02:13 fgets2.c
-rwxr-xr-x 1 root root 45208 Jun 5 15:39 halog
-rw-rw-r-- 1 root root 47299 Dec 20 02:13 halog.c
-rw-rw-r-- 1 root root 753 Dec 20 02:13 Makefile
[root@DT_Node-172_25_10_245 /usr/local/haproxy-1.9.0/contrib/halog]# cp halog /usr/local/bin/
例如,如果要从日志中提取每服务器统计信息,可以使用以下命令:
[root@host-www.linuxea.com /var/log]# halog -srv -H < haproxy.log | column -t
19 lines in, 3 lines out, 15 parsing errors
#srv_name 1xx 2xx 3xx 4xx 5xx other tot_req req_ok pct_ok avg_ct avg_rt
backend-linuxea.com/etcd1 0 1 0 0 0 0 1 1 100.0 0 1
backend-linuxea.com/etcd2 0 1 0 0 0 0 1 1 100.0 0 0
backend-linuxea.com/etcd3 0 2 0 0 0 0 2 2 100.0 1 0
当你需要解析每个状态代码的日志行并快速发现给定服务器是否不健康时(例如,返回太多5xx响应),这非常有用。或者,服务器可能拒绝太多请求(4xx响应),这是暴力攻击的标志。你还可以使用该avg_rt
列获取每台服务器的平均响应时间,这有助于进行故障排除。
使用HALog,你可以使用以下命令获取每URL统计信息:
[root@host-www.linuxea.com /var/log]# halog -ut -H < haproxy.log | column -t
19 lines in, 1 lines out, 15 parsing errors
#req err ttot tavg oktot okavg bavg btot src
4 0 2 0 2 0 238 952 /
输出显示请求数,错误数,总计算时间,平均计算时间,成功请求的总计算时间,成功请求的平均计算时间,发送的平均字节数以及总数发送的字节数。除了解析服务器和URL统计信息之外,你还可以应用多个过滤器来匹配具有给定响应时间,HTTP状态代码,会话终止代码等的日志。
HAProxy Stats
使用HALog解析日志并不是从HAProxy中获取指标的唯一方法。该HAProxy的统计页面可以通过添加启用stats enable
指令到一个frontend
或listen
部分。它显示服务器的实时统计信息。以下listen
部分启动Stats页面,侦听端口8404:
listen stats
bind *:8404
stats enable
stats uri /
stats refresh 5s
统计页面对于获取有关流经HAProxy的流量的即时信息非常有用。但是,它不存储此数据,仅显示单个负载均衡器的数据。
延伸阅读
linuxea:haproxy 1.9中的多线程linuxea:haproxy1.9 了解四个基础部分