grok语句中的if语句

6
我正在创建一个logstash grok过滤器,以从备份服务器中提取事件,并希望能够测试字段是否符合模式,如果匹配模式,则进一步处理该字段并提取其他信息。
为此,我在grok语句本身中嵌入了一个if语句。这将导致测试失败,出现“Error: Expected one of #, =>”的错误提示。
以下是过滤器语句:
filter {
    grok {
        patterns_dir => "./patterns"
        # NetWorker logfiles have some unusual fields that include undocumented engineering codes and what not
        # time is in 12h format (ugh) so custom patterns need to be used.
        match => [ "message", "%{NUMBER:engcode1} %{DATESTAMP_12H:timestamp}  %{NUMBER:engcode2} %{NUMBER:engcode3} %{NUMBER:engcode4} %{NUMBER:ppid} %{NUMBER:pid} %{NUMBER:engcode5} %{WORD:processhost} %{WORD:processname} %{GREEDYDATA:daemon_message}" ]
        # attempt to find completed savesets and pull that info from the daemon_message field
        if [daemon_message] =~ /done\ saving\ to\ pool/  { 
            grok {
                match => [ "daemon_message", "%{WORD:savehost}\:%{WORD:saveset} done saving to pool \'%{WORD:pool}\' \(%{WORD:volume}\) %{WORD:saveset_size}" ]
            }
        }
    }
    date {
        # This is requred to set the time from the logline to the timestamp and not have it create it's own.
        # Note the use of the trailing 'a' to denote AM or PM. 
        match => ["timestamp", "MM/dd/yyyy HH:mm:ss a"]
    } 
}

这个代码块出现了以下错误:

$ /opt/logstash/bin/logstash -f ./networker_daemonlog.conf --configtest
Error: Expected one of #, => at line 12, column 12 (byte 929) after # Basic dumb simple networker daemon log grok filter for the NetWorker daemon.log 
# no smarts to this and not really pulling any useful info from the files (yet)
filter {
    grok {
... lines deleted ...
        # attempt to find completed savesets and pull that info from the daemon_message field
        if 

我刚接触logstash,意识到在grok语句中使用条件可能不可行,但我更喜欢用这种方式进行条件处理,而不是添加额外的match行,因为这样可以保留daemon_message字段供其他用途,同时提取出我想要的数据。
注:完全删除if语句允许configtest通过并使过滤器解析日志。
提前感谢您的帮助...
1个回答

17

条件语句放在过滤器之外,因此类似这样的语句:

if [field] == "value" {
     grok {
          ...
     }
]

应该是正确的。在您的情况下,先执行第一个 grok,然后再测试运行第二个,即:

grok {
    match => [ "message", "%{NUMBER:engcode1} %{DATESTAMP_12H:timestamp}  %{NUMBER:engcode2} %{NUMBER:engcode3} %{NUMBER:engcode4} %{NUMBER:ppid} %{NUMBER:pid} %{NUMBER:engcode5} %{WORD:processhost} %{WORD:processname} %{GREEDYDATA:daemon_message}" ]
}
if [daemon_message] =~ /done\ saving\ to\ pool/  {
    grok {
        match => [ "daemon_message", "%{WORD:savehost}\:%{WORD:saveset} done saving to pool \'%{WORD:pool}\' \(%{WORD:volume}\) %{WORD:saveset_size}" ]
    }  
}

这实际上是针对匹配的记录运行两个正则表达式。由于 grok 仅在正则表达式匹配时才会创建字段,因此您可以这样做:

grok {
    match => [ "message", "%{NUMBER:engcode1} %{DATESTAMP_12H:timestamp}  %{NUMBER:engcode2} %{NUMBER:engcode3} %{NUMBER:engcode4} %{NUMBER:ppid} %{NUMBER:pid} %{NUMBER:engcode5} %{WORD:processhost} %{WORD:processname} %{GREEDYDATA:daemon_message}" ]
}
grok {
    match => [ "daemon_message", "%{WORD:savehost}\:%{WORD:saveset} done saving to pool \'%{WORD:pool}\' \(%{WORD:volume}\) %{WORD:saveset_size}" ]
}

要衡量实际日志文件的性能,因为这将运行较少的正则表达式,但第二个更复杂。

如果你真的想疯狂,你可以在一个grok{}中完成所有这些操作,使用break_on_match功能。


好的,我担心这一点。我希望能够在填充新字段时拆分daemon_message字段,但似乎超出了logstash软件的范围...谢谢。 - michaelcoyote
以上示例是从您的输入中创建新字段;您还需要什么? - Alain Collins
啊,抱歉,我误解了。是的,这正是我想要的。再次感谢。 - michaelcoyote
这些条件语句有文档记录吗? - Elzo Valugi
3
@ElzoValugi,他们不断地移动文档位置,但当前链接是https://www.elastic.co/guide/en/logstash/current/event-dependent-configuration.html#conditionals。 - Alain Collins
@AlainCollins,您能否编辑答案并添加此链接? - JR ibkr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接