Logstashを使用したlambdaのログのパースについて

logstashで、AWSのlambdaのログをパースしたいです。

サンプル

START RequestId: cce511d2-861d-4b2c-8813-e6f09b6567bb Version: $LATEST                                                                                            
END RequestId: cce511d2-861d-4b2c-8813-e6f09b6567bb                                                                                                               
REPORT RequestId: cce511d2-861d-4b2c-8813-e6f09b6567bb Duration: 1.88 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 43 MB Init Duration: 130.17 ms
START RequestId: 44014e8f-ac46-4994-a93b-edd300cae5c8 Version: $LATEST                                                                   
END RequestId: 44014e8f-ac46-4994-a93b-edd300cae5c8                                                                                      
REPORT RequestId: 44014e8f-ac46-4994-a93b-edd300cae5c8 Duration: 1.60 ms Billed Duration: 2 ms Memory Size: 128 MB Max Memory Used: 43 MB

「REPORT」から始まる行のみを対象とし、「Init Duration~」は、ある場合とない場合が混在します。
上記のログを例にすると、以下のように分割したいです。grokを使用しているのですが上手くいっておらず、ご教示頂けないでしょうか。

フィールド名 値
requestid cce511d2-861d-4b2c-8813-e6f09b6567bb
duration 1.88
billed_duration 2
memory_size 128
max_memory_used 43
init_duration 130.17(存在する場合のみ)

grok定義を、以下のようにすると、init_durationがある場合は良いのですが、無い場合にエラーになってしまいます。また、先頭が「REPORT」で始まる行以外は無視したいです。
REPORT RequestId: %{DATA:request_id} Duration: %{NUMBER:duration} ms Billed Duration: %{NUMBER:billed_duration} ms Memory Size: %{NUMBER:memory_size} MB Max Memory Used: %{NUMBER:max_memory_used} MB Init Duration: %{NUMBER:init_duration} ms

以下を参考としております

こんにちわ。

Logstashについてはあまり詳しくないので、正しいアプローチかどうかわかりませんが以下のようにすると動作確認ができました。

1.REPORTで始まる行以外は無視する ⇒ ifを使い、REPORTで始まらないものはDropする
2.Init Durationがあるものとないものがある ⇒ Grokのmatchに複数のパターンを記載しておく

使用したLogstashの設定

コンソールに提示されたログのテキストを貼り付けて、コンソールに出力された内容を確認します。

input {
  stdin {
      codec => "line"
  }
}
filter {
  # 先頭行REPORT以外は無視する
  if [message] !~ /^REPORT/ {
    drop {}
  }

  grok {
    "match" => { "message" => [
      "REPORT RequestId: %{DATA:request_id} Duration: %{NUMBER:duration} ms Billed Duration: %{NUMBER:billed_duration} ms Memory Size: %{NUMBER:memory_size} MB Max Memory Used: %{NUMBER:max_memory_used} MB Init Duration: %{NUMBER:init_duration} ms",
      "REPORT RequestId: %{DATA:request_id} Duration: %{NUMBER:duration} ms Billed Duration: %{NUMBER:billed_duration} ms Memory Size: %{NUMBER:memory_size} MB Max Memory Used: %{NUMBER:max_memory_used} MB"
    ]}
  }
}
output {
  stdout {}
}

Grokのmatchでは、Init Durationがあるパターンの方を先に書いています。
行にInit Durationがある場合には、このパターンが使用され、なければ次の行で指定しているInit Durationがないパターンの方が使用されるようです。

出力の確認

確認した環境

  • Logstash 7.13.2 (公式Dockerイメージを利用)

いかがでしょうか?