简体   繁体   English

配置文件,logstash ruby filter event.get(“message”).match() 错误

[英]Config file, logstash ruby filter event.get(“message”).match() Error

In the logstash config file I am trying to just get the XML data to parse.在 logstash 配置文件中,我试图获取要解析的 XML 数据。

This is my config file:这是我的配置文件:


input {
    file {
        path => "/home/elastic-stack/logstash-7.3.2/event-data/telmetry.log"
        start_position => "beginning"
        type => "sandbox-out"
        codec => multiline {
            pattern => "^</datastore-contents-xml>"
            negate => "true"
            what => "next"
    }

    }
    http { 
        host => "127.0.0.1"
        port => 8080
        type => "sandbox-out"
    }
}
filter {
    grok {
        match => { "message" => "\[%{USER:host_name} %{IP:ip_address} %{USER:session-id} %{NUMBER:session-id-num}\]"}
    }
    grok {
        match => { "message" => "\Subscription Id     \: %{BASE16NUM:subcription-id:int}"}
    }    
    grok {
        match => { "message" => "\Event time      \: %{TIMESTAMP_ISO8601:event-time}"}
    }
    grok {
        match => {"message" => "\<%{USERNAME:Statistic}\>"}
    }
    mutate {
        remove_field => ["headers", "host_name", "session-id","message"]
    }
    date {
        match => ["timestamp","dd/MMM/yyyy:HH:mm:ss Z"]
    }
    ruby { code => 'event.set("justXml", event.get("message").match(/.+(<datastore-contents-xml.*)/m)[1])' }
    xml {
        #remove_namespaces => "true"
        #not even the namspace option is working to access the http link
        source => "justXml"
        target => "xml-content"
        #force_array => "false"
        xpath => [
            "//*[name()='datastore-contents-xml']/*[name()='memory-statistics']/*[name()='memory-statistic'][1]/*[name()='name']/text()" , "name" ,
            "//*[name()='datastore-contents-xml']/*[name()='memory-statistics']/*[name()='memory-statistic'][1]/*[name()='total-memory']/text()" , "total-memory",
            "//*[name()='datastore-contents-xml']/*[name()='memory-statistics']/*[name()='memory-statistic'][1]/*[name()='used-memory']/text()" , "used-memory",
            "//*[name()='datastore-contents-xml']/*[name()='memory-statistics']/*[name()='memory-statistic'][1]/*[name()='free-memory']/text()" , "free-memory" ,
            "//*[name()='datastore-contents-xml']/*[name()='memory-statistics']/*[name()='memory-statistic'][1]/*[name()='lowest-memory']/text()" , "lowest-memory" ,
            "//*[name()='datastore-contents-xml']/*[name()='memory-statistics']/*[name()='memory-statistic'][1]/*[name()='highest-memory']/text()" , "highest-memory" 
        ]
        #logstash is not dectecting any of these xpaths in the config  
    }
    mutate {
        convert => {
            "total-memory" => "integer"
            "used-memory" => "integer"
            "free-memory" => "integer"
            "lowest-memory" => "integer"
            "highest-memory" => "integer"
            }
    }


}
output {
    stdout {
        codec => rubydebug
    }

    file {
        path => "%{type}_%{+dd_MM_yyyy}.log"
    }
}

Desired output:所需的 output:

{
        "ip_address" => "10.10.20.30",
    "subcription-id" => 2147483650,
        "event-time" => "2019-09-12 13:13:30.290000+00:00",
              "host" => "127.0.0.1",
         "Statistic" => "memory-statistic",
              "type" => "sandbox-out",
          "@version" => "1",
        "@timestamp" => 2019-09-26T10:03:00.620Z,
    "session-id-num" => "35"
        "yang-model" => "http://cisco.com/ns/yang/Cisco-IOS-XE-memory-oper"
              "name" => "Processor"
      "total-memory" => 2238677360
       "used-memory" => 340449924
       "free-memory" => 1898227436
      "lowest-usage" => 1897220640
     "highest-usage" => 1264110388
}

ERROR:错误:

[2019-09-27T09:18:55,622][ERROR][logstash.filters.ruby    ] Ruby exception occurred: undefined method `match' for nil:NilClass
/home/elastic-stack/logstash-7.3.2/vendor/bundle/jruby/2.5.0/gems/awesome_print-1.7.0/lib/awesome_print/formatters/base_formatter.rb:31: warning: constant ::Fixnum is deprecated
{
        "ip_address" => "10.10.20.30",
    "subcription-id" => 2147483650,
    "session-id-num" => "35",
              "tags" => [
        [0] "_rubyexception"
    ],
         "Statistic" => "memory-statistic",
        "event-time" => "2019-09-12 13:13:30.290000+00:00",
              "type" => "sandbox-out",
          "@version" => "1",
              "host" => "127.0.0.1",
        "@timestamp" => 2019-09-27T07:18:54.868Z

By the error I can already know that the problem is with the ruby filter but I do not know how to resolve it.通过该错误,我已经知道问题出在 ruby 过滤器上,但我不知道如何解决。

This data generate by Cisco Telemetry and I am trying to ingest it using Elastic Stack.此数据由 Cisco Telemetry 生成,我正在尝试使用 Elastic Stack 获取它。

The error seems to be that the event has no message field, so you cannot call match on a non existing thing.错误似乎是该事件没有message字段,因此您不能在不存在的事物上调用match I see you are calling match on the message field in this ruby code:我看到您在此 ruby 代码中的message字段上调用match

ruby { code => 'event.set("justXml", event.get("message").match(/.+(<datastore-contents-xml.*)/m)[1])' }

However you are removing the message field from the event a few lines earlier:但是,您要在前几行从事件中删除message字段:

mutate {
  remove_field => ["headers", "host_name", "session-id","message"]
}

Solution is to remove the message field only when you don't need it anymore, I would move the remove_field mutate to the end of the filter block.解决方案是仅在您不再需要它时删除消息字段,我会将 remove_field 变异移动到filter块的末尾。

One more suggestion if I may add.如果我可以添加,还有一个建议。 You have multiple grok filters running on the same, message field:您有多个 grok 过滤器在同一个消息字段上运行:

grok {
  match => { "message" => "\[%{USER:host_name} %{IP:ip_address} %{USER:session-id} %{NUMBER:session-id-num}\]"}
}
grok {
  match => { "message" => "\Subscription Id     \: %{BASE16NUM:subcription-id:int}"}
}    
grok {
  match => { "message" => "\Event time      \: %{TIMESTAMP_ISO8601:event-time}"}
}
grok {
  match => {"message" => "\<%{USERNAME:Statistic}\>"}
}

This can be simplified into this (you can check to theGrok filter docs :这可以简化为(您可以查看Grok 过滤器文档

grok {
  break_on_match => false,
  match => {
    "message" => [
      "\[%{USER:host_name} %{IP:ip_address} %{USER:session-id} %{NUMBER:session-id-num}\]",
      "\Subscription Id     \: %{BASE16NUM:subcription-id:int}",
      "\Event time      \: %{TIMESTAMP_ISO8601:event-time}",
      "\<%{USERNAME:Statistic}\>"
    ]
  }
}

This way you need only one instance of the grok filter, as it will go through the patterns in the list and because of break_on_match=>false it will not finish after the first successful match, but will make sure to extract all fields it can based on all the patterns in the list.这样,您只需要一个 grok 过滤器实例,因为它将通过列表中的模式 go 并且由于break_on_match=>false它不会在第一次成功匹配后完成,但会确保提取它可以基于的所有字段在列表中的所有模式上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM