Logstash过滤和解析模具输出

时间:2017-02-15 16:29:44

标签: ruby regex elasticsearch logstash deis

环境

  • Ubuntu 16.04
  • Logstash 5.2.1
  • ElasticSearch 5.1

我已将Deis平台配置为将日志发送到我们的Logstack节点,没有任何问题。然而,我仍然是Ruby的新手,而Regexes并不是我的强项。

日志示例

2017-02-15T14:55:24UTC deis-logspout[1]: 2017/02/15 14:55:24 routing all to udp://x.x.x.x:xxxx\n

Logstash配置:

input {
    tcp {
        port => 5000
        type => syslog
        codec => plain
    }
    udp {
        port => 5000
        type => syslog
        codec => plain
    }
}

filter {
    json {
        source => "syslog_message"
    }
}

output {
    elasticsearch { hosts => ["foo.somehost"] }
}

Elasticsearch输出:

"@timestamp" => 2017-02-15T14:55:24.408Z,
"@version" => "1",
"host" => "x.x.x.x",
"message" => "2017-02-15T14:55:24UTC deis-logspout[1]: 2017/02/15 14:55:24 routing all to udp://x.x.x.x:xxxx\n",
"type" => "json"

期望的结果:

"@timestamp" => 2017-02-15T14:55:24.408Z,
"@version" => "1",
"host" => "x.x.x.x",
"type" => "json"
"container" => "deis-logspout"
"severity level" => "Info"
"message" => "routing all to udp://x.x.x.x:xxxx\n"

如何将信息中的信息提取到各自的字段中?

1 个答案:

答案 0 :(得分:0)

不幸的是,您对自己要做的事情的假设略有不同,但我们可以解决这个问题!

您为JSON创建了一个正则表达式,但您没有解析JSON。您只是在解析一个标记为bastardized syslog的日志(请参阅source中的syslogStreamer),但实际上并不是syslog格式(RFC 5424或3164)。 Logstash之后提供JSON输出。

让我们分解消息,消息成为您解析的源。关键是你必须从前到后解析消息。

<强>消息:

2017-02-15T14:55:24UTC deis-logspout[1]: 2017/02/15 14:55:24 routing all to udp://x.x.x.x:xxxx\n
  • 2017-02-15T14:55:24UTC:时间戳是一种常见的grok模式。这主要遵循 TIMESTAMP_ISO8601 但不完全。
  • deis-logspout[1]:这将是您的logsource,您可以将其命名为容器。您可以使用grok模式 URIHOST
  • routing all to udp://x.x.x.x:xxxx\n:由于大多数日志的消息都包含在消息的末尾,因此您可以使用grok模式 GREEDYDATA ,这相当于.*用正则表达式。
  • 2017/02/15 14:55:24:另一个时间戳(为什么?)与常见的grok模式不匹配。

使用grok过滤器,您可以将语法(从正则表达式抽象)映射到语义(您提取的值的名称)。例如%{URIHOST:container}

你会看到我对grok过滤器进行了一些黑客攻击,以使格式化工作。即使您不打算捕获结果,也有文本的匹配部分。如果您无法更改时间戳的格式以匹配标准,请创建自定义模式。

<强>配置:

input {
    tcp {
        port => 5000
        type => deis
    }
    udp {
        port => 5000
        type => deis
    }
}

filter {
    grok {
        match => { "message" => "%{TIMESTAMP_ISO8601:timestamp}(UTC|CST|EST|PST) %{URIHOST:container}\[%{NUMBER}\]: %{YEAR}/%{MONTHNUM}/%{MONTHDAY} %{TIME} %{GREEDYDATA:msg}" }
    }
}

output {
    elasticsearch { hosts => ["foo.somehost"] }
}

<强>输出:

{
    "container" => "deis-logspout",
    "msg" => "routing all to udp://x.x.x.x:xxxx",
    "@timestamp" => 2017-02-22T23:55:28.319Z,
    "port" => 62886,
    "@version" => "1",
    "host" => "10.0.2.2",
    "message" => "2017-02-15T14:55:24UTC deis-logspout[1]: 2017/02/15 14:55:24 routing all to udp://x.x.x.x:xxxx",
    "timestamp" => "2017-02-15T14:55:24"
    "type" => "deis"
}

你可以另外改变项目以删除@timestamp,@ host等,因为这些是由Logstash默认提供的。另一个建议是使用date filter将找到的任何时间戳转换为可用格式(更适合搜索)。

根据日志格式,您可能需要略微更改模式。我只有一个例子。这也保留了原始的完整消息,因为在Logstash中完成的任何字段操作都是破坏性的(它们用相同名称的字段覆盖值)。

资源: