通过 rsyslogd(8) 进行异步日志记录并增加写入缓冲区

ari*_*ica 9 vmware logging rsyslog

在一个运行在虚拟容器 (VMware) 中且缺乏本地存储的高流量网站上,我们通过从直接登录到日志文件(驻留在远程网络存储上)切换到rsyslogd

本质上,我们已经从同步日志切换到异步日志记录。Web 服务器工作人员使用syslog(3)写入一些内存缓冲区,然后rsyslogd(8)将数据以自己的速度并行发送到实际文件,因此进程在记录时不会阻塞 IO。

到现在为止还挺好。问题是偶尔会阻止rsyslogd写入(例如,暂时/长时间的网络中断)并且传入缓冲区会迅速填满。

我的问题是:

  • 使用syslog(3)写入rsyslogd时,客户端是否会阻塞?
  • 有没有办法查看rsyslogd统计信息,例如缓冲区有多大/满?
  • 有没有办法增加rsyslogd传入缓冲区的大小?

小智 1

据我记得 rsyslog 中主消息队列的默认模式是固定大小数组。它有 10k 左右元素的限制。尝试将其更改为链表队列,它应该可以更好地处理偶尔的消息突发。

是的,有FixedArrayLinkedList排队。


Enz*_*zoR 1

你的第一个问题的答案是:

是的,任何对 syslog() 的调用都会被阻塞。也许时间很短,但它仍然是涉及文件描述符的同步调用。请参阅man 3 syslog获取更多详细信息。

除非您的服务器使用异步架构和原语,否则总会有一些锁定。这种情况可以减轻,但不能消除,例如通过使用单独的线程进行日志记录。对于另外两个问题,我不太清楚,但检查 rsyslogd 源代码(以及 syslog() 系列函数的源代码)是了解的唯一方法。

更一般地说,如果您通过 UDP:514“网络系统日志协议”将日志记录移动到外部服务器,那么创建锁的可能性几乎为零。缺点是在高负载期间可能会丢失一些日志记录

首先,在“原始”服务器中,您需要确保所有日志记录都是通过系统日志进行的。例如,在 Apache2 中您需要指定:

ErrorLog "syslog:daemon"
Run Code Online (Sandbox Code Playgroud)

对于其他服务器,请参阅相应的手册页。如果您不能确保这一点,请记住登录文件系统可能会创建

其次,在原始 rsyslogd 配置中,您要求将您选择的设施(本例中的“守护进程”)的所有系统日志流量定向到一个或多个外部系统日志服务器。在 rsyslog 配置文件中您可以指定:

daemon.* @192.168.128.1
daemon.* @192.168.254.1
Run Code Online (Sandbox Code Playgroud)

将日志的两个副本同时发送到两个不同的服务器。

第三,在目标服务器中启用通过 UDP:514 接收系统日志消息。它位于(目标)rsyslogd 配置文件中,通常默认禁用(删除前导 # 就足够了:

$ModLoad imudp
$UDPServerRun 514
Run Code Online (Sandbox Code Playgroud)

第四,可选但强烈推荐,我还将启用高分辨率时间戳:

$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat
Run Code Online (Sandbox Code Playgroud)

此外,此选项通常默认被禁用(到底为什么?)。