Logstash:Grok filter 入门

有效分析和查询送入Elastic Stack的数据的能力取决于信息的可读性。 这意味着,当将非结构化数据摄取到系统中时,必须将其转换为结构化数据。

通常,这个至关重要的任务留给Logstash(尽管还有其他日志传送器可用,比如Fluentd)。 无论你定义什么数据源,都必须提取日志并执行一些魔力来美化它们,以确保在将它们输出到Elasticsearch之前正确地对其进行了解析。

Logstash中的数据操作是使用过滤器插件执行的。 本文重点介绍最流行和有用的过滤器插件之一-Logstash grok过滤器,该过滤器用于将非结构化数据解析为结构化数据。

在之前我的另外一篇文章“Elasticsearch:Elastic可观测性 - 数据结构化及处理”,我也介绍了如何使用ingest node来对数据进行加工和格式化。

 

什么是Grok?

最初的术语实际上是很新的-由罗伯特·A·海因莱因(Robert A. Heinlein)在他的1961年的《陌生的土地上的陌生人》一书中创造的–指的是理解某种东西,使人们真正沉浸其中。 这是grok语言和Logstash grok插件的合适名称,它们可以以一种格式修改信息并将其浸入另一种格式(特别是JSON)。 已经有数百种用于记录的Grok模式。

 

Grok是如何工作的?

简而言之,grok是一种将行与正则表达式匹配,将行的特定部分映射到专用字段中以及根据此映射执行操作的方法。

内置了超过200种Logstash模式,用于过滤AWS,Bacula,Bro,Linux-Syslog等中的单词,数字和日期等项目。 如果找不到所需的模式,则可以编写自己的自定义模式。 还有多个匹配模式的选项,可简化表达式的编写以捕获日志数据。

这是Logstash grok过滤器的基本语法格式:

%{PATTERN:FieldName}

这将匹配预定义的模式,并将其映射到特定的标识字段。 由于grok本质上是基于正则表达式的组合,因此你也可以创建自己的基于正则表达式的grok过滤器。 例如:

(?\d\d-\d\d-\d\d)

这将使22-22-22(或任何其他数字)的正则表达式与字段名称匹配。

 

一个Logstash Grok 例子

这个grok调试工具是开始构建grok过滤器的好方法:https://grokdebug.herokuapp.com/。你也可以在Kibana中找到grok的调试工具:

使用此工具,您可以粘贴日志消息并逐步构建grok模式,同时连续测试编译。 通常,我建议从%{GREEDYDATA:message}模式开始,然后逐步添加越来越多的模式。

在上面的示例中,我将从以下内容开始:

%{GREEDYDATA:message}

比如针对这条信息:

83.149.9.216 - - [17/May/2015:10:05:03 +0000] "GET /presentations/logstash-monitorama-2013/images/kibana-search.png HTTP/1.1" 200 203023 "http://semicomplete.com/presentations/logstash-monitorama-2013/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.77 Safari/537.36"

我们可以看到整个信息都赋予给message了。

我们再接着尝试如下的例子:

%{IPORHOST:clientip} - - \[%{HTTPDATE:timestamp}\] %{GREEDYDATA:message}

在上面,我们可以看到clientip, message,及timestamp。

 

常见的例子

以下是一些示例,可帮助你熟悉如何构造grok过滤器:

Syslog

用Grok解析syslog消息是新用户更普遍的需求之一。 syslog还有几种不同的日志格式,因此请牢记编写自己的自定义grok模式。 这是常见系统日志解析的一个示例:

May  4 00:10:36 liuxg xpcproxy[69746]: libcoreservices: _dirhelper_userdir: 557: bootstrap_look_up returned (ipc/send) invalid destination port

在Logstash中,我们应该使用如下的grok filter:

grok {
   match => { 
    "message" => "%{SYSLOGTIMESTAMP:syslog_timestamp}
    %{SYSLOGHOST:syslog_hostname}
    %{DATA:syslog_program}(?:\[%{POSINT:syslog_pid}\])?:
    %{GREEDYDATA:syslog_message}" 
  }
}

Apache access logs

80.135.37.131 - - [11/Sep/2019:23:56:45 +0000] "GET /item/giftcards/4852 HTTP/1.1" 200 91 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:9.0.1) Gecko/20100101 Firefox/9.0.1"

grok  {
      match => { "message" => "%{COMBINEDAPACHELOG}" }
}

Elasticsearch

[2017-09-10T12:07:26,683][WARN ][index.indexing.slowlog.index] [GOgO9TD] [testindex-slowlogs/yNbyYk1ARSW_hd0YRh6J0A] took[142.3micros], took_millis[0], type[product], id[105], routing[] , source[{"price":9925,"name":"Nariko"}]

grok {
      match => ["message", "\[%{TIMESTAMP_ISO8601:timestamp}\]\[%{DATA:loglevel}%{SPACE}\]\[%{DATA:source}%{SPACE}\]%{SPACE}\[%{DATA:node}\]%{SPACE}\[%{DATA:index}\] %{NOTSPACE} \[%{DATA:updated-type}\]",
                "message", "\[%{TIMESTAMP_ISO8601:timestamp}\]\[%{DATA:loglevel}%{SPACE}\]\[%{DATA:source}%{SPACE}\]%{SPACE}\[%{DATA:node}\] (\[%{NOTSPACE:Index}\]\[%{NUMBER:shards}\])?%{GREEDYDATA}"
      ]
   }

上面有两种匹配的方法,只要其中的一种可以匹配就可以了。

 

总结

Logstash grok只是在将日志转发到Elasticsearch之前可以应用于你的日志的一种过滤器。 由于grok在测井管道中起着至关重要的作用,因此它也是最常用的过滤器之一。