有没有一种方法可以使用rsyslog config解析日志消息并将其转换为结构化消息?

时间:2018-10-03 23:19:55

标签: rsyslog

我正在尝试解析日志消息,并使用rsyslog将其转换为结构化消息。有没有办法通过rsyslog config支持这种操作?我尚未探索为此编写自定义解析器或消息修改插件的选项。

我发现template list properties可以做到这一点。有没有办法做到以下几点?

  1. 将2个字段映射到单个输出名称。例如:“ __ ts”:“ 2018-09-20 10:18:56.363”(下面示例中的前2个字段)。由于我在寻找不依赖于字段值的解决方案,因此此处将不使用正则表达式。例如:这两个字段可以是两个字符串或其他一些值,而不仅仅是日期。
  2. 根据位置提取所有已知字段后,提取味精中的剩余量。例如:“ msg”:“正在使用状态为DOWN的someOtherName注销应用程序nameOfAnApiHere”。
  3. 是否可以使用local variables来保存msg中的字段值并使用模板中的变量?

示例日志消息:

2018-09-20 10:18:56.363信息--[Thread-68] x.y.z.key1Value正在使用状态为DOWN的someOtherName注销应用程序nameOfAnApiHere

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"
          }
       }
     ]
}

谢谢。

1 个答案:

答案 0 :(得分:1)

您还可以使用正则表达式来匹配消息的各个部分。例如,将您的outname="__ts"属性替换为:

 property(outname="__ts" name="msg" 
  regex.expression="([^ ]+ +[^ ]+)" 
  regex.type="ERE" 
  regex.submatch="1" format="jsonf")

在这里,扩展正则表达式(ERE)查找其中一个或多个(+)的非空格([^ ]),然后是一个或多个空格,以及另一个非空格。 ()将这两个单词捕获为子匹配项,然后从1开始选择该单词。结果应该是您想要的。

您可以类似地将正则表达式用于第二个要求,方法是再次计算“单词”和空格,或者进行更精确的其他匹配。此处,正则表达式通过在单词和空格模式之后放置重复计数{6}来跳过6个单词,然后捕获其余单词(.*)。由于()有2套,因此要保留的子匹配现在为2,而不是1:

 property(name="msg" 
  regex.expression="([^ ]+ +){6}(.*)" 
  regex.type="ERE" 
  regex.submatch="2" format="jsonf" droplastlf="on" )