我在让 rsyslog 生成正确的 Logstash 格式时遇到问题。我正在接收远程 rsyslog 消息(使用 RELP),然后使用通过 mmexternal 加载的一些定制代码来处理这些消息。 mmexternal 定制代码的输出采用字符串形式,表示 json 对象,详细说明原始消息中所需的字段。该对象是使用 json 库创建的,然后转换为字符串(即
std::string output Json::writeString(builder, jsonObject);
),如果我将数据输出到 omfile 类型的日志文件 (my_rsyslog.conf),这似乎可以正常工作。此输出旨在形成发送到 Logstash 的 json 消息的“内部”部分,即外部部分将由 rsyslog 本身提供时间戳、严重性、procid 等,以便在 mmexternal 定制代码之外进行处理。输出看起来正确,并且 json 键和值的引号(需要时)未转义。
但是,当我尝试将输出放入 rsyslog 中的 json 模板时,我得到的内部 json 格式错误,其中引号包含转义字符。这成为 Logstash 的一个问题,因为它收到的消息中只有一部分是有用的,即只有时间戳、严重性、procid 等。logstash 无法使用 json 块内部。
我正在使用AlmaLinux9、Rsyslog 8.2102.0-113.el9_2、Logstash 8.8.2-1。
我已经尝试过这个模板(在https://www.digitalocean.com/community/tutorials/how-to-centralize-logs-with-rsyslog-logstash-and-elasticsearch-on-ubuntu-14-04 ):
template(name="json-template"
type="list") {
constant(value="{")
constant(value="\"@timestamp\":\"") property(name="timereported" dateFormat="rfc3339")
constant(value="\",\"sysloghost\":\"") property(name="hostname")
constant(value="\",\"severity\":\"") property(name="syslogseverity-text")
constant(value="\",\"procid\":\"") property(name="procid")
constant(value="\",\"message\":\"") property(name="msg" format="json")
constant(value="\"}\n")
}
在logstash输出中(我在前台模式下运行),除了消息字段之外,所有字段看起来都是正确的,它看起来像这样:
"@timestamp" => 2023-08-29T<blah blah>,
<another correctly formatted field>,
"message" => "{ \"blocks*\": [\"blockID\"...< more stuff>...] }", # unwanted quotes enclosing string and escaped quotes within.
对于消息字段的格式,我使用了 json、jsonf、jsonr 和 jsonfr。似乎没有什么区别。
我还删除了包含消息字段的引号,如下所示:
constant(value="\",\"message\":") property(name="msg" format="json")
constant(value="}\n")
但这只会更多地破坏输出。
我还考虑过使用“更容易”来使用更新的模板格式(在这里找到:https://rainer.gerhards.net/2018/02/simplifying-rsyslog-json- Generation.html),但我得到相同的结果:
template(name="json-template" type="list" option.jsonf="on") {
property(outname="@timestamp"
name="timereported"
dateFormat="rfc3339" format="jsonf")
property(outname="message"
name="msg" format="jsonf")
}
有趣的是,如果我将 jsonf 更改为 json,每个引号中都会有更多转义字符,即
\\\\\\\"
任何帮助将不胜感激。
肖恩。
在使用 rsyslog 的模板将日志转发到 Logstash 时,您似乎遇到了
message
字段的 JSON 格式问题。为了确保 message
字段正确格式化为 JSON,并且没有不必要的转义字符,您可以按如下方式修改 rsyslog 模板:
template(name="json-template" type="list") {
constant(value="{")
constant(value="\"@timestamp\":\"") property(name="timereported" dateFormat="rfc3339" format="json")
constant(value="\",\"sysloghost\":\"") property(name="hostname")
constant(value="\",\"severity\":\"") property(name="syslogseverity-text")
constant(value="\",\"procid\":\"") property(name="procid")
constant(value="\",\"message\":") property(name="msg" format="json")
constant(value="\"}\n")
}
在此更新的模板中,我进行了以下更改:
message
之前的 constant
行中不必要的 "message\":
字段转义。这应该可以防止输出中出现额外的反斜杠。此模板应生成格式正确的 JSON
message
字段,没有不必要的转义字符。进行此更改后,重新启动 rsyslog 服务以应用更新的配置。
如果您仍然遇到 JSON 格式问题,请确保您使用的 rsyslog 版本支持
format="json"
指令的 property
选项。如果没有,请考虑升级到包含此功能的新版本 rsyslog。
一旦 rsyslog 配置正确,Logstash 应该能够毫无问题地解析 JSON
message
字段。