流利的解析

Fluentd Parsing

您好,我正在尝试使用 fluentd 解析单行日志。这是我正在尝试解析的日志。

F2:4200000000000000,F3:000000,F4:000000060000,F6:000000000000,F7:000000000,F8..........etc

这将解析成这样:

{ "F2"   : "4200000000000000", "F3" : "000000", "F4"   : "000000060000" ............etc }

我尝试使用正则表达式,但它令人困惑,让我为不同的键和值编写了多个正则表达式。有没有更简单的方法来实现这个目标?

EDIT1:嘿嘿!我会让这个更详细。我目前正在使用 fluentd 跟踪日志到 Elasticsearch+Kibana。这是流利地发送到 Elasticsearch 的未解析示例日志:

21/09/02 16:36:09.927238: 1 frSMS:0:13995:#HTF4J::141:141:msg0210,00000000000000000,000000,000000,007232,00,#,F2:00000000000000000,F3:002000,F4:000000820000,F6:Random message and strings,F7:.......etc

{"message":"frSMS:0:13995:#HTF4J::141:141:msg0210,00000000000000000,000000,000000,007232,00,#,F2:00000000000000000,F3:002000,F4:000000820000,F6:Random digits and chars,F7:.......etc"}

此日志只有消息键,因此我无法仅使用整个消息字段编制索引和创建仪表板。我想要实现的是只捕获有用的字段,如果它没有键则将键添加到其中并使索引更容易。

{"logdate" : "21/09/02 16:36:09.927238",
     "source" : "frSMS",
     "UID" : "#HTF4J",
     "statuscode" : "msg0210",
     "F2": "00000000000000000",
     "F3": "randomchar314516",.....}

我使用了正则表达式插件来解析这个但是它太过分了而且 .这是我到目前为止所做的:

^(?<logDate>\d{2}.\d{2}.\d{2}\s\d{2}:\d{2}:\d{2}.\d{6}\b)....(?<source>fr[A-Z]{3,4}|to[A-Z]{3,4}\b).(?<status>\d\b).(?<dummyfield>\d{5}\b).(?<HUID>.[A-Z]{5}\b)..(?<d1>\d{3}\b).(?<d2>\d{3}\b).(?<msgcode>msg\d{4}\b).(?<dummyfield1>\d{16}\b).(?<dummyfield2>\d{6}\b).(?<dummyfield3>\d{6,7}\b).(?<dummyfield4>\d{6}\b).(?<dummyfield5>\d{2}\b)...

结果为:

"logDate": "21/09/02 16:36:09.205706", "source": "toSMS" , "status": "0", "dummyfield": "13995" , "UID" : "#HTFAA" , "d1" : "156" , "d2" : "156" , "msgcode" : "msg0210", "dummyfield1" :"0000000000000000" , "dummyfield2" :"002000", "dummyfield3" :"2000000", "dummyfield4" :"00", "dummyfield5" :"2000000" , "dummyfield6" :"867202"

仅适用于示例日志,并且包含无用的字段,如 field1、dummyfield、dummyfield1 等。 其他日志具有有用的值和键(日期、源、消息代码、UID、F1、F2 字段),就像我在预期输出中展示的那样。无用的字段不是静态的(它们可以是 none,或者有更少|更多的数字和字符)所以它们触发模式不匹配错误。

所以问题是:

  1. 如何使用正则表达式捕获我提到的有用字段?
  2. 如何捕获 F1,F2,F3...... 具有不同值的字段 混合字符串等模式?

PS:我将我写入的正则表达式封装到 html 片段中,这样 <> 捕获字段就不会被删除

要使用的正则表达式模式:

(F[\d]+):([\d]+)

此模式将捕获所有 'F' 值及其后的任何数字 - 是的,即使它是 F105 它仍然有效。整个 'F105' 将作为第一组存储在您的正则表达式匹配表达式

上述模式的右侧部分将捕获 ':' 之后的所有数字的值,直到任何不是数字的字符。即 ',', 'F', etc.. 并将其存储为正则表达式匹配中的第二组

使用

根据您的编码语言,您将必须使用迭代器访问正则表达式 matches 变量并分别提取 group 1group 2

Python 示例:

import re

log = 'F2:4200000000000000,F3:000000,F4:000000060000,F6:000000000000,F7:000000000,F105:9726450'
pattern = '(F[\d]+):([\d]+)'
matches = re.finditer(pattern,log)
log_dict = {}
for match in matches:
    log_dict[match.group(1)] = match.group(2) 
print(log_dict)

输出

{'F2': '4200000000000000', 'F3': '000000', 'F4': '000000060000', 'F6': '000000000000', 'F7': '000000000', 'F105': '9726450'}

假设日志日期将是静态的(在模式方面)您可以使用“.+”正则表达式忽略无用的值,并通过它们的模式收集有用的值。所以正则表达式将是这样的:

(?\d{2}.\d{2}.\d{2}\s\d{2}:\d{2}:\d{2}.\d{6}\b).+(?fr[A-Z]{3,4}|to[A-Z]{3,4}).+(?#[A-Z0-9]{5}).+(?msg\d{4})

输出如下:

{"logdate" : "21/09/02 16:36:09.927238", "source" : "frSMS", "UID" : "#HTF4J","statuscode" : "msg0210"}

我正在努力获取 F2、F3、FN 键和值。