Logstashのgrok内のmatchのパターンについて


#1

初めて投稿します。

《環境》

  • Elasticsearch, Logstash, Kibana, Beats(Filebeat)のバージョン:5.0.2
  • ELKスタックをサーバA(CentOS6.2)、FilebeatをサーバB(CentOS6.7)にインストール

《状況》

サーバA上のWebのメールフォームからメールを送信し、その際にto,from,cc等の情報をテキストにログ(独自フォーマット)として吐き出します。 このログをFilebeatからサーバBのLogstashに投げて加工し、Elasticsearchに蓄積させている状態です。

《やりたいこと》

このメールフォームではccを0~3つまで設定して送信できるようになっているのですが、このccをそれぞれElasticsearchにフィールドに登録させたいと考えています(Kibanaでどの宛先が多いのか、などの情報を見たいため)。 この動作をさせるためには、Logstashのgrok、matchの条件をどのように記述すれば良いのでしょうか?(あるいは、他の方法があるか) 現状では下記のように条件を記述しています。
    grok {
      match => { "message" => [
        "%{TIMESTAMP_ISO8601:timestamp}, TO=\<%{NOTSPACE:to}\>, FROM=\<%{NOTSPACE:from}\>, CC=\<\>, SUBJECT:%{GREEDYDATA:subject}",
        "%{TIMESTAMP_ISO8601:timestamp}, TO=\<%{NOTSPACE:to}\>, FROM=\<%{NOTSPACE:from}\>, CC=\<%{NOTSPACE:cc}\>, SUBJECT:%{GREEDYDATA:subject}",
        "%{TIMESTAMP_ISO8601:timestamp}, TO=\<%{NOTSPACE:to}\>, FROM=\<%{NOTSPACE:from}\>, CC=\<%{NOTSPACE:cc}\>, CC2=\<%{NOTSPACE:cc2}\>, SUBJECT:%{GREEDYDATA:subject}"
      ] }
    }
しかし、このパターンですとccの中にcc2などの情報も一緒に入ってきてしまいます(例えば、 CC=<hoge@example.com>, CC2=<fuga@example.com> という行だと、 cc:hoge@example.com, cc2:fuga@example.com という形で入ってきてほしいのですが、cc:hoge@example.com>, CC2=<fuga@example.com> という一続きの文字列で入ってしまう)。 logstash/grok-patterns at v1.4.2 · elastic/logstash · GitHubのパターンを参照すると、少なくともNOTSPACEはスペースで区切られそうな気がするのですが…。 メールアドレスを厳密に正規表現で扱おうとするのはかなり無理があるという話は聞いたことがあるので、厳密にはやろうとは考えていないのですが、このような状況ではどのようにパターンを記述すれば良いのか、ご教授頂けると助かります。

以上、よろしくお願いします。


#2

"%{TIMESTAMP_ISO8601:timestamp}, TO=\<%{NOTSPACE:to}\>, FROM=\<%{NOTSPACE:from}\>, CC=\<%{NOTSPACE:cc}?\>(, CC2=\<%{NOTSPACE:cc2}?\>)?, SUBJECT:%{GREEDYDATA:subject}"

こんな感じでどうでしょうか。
CC2 のパース自体を (pattern)? で0回マッチで無視する。


(tsgkdt) #3

logstashのgrokフィルターに注目してみると、記載されているfilterの書式を使っても、手元の環境で再現しませんでした。
入力している文字が、実は期待しているフォーマットでない可能性があるのでは。
logstashのgrokの問題ではないように見えました。

  • logstash:5.0.2

検証に使用したconfは以下の通りです。

input { stdin { } }
filter {
   grok {
      match => { "message" => [
        "%{TIMESTAMP_ISO8601:timestamp}, TO=\<%{NOTSPACE:to}\>, FROM=\<%{NOTSPACE:from}\>, CC=\<\>, SUBJECT:%{GREE
DYDATA:subject}",
        "%{TIMESTAMP_ISO8601:timestamp}, TO=\<%{NOTSPACE:to}\>, FROM=\<%{NOTSPACE:from}\>, CC=\<%{NOTSPACE:cc}\>, 
SUBJECT:%{GREEDYDATA:subject}",
        "%{TIMESTAMP_ISO8601:timestamp}, TO=\<%{NOTSPACE:to}\>, FROM=\<%{NOTSPACE:from}\>, CC=\<%{NOTSPACE:cc}\>, 
CC2=\<%{NOTSPACE:cc2}\>, SUBJECT:%{GREEDYDATA:subject}"
      ] }
    }
}
output {
  stdout { codec => rubydebug }
}

入力文字列: 2016-12-14T00:00:00, TO=abc@a.com, FROM=ddd@d.com, CC=hoge@example.com, CC2=fuga@example.com, SUBJECT:aiueo

としたとき、成功しているように見えます。

{
            "cc" => "hoge@example.com",
    "@timestamp" => 2016-12-14T01:04:09.863Z,
           "cc2" => "fuga@example.com",
       "subject" => "aiueo",
      "@version" => "1",
          "host" => "99120e6bd606",
          "from" => "ddd@d.com",
            "to" => "abc@a.com",
       "message" => "2016-12-14T00:00:00, TO=<abc@a.com>, FROM=<ddd@d.com>, CC=<hoge@example.com>, CC2=<fuga@example.com>, SUBJECT:aiueo",
          "tags" => [],
     "timestamp" => "2016-12-14T00:00:00"
}

入力文字列: 2016-12-14T00:00:00, TO=abc@a.com, FROM=ddd@d.com, CC=hoge@example.com,CC2=fuga@example.com, SUBJECT:aiueo
CCとCC2の間に空白がないと、指摘されたようなCCにCC2の分も含まれてしまう

{
            "cc" => "hoge@example.com>,CC2=<fuga@example.com",
    "@timestamp" => 2016-12-14T01:08:45.160Z,
       "subject" => "aiueo",
      "@version" => "1",
          "host" => "99120e6bd606",
          "from" => "ddd@d.com",
            "to" => "abc@a.com",
       "message" => "2016-12-14T00:00:00, TO=<abc@a.com>, FROM=<ddd@d.com>, CC=<hoge@example.com>,CC2=<fuga@example.com>, SUBJECT:aiueo",
          "tags" => [],
     "timestamp" => "2016-12-14T00:00:00"
}


#4

nxhack様

ご返答有り難うございます。
こんなにすっきりとした記述ができるのですね。ご教示頂いた記述を基にして

"%{TIMESTAMP_ISO8601:timestamp}, TO=\<%{NOTSPACE:to}?\>, FROM=\<%{NOTSPACE:from}\>, CC=\<%{NOTSPACE:cc}*>(, CC2=\<%{NOTSPACE:cc2}?\>)?, SUBJECT:%{GREEDYDATA:subject}"

としてパターンの記述を簡略化することができました。ありがとうございます。


tsgkdt様

ご返答有り難うございます。
色々見直した結果、ご指摘の通りプログラム側のバグでCC、CC2の文字列を結合する際にスペースが抜けてしまっていました。
フィールドに入ってこないのでプログラムとlogstash.conf双方を弄っている最中に消してしまっていたようです。
お騒がせしました。そして、ご指摘により気付くことができました。ありがとうございます。

原因が判明し、当初の意図した通りにフィールドに入ってくるようになったので、これを以て解決とさせて頂きます。
改めて、ご返答頂いたお二方に感謝の意を申し上げます。ありがとうございました。


(system) #5

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.