【问题标题】:Fluentd Parsing流畅的解析
【发布时间】:2021-09-02 09:57:22
【问题描述】:

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

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

这会解析成这样:

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

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

EDIT1:嘿嘿!我会让这个更详细。我目前正在使用 fluentd 将日志拖尾到 Elasticsearch+Kibana。这是 fluentd 发送到 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
  • Elasticsearch 收到消息:

{"message":"frSMS:0:13995:#HTF4J::141:141:msg0210,00000000000000000,000000,000000,007232,00,#,F2:00000000000000000,F3:002000,F4:0602 :随机的 数字和字符,F7:.......等"}

这个日志只有消息键,所以我不能只使用整个消息字段来索引和创建仪表板。我想要实现的是只捕获有用的字段,如果它没有键,则将键添加到其中并使索引更容易。

  • 预期输出:
{"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", “来源”:“toSMS”, “状态”:“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 等无用字段。 其他日志具有有用的值和键(日期、来源、msgcode、UID、F1、F2 字段),就像我在预期输出中展示的那样。无用字段不是静态的(它们可以是无,或具有更少|更多的数字和字符),因此它们会触发模式不匹配错误。

所以问题是:

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

PS:我将我写的正则表达式包装到 html sn-p 中,所以 捕获字段不会被删除

【问题讨论】:

  • 你试过什么正则表达式?也许这对你有帮助:(\w+):([^,]+)

标签: regex fluentd


【解决方案1】:

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

(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,直接用:(F\d+):(\d+)
【解决方案2】:

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

(?\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”,“状态码”:“msg0210”}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多