将单个日志行中的多个字段数据实例提取到多值字段中

Extract multiple instances of field data from a single log line into a multi-valued field

我希望从单个日志行中提取同一字段的多个实例。例如,假设我有以下日志记录:

Recipients: alice@somedomain.com bob@someotherdomain.com carl@carlsplace.org

我事先不知道会列出多少个电子邮件地址。

与此相关,在一些早期的工作中,我处理的日志记录如下所示:

Step=12305, Step=11006, Step=11001, Step=11018, Step=12304, Step=11522, Step=11806

在那种情况下,我利用了 kv{} 过滤器,它自动生成了一个漂亮的多值字段,如下所示:

"Step": [
      "12305",
      "11006",
      "11001",
      "11018",
      "12304",
      "11522",
      "11806"
    ],

我想得到与我的结果相同类型的多值字段,但不能简单地再次使用 kv,因为实际的日志行比我原来的例子更混乱。实际的日志行更像这样:

Recipients: Unwanted_text alice@somedomain.com other junk bob@someotherdomain.com some.hostname.net 1 carl@carlsplace.org even-more

我想要一个 grok 表达式,它可以捕获 N 个电子邮件地址 (%{EMAILADDRESS}),无论它们在日志行中的什么位置,并将它们放入一个多值字段中。有人可以建议怎么做吗?

谢谢,

克里斯

您可以像下面这样使用正则表达式,然后捕获字符串中的所有匹配项:

[\w\d_]*?@[\w]*?\.[\w]{2,3}\.?[\w]?

演示:https://regex101.com/r/kDUoi5/2

测试:

Recipients: Unwanted_text alice@somedomain.com other junk bob@someotherdomain.com some.hostname.net 1 carl@carlsplace.org even-more

匹配:

Match 1
Full match  26-46   `alice@somedomain.com`
Match 2
Full match  58-81   `bob@someotherdomain.com`
Match 3
Full match  102-121 `carl@carlsplace.org`
input{
    beats{
        port => #specify_your_port_here
    }
}

filter{
    mutate{
        gsub => [
            "message","([a-zA-Z][a-zA-Z0-9_.+-=:]+@\b(?:[0-9A-Za-z][0-9A-Za-z-]{0,62})(?:\.(?:[0-9A-Za-z][0-9A-Za-z-]{0,62}))*(\.?|\b))","email=" 
        ]
    }

    kv{
        source => "message"
    }
}

output{
    elasticsearch{
        host => "localhost:9200"
        index => "manual"
        document_type => "log"
    }
}

我测试了上面的配置文件,其中filebeat从文件中读取输入日志并将其发送到logstash。

解释:->

  1. 我使用 gsub 将输入 message 中所有出现的电子邮件地址替换为 email= 和捕获的电子邮件地址。

  2. 这里使用的正则表达式只是grok中用于电子邮件地址的正则表达式,我只是添加了一个捕获组以捕获电子邮件地址。

  3. 然后我用邮箱地址提取了邮箱地址。

例如:->

输入消息 ->

Recipients: Recipients: Unwanted_text alice@somedomain.com other junk bob@someotherdomain.com some.hostname.net 1 carl@carlsplace.org even-more

gsub 将输入消息转换为 :->

Recipients: Unwanted_text email=alice@somedomain.com other junk email=bob@someotherdomain.com some.hostname.net 1 email=carl@carlsplace.org even-more

然后 kv 过滤器创建一个数组 'email',其中包含所有电子邮件地址

"email": [
    "alice@somedomain.com",
    "bob@someotherdomain.com",
    "carl@carlsplace.org"
]