Logstash:Mutate过滤器不起作用

时间:2016-09-19 20:44:52

标签: elasticsearch logstash

我有以下过滤器

filter {
    grok {
    break_on_match => false
        match => { 'message' => '\[(?<log_time>\d{0,2}\/\d{0,2}\/\d{2} \d{2}:\d{2}:\d{2}:\d{3} [A-Z]{3})\]%{SPACE}%{BASE16NUM}%{SPACE}%{WORD:system_stat}%{GREEDYDATA}\]%{SPACE}%{LOGLEVEL}%{SPACE}(?<log_method>[a-zA-Z\.]+)%{SPACE}-%{SPACE}%{GREEDYDATA:log_message}%{SPACE}@%{SPACE}%{IP:app_host}:%{INT:app_port};%{SPACE}%{GREEDYDATA}Host:%{IPORHOST:host_name}:%{POSINT:host_port}' }
    match => { 'message' => '\[(?<log_time>\d{0,2}\/\d{0,2}\/\d{2} \d{2}:\d{2}:\d{2}:\d{3} [A-Z]{3})\]'}
    }
    kv{
      field_split => "\n;"
      value_split => "=:" 
      trimkey => "<>\[\],;\n"
      trim => "<>\[\],;\n"
    }
    date{
    match => [ "log_time","MM/dd/YY HH:mm:ss:SSS z" ]
    target => "log_time"
    locale => "en"
    }

    mutate {

      convert => { 
              "line_number" => "integer" 
              "app_port" => "integer" 
              "host_port" => "integer" 
              "et" => "integer" 

      }

      #remove_field => [ "message" ]

    }

    mutate {

    rename => {

              "et" => "execution_time"
              "URI" => "uri"
              "Method" => "method"

      }
    }

}

我可以从grok和kv过滤器中获得结果,但是mutate过滤器都不起作用。是因为kv过滤器吗?

编辑:目的

我的问题是我的日志包含异构日志记录。例如

[9/13/16 15:01:18:301 EDT] 89798797 SystemErr                                                     jbhsdbhbdv [vjnwnvurnuvuv] INFO djsbbdyebycbe - Filter.doFilter(..) took 0 ms.

[9/13/16 15:01:18:302 EDT] 4353453443 SystemErr                                                    sdgegrebrb [dbebtrntn] INFO sverbrebtnnrb - [SECURITY AUDIT] Received request from: "null" @ wrvrbtbtbtf:000222; Headers=Host:vervreertherg:1111
Connection:keep-alive
User-Agent:Mozilla/5.0
Accept:text/css,*/*;q=0.1
Referer:https:kokokfuwnvuwnev/ikvdwninirnv/inwengi
Accept-Encoding:gzip
Accept-Language:en-US,en;q=0.8
; Body=; Method=GET; URI=dasd/wgomnwiregnm/iwenviewn; et=10ms; SC=200

所有我关心的是捕获每个记录开头的时间戳和其他几个字段(如果它们存在)。我想要MethodetHostloglevelURI。如果这些字段不存在,我仍然希望捕获loglevel并记录message的事件。

建议使用相同的logstash进程捕获此类事件吗?我应该运行两个logstash进程吗?问题是我不会事先知道日志的结构,除了我想要捕获的几个字段。

多行配置

path => ["path to log"]
start_position => "beginning" 
ignore_older => 0 
sincedb_path => "/dev/null"
codec => multiline {
pattern => "^\[\d{0,2}\/\d{0,2}\/\d{2} \d{2}:\d{2}:\d{2}:\d{3} [A-Z]{3}\]"
negate => "true"
what => "previous"

1 个答案:

答案 0 :(得分:1)

可能是因为在初始grok期间没有创建某些字段(line_number,et,URI,Method)。例如,我看到您定义了“log_method”,但在mutate-&gt;重命名中,您可以参考“Method”。是否在输入块中应用了json编解码器或其他内容来添加这些额外的字段?

如果您发布样本日志,我可以使用您的过滤器测试它们并为您提供更多帮助。 :)

修改: 我看到你发送的日志有多行。你在输入上使用多线过滤器吗?你也可以分享你的输入块吗?

您绝对不需要运行两个Logstash进程。一个Logstash可以处理多种日志格式。您可以使用条件,尝试/捕获,或通过添加“?”将字段标记为可选字段后。

更多编辑: 我得到的输出暗示你的mutate过滤器有效:

"execution_time" => 10,
"uri" => "dasd/wgomnwiregnm/iwenviewn",
"method" => "GET"

我将trimkey => "<>\[\],;\n"更改为trimkey => "<>\[\],;( )?\n"后。我注意到那些字段(et,Method)的前缀是空格。

注意:我正在使用以下多行过滤器进行测试,如果你的不同会影响结果。如果有帮助,请告诉我。

codec => multiline {
  pattern => "\n"
  negate => true
  what => previous
}