首页 > 解决方案 > rsyslog 配置以合并来自 imuxsock 的多行

问题描述

我有一个将其输出写入标准输出并由 systemd 管理的 Web 服务。systemd 配置将标准输出发送到 syslog。我遇到的问题是多行消息被分成多个系统日志条目。这是异常堆栈跟踪的一个问题。有没有办法配置 rsyslog 将它们合并到一个条目中?我找到了一些使用其readMode属性的解决方案,imfile这正是我需要的,但在我的情况下,我直接从 default 接收数据imuxsock

我正在使用的测试正在运行

echo -e "<<hello\n\tsecond\n\tthird\nnew message>>" | logger -t my-tag

这会产生

May 16 17:06:46 host my-tag: <<hello
May 16 17:06:46 host my-tag:    second
May 16 17:06:46 host my-tag:    third
May 16 17:06:46 host my-tag: new message>>

但我想得到的是

May 16 17:06:46 host my-tag: <<hello
    second
    third
May 16 17:06:46 host my-tag: new message>>

这可能吗?该行为可以描述为imfilereadMode 中的模式 2

2 - 缩进(新的日志消息从行首开始。如果一行以空格或制表符“t”开头,则它是之前日志消息的一部分)

需要注意的是,因为它不是像 imfile 消耗的静态数据,所以需要一个计时器,1s 或其他东西,如果没有收到新数据,我们假设日志条目已终止

标签: systemdrsyslog

解决方案


您可以使用omprog rsyslog模块尝试将数据线缝合在一起。例如,配置

$ModLoad omprog
:syslogtag, isequal, "my-tag:" action(type="omprog"
    binary="/bin/myprog" output="/var/log/myoutput")

将运行程序并将所有带有标签/bin/myprog的输入传递给它。my-tag程序的任何输出都将保存到文件/var/log/myoutput中。

下面的示例程序使用了一个脚本,该脚本使用没有终止换行符awk来打印行。printf具有以制表符开头的消息部分(此处由rsyslogoctal转义#011)的输入将类似地被打印。将在任何没有选项卡的输入之前打印换行符,新消息也是如此。我让你添加一个刷新超时。

#!/bin/sh
awk '
/my-tag: #011/{
     i = index($0,"#011")
     printf "\n\t%s",substr($0,i+4)
     next
}
{    if(NR>1)printf "\n"; fflush();
     printf "%s",$0
}'

注意这是 gnu awk (gawk),它有一个fflush()命令。否则,您可能需要类似stdbuf命令来停止缓冲。


推荐阅读