有没有办法使用 rsyslog 配置解析日志消息并将它们转换为结构化消息?
Is there a way parse log messages using rsyslog config and transform them to structured messages?
我正在尝试解析日志消息并使用 rsyslog 将它们转换为结构化消息。有没有办法用 rsyslog 配置支持这样的操作?我还没有探索为此编写自定义解析器或消息修改插件的选项。
我发现 template list properties 可以做一些。有没有办法做到以下几点?
- 将 2 个字段映射到单个输出名称。例如:“__ts”:“2018-09-20 10:18:56.363”(以下示例中的前 2 个字段)。不会在这里使用正则表达式,因为我正在寻找一种不依赖于字段值的解决方案。例如:这两个字段可以是两个字符串或一些其他值而不仅仅是日期。
- 根据位置提取所有已知字段后,提取 msg 中剩余的内容。例如:"msg":"Unregistering application nameOfAnApiHere with someOtherName with status DOWN"。
- 有没有办法使用 local variables 来保存来自 msg 的字段值并使用模板中的变量?
示例日志消息:
2018-09-20 10:18:56.363 INFO --- [Thread-68] x.y.z.key1Value 取消注册应用程序 nameOfAnApiHere 和 someOtherName,状态为 DOWN
1. rsyslog 配置模板定义
template(name="structure-log-format" type="list") {
constant(value="{")
# This only extracts the first field with value 2018-09-20.
# TODO: What is a way to map first 2 fields to map to __ts field?
property(outname="__ts" name="msg" field.number="1" field.delimiter="32" format="jsonf") constant(value=", ")
constant(value="\"event\":[{")
constant(value="\"payload\":{")
property(outname="_log_" name="syslogtag" format="jsonf") constant(value=", ")
property(outname="__loglvl" name="msg" field.number="4" field.delimiter="32" format="jsonf") constant(value=", ")
property(outname="__thread" name="msg" field.number="7" field.delimiter="32" format="jsonf") constant(value=", ")
property(outname="__key1" name="msg" field.number="8" field.delimiter="32" format="jsonf") constant(value=", ")
# The following setting will include full message value starting from "2018-09-20 ... DOWN"
# TODO: What is a way to only include message starting from "Unregistering ... DOWN"?
property(name="msg" format="jsonf" droplastlf="on" )
constant(value="}")
constant(value="}]} \n")
}
2。预期结果:
{
"__ts": "2018-09-20 10:18:56.363",
"event": [
{
"payload": {
"_log_": "catalina",
"__loglvl": "INFO",
"__thread": "Thread-68",
"__key1": "x.y.z.key1Value",
"msg": "Unregistering application nameOfAnApiHere with someOtherName with status DOWN"
}
}
]
}
3。实际结果:
{
"__ts": "2018-09-20",
"event": [
{
"payload": {
"_log_": "catalina",
"__loglvl": "INFO",
"__thread": "Thread-68",
"__key1": "x.y.z.key1Value",
"msg": "2018-09-20 10:18:56.363 INFO 2144 --- [Thread-68] x.y.z.key1Value Unregistering application nameOfAnApiHere with someOtherName with status DOWN"
}
}
]
}
谢谢。
您还可以使用正则表达式来匹配消息的各个部分。例如,将 outname="__ts"
属性 替换为:
property(outname="__ts" name="msg"
regex.expression="([^ ]+ +[^ ]+)"
regex.type="ERE"
regex.submatch="1" format="jsonf")
此处扩展正则表达式 (ERE) 查找非 space ([^ ]
) 中的一个或多个 (+),后跟 space 或多个,还有一个不是-space。这2个词被()
捕获为子匹配,你select这个,从1开始计数。结果应该如你所愿。
您可以类似地为第二个要求使用正则表达式,通过再次计算 "words" 和 spaces,或者更精确的其他匹配。此处正则表达式通过在单词和 space 模式之后放置重复计数 {6}
来跳过 6 个单词,然后捕获其余单词 (.*
)。由于有 2 组 ()
,因此要保留的子匹配现在是 2,而不是 1:
property(name="msg"
regex.expression="([^ ]+ +){6}(.*)"
regex.type="ERE"
regex.submatch="2" format="jsonf" droplastlf="on" )
我正在尝试解析日志消息并使用 rsyslog 将它们转换为结构化消息。有没有办法用 rsyslog 配置支持这样的操作?我还没有探索为此编写自定义解析器或消息修改插件的选项。
我发现 template list properties 可以做一些。有没有办法做到以下几点?
- 将 2 个字段映射到单个输出名称。例如:“__ts”:“2018-09-20 10:18:56.363”(以下示例中的前 2 个字段)。不会在这里使用正则表达式,因为我正在寻找一种不依赖于字段值的解决方案。例如:这两个字段可以是两个字符串或一些其他值而不仅仅是日期。
- 根据位置提取所有已知字段后,提取 msg 中剩余的内容。例如:"msg":"Unregistering application nameOfAnApiHere with someOtherName with status DOWN"。
- 有没有办法使用 local variables 来保存来自 msg 的字段值并使用模板中的变量?
示例日志消息:
2018-09-20 10:18:56.363 INFO --- [Thread-68] x.y.z.key1Value 取消注册应用程序 nameOfAnApiHere 和 someOtherName,状态为 DOWN
1. rsyslog 配置模板定义
template(name="structure-log-format" type="list") {
constant(value="{")
# This only extracts the first field with value 2018-09-20.
# TODO: What is a way to map first 2 fields to map to __ts field?
property(outname="__ts" name="msg" field.number="1" field.delimiter="32" format="jsonf") constant(value=", ")
constant(value="\"event\":[{")
constant(value="\"payload\":{")
property(outname="_log_" name="syslogtag" format="jsonf") constant(value=", ")
property(outname="__loglvl" name="msg" field.number="4" field.delimiter="32" format="jsonf") constant(value=", ")
property(outname="__thread" name="msg" field.number="7" field.delimiter="32" format="jsonf") constant(value=", ")
property(outname="__key1" name="msg" field.number="8" field.delimiter="32" format="jsonf") constant(value=", ")
# The following setting will include full message value starting from "2018-09-20 ... DOWN"
# TODO: What is a way to only include message starting from "Unregistering ... DOWN"?
property(name="msg" format="jsonf" droplastlf="on" )
constant(value="}")
constant(value="}]} \n")
}
2。预期结果:
{
"__ts": "2018-09-20 10:18:56.363",
"event": [
{
"payload": {
"_log_": "catalina",
"__loglvl": "INFO",
"__thread": "Thread-68",
"__key1": "x.y.z.key1Value",
"msg": "Unregistering application nameOfAnApiHere with someOtherName with status DOWN"
}
}
]
}
3。实际结果:
{
"__ts": "2018-09-20",
"event": [
{
"payload": {
"_log_": "catalina",
"__loglvl": "INFO",
"__thread": "Thread-68",
"__key1": "x.y.z.key1Value",
"msg": "2018-09-20 10:18:56.363 INFO 2144 --- [Thread-68] x.y.z.key1Value Unregistering application nameOfAnApiHere with someOtherName with status DOWN"
}
}
]
}
谢谢。
您还可以使用正则表达式来匹配消息的各个部分。例如,将 outname="__ts"
属性 替换为:
property(outname="__ts" name="msg"
regex.expression="([^ ]+ +[^ ]+)"
regex.type="ERE"
regex.submatch="1" format="jsonf")
此处扩展正则表达式 (ERE) 查找非 space ([^ ]
) 中的一个或多个 (+),后跟 space 或多个,还有一个不是-space。这2个词被()
捕获为子匹配,你select这个,从1开始计数。结果应该如你所愿。
您可以类似地为第二个要求使用正则表达式,通过再次计算 "words" 和 spaces,或者更精确的其他匹配。此处正则表达式通过在单词和 space 模式之后放置重复计数 {6}
来跳过 6 个单词,然后捕获其余单词 (.*
)。由于有 2 组 ()
,因此要保留的子匹配现在是 2,而不是 1:
property(name="msg"
regex.expression="([^ ]+ +){6}(.*)"
regex.type="ERE"
regex.submatch="2" format="jsonf" droplastlf="on" )