Grok正则捕获秘籍:Logstash插件预定义及引用方法全解析

admin AI新闻 19

Grok 正则捕获

Grok属于Logstash最为关键的插件, 你能够于grok之内预先设定好被冠名正则表达式, 于之后(grok参数或者其他正则表达式当中)对其加以引用。

正则表达式语法

负责运维工作的工程师, 或多或少都对正则有一定程度的了解知晓。你能够于grok当中撰写符合标准规范的正则, 呈现形式如下这般:

\s+(?\d+(?:\.\d+)?)\s+

提示注意, 这样一种正则表达式的写法, 对于 Perl 程序员而言, 应该是相当熟悉的, 对于 Ruby 程序员来说, 同样也是如此的, 然而 Python 程序员, 或许会相对更习惯去写 (?Ppattern) 这种形式, 可是没办法, 那就去适应一下。

此刻, 为我们现有的那个配置文件, 增添首个过滤器区段的配置。此配置需添加之处, 乃在输入区段与输出区段之间(logstash 执行区段之时, 并不依赖于次序, 但是呢, 只为了自身看得便利些, 还是依照次序来书写吧):

input {stdin{}}
filter {
    grok {
        match => {
            "message" => "\s+(?\d+(?:\.\d+)?)\s+"
        }
    }
}
output {stdout{}}

开启 logstash 进程,接着输入"begin 123.456 end"开云app官方最新下载地址, 随后你会目睹类似于下面这般的输出:

{
         "message" => "begin 123.456 end",
        "@version" => "1",
      "@timestamp" => "2014-08-09T11:55:38.186Z",
            "host" => "raochenlindeMacBook-Air.local",
    "request_time" => "123.456"
}

令人感觉好看!然而, 对于数据类型似乎并非十分满意……request_time理应属于数值范畴, 而非字符串类型。

我们曾提到过, 稍后会去学习运用LogStash::Filters::Mutate来对字段值类型进行转换, 然而在grok当中, 实际上存在着自身的奇妙方法来达成这个功能!

Grok 表达式语法

Grok具备将预先定义好的grok表达式写入文件之中的支持功能, 官方所提供的预先定义的grok表达式的查看位置如下: https://github.com/logstash/logstash/tree/v1.4.2/patterns。

要留意, 于新版本的logstash当中, pattern目录已然为空, 最后的一个commit表明core patterns将会经由logstash - patterns - core gem予以提供, 这个目录可供使用者放置自定义的patterns。

下面是从官方文件中摘抄的最简单但是足够说明用法的示例:

USERNAME [a-zA-Z0-9._-]+
USER %{USERNAME}

一开头的这一行, 运用平常的正则表达式去界定一个 grok 表达式;紧接着的第二行, 凭借打印赋值样式, 借由先前定好的那个 grok 表达式来确定另一个 grok 表达式。

grok 表达式的打印复制格式的完整语法是下面这样的:

%{PATTERN_NAME:capture_name:data_type}

请注意啦, data_type当前仅仅支持下述两个值, 其中一个是int, 另一个是float。

所以我们可以改进我们的配置成下面这样:

filter {
    grok {
        match => {
            "message" => "%{WORD} %{NUMBER:request_time:float} %{WORD}"
        }
    }
}

重新运行进程然后可以得到如下结果:

{
         "message" => "begin 123.456 end",
        "@version" => "1",
      "@timestamp" => "2014-08-09T12:23:36.634Z",
            "host" => "raochenlindeMacBook-Air.local",
    "request_time" => 123.456
}

这次 request_time 变成数值类型了。

最佳实践

在实际进行运用的过程当中, 我们是需要去处理种类繁多、各式各样的日志文件的, 若果你全部都是在配置文件里各自分别写下一行属于自己的表达式, 那么就会变得完全没有办法进行管理了。所以呢, 我们所给出的建议便是得把所有的grok表达式统一集中写入到一个特定的地方, 之后再用filter/grok的patterns_dir选项将这个地方明确指出来。

要是你将标名为 “message” 内的全部信息都解析到各异的字段之中, 那么数据实际上就等同于重复保存了两份。故而你能够运用 remove_field 参数去删除掉 message 字段, 或者借助 overwrite 参数对默认的 message 字段加以重写, 仅留存最为关键的部分。

重写参数的示例如下:

filter {
    grok {
        patterns_dir => "/path/to/your/own/patterns"
        match => {
            "message" => "%{SYSLOGBASE} %{DATA:message}"
        }
        overwrite => ["message"]
    }
}

小贴士多行匹配

跟 codec/multiline 一块儿搭配使用之际, 得留意一个问题, grok 正则跟普通正则相同, 默认情形下是不支持匹配回车换行的, 恰似您需要 =~ //m 那般, 也得单独去指定, 具体的写法是在表达式起始位置添加上 (?m) 标记, 像下面这样:

match => {
    "message" => "(?m)\s+(?\d+(?:\.\d+)?)\s+"
}

多项选择

有时, 我们会遇到一种情形。什么情形? 就是一个日志存在多种可能格式的状况。在这种时候, 要是想把它写成单一正则的话, 就会变得比较困难。不然, 如果全都用 | 隔开的话, 又会显得比较丑陋。就在这个时候, logstash 的语法给我们提供了一个很有趣的解决方式。

不管是在文档里, 还是在其他相关说明处, 都有明确指出, logstash 里的 filters 文件夹下的 grok 插件, 其 match 参数, 所应当接受的, 是一个 Hash 值。不过呢, 由于在早期的 logstash 定义的语法当中, Hash 值同样也是采用了 这样的写法来进行书写的, 因而实际上, 在现在这个阶段, 把 Array 值传递给 match 参数的话, 同样在逻辑上是完全不存在问题的。所以, 基于这样的情况, 在我们当前所处的这个这里, 实际上是完全能够传递多个正则表达式, 以此来针对同一个字段进行匹配的:

match => [
    "message", "(?\d+(?:\.\d+)?)",
    "message", "%{SYSLOGBASE} %{DATA:message}",
    "message", "(?m)%{WORD}"
]

logstash 是会依照这个定义次序逐个尝试匹配的, 一直到匹配成功才停止。尽管其效果与用 |进行分割来写一个很大的正则是相同的,然而它的可阅读性却是提升了许多。

最后的这一点开云手机入口app下载开云app官方入口网站,同时这也是最为关键的那一点开云app在线入口,开云真人官方下载, 我以强烈的态度提议, 每一个人都应该去运用 Grok Debugger 来对自身的 grok 表达式实施调试。

标签: Grok Logstash 正则表达式 配置文件 调试工具

发布评论 0条评论)

还木有评论哦,快来抢沙发吧~