こんにちわ! Suです!
最近、開発現場でLogstashのfilterを設定する機会があって、初めてGrokを触ったので、調べたGrokについて簡単にまとめました。
この記事がお役に立てれば幸いです!
Grokって何?
Grokは複雑なテキストデータのパターンマッチングを行うための強力なツールであり、ログの解析やデータ抽出など、さまざまな用途で活用されてるようです。
なんのこっちゃ分からん!w という方に向けてざっくり説明すると
こんな感じのテキスト(これはApacheというソフトのログです)を
127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326
こんな感じに構造化するためのツールです。これをElasticSearchに保存して、Kibanaで検索したりします。
{
"client_ip": "127.0.0.1",
"ident": "-",
"user": "frank",
"timestamp": "10/Oct/2000:13:55:36 -0700",
"request": "GET /apache_pb.gif HTTP/1.0",
"httpversion": "1.0",
"response": "200",
"bytes": "2326"
}
Grok使わなくても正規表現使えばいいじゃない
おっしゃる通りですが、今まで正規表現で頑張っていた解析を、簡単な表現で構造化できるのはすごいことだと思います。
試しに先ほどのこのログを正規表現で表現すると以下になります。
(?<client_ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}) - (?<ident>\S+) (?<user>\S+) \[(?<timestamp>[^\]]+)\] "(?<request>[^"]+)" (?<response>\d{3}) (?<bytes>\d+)
どうでしょう?難しいですよね?
正規表現マスターであれば苦労はないかもしれませんが、それでも「1つ間違えれば正しく動作しない」ことになります。
Grokは複雑なフォーマットを簡単に表現できる素晴らしいツールだとわかります。
Grokのフォーマットってどこ見ればいいの?
ツールによってどのGrokパターンを持っているか分からないので、LogstashのGrokパターンだけおいておきます。
https://github.com/logstash-plugins/logstash-patterns-core/blob/main/patterns/legacy/grok-patterns
LogstashでGrokを使うフィルターの内容教えて
サンプルを以下に書きます。Logstashのフィルターは、「input」、「filter」、「output」と3つの構造に分かれています。
詳細は割愛しますが
- inputは、データがどこから入ってくるかを指定する(標準入力ならstdin、Kafkaのならkafkaという設定になる)
- filterは、今回まとめているgrokを使ったフィルターで構造化したり、不要なデータを除外したりなど行う
- outputは、filterの結果をどのように出力するかを指定する(標準出力ならstdout、ElasticSearchに出力もできます)
という感じです。
#sample.conf
input {
stdin {}
}
filter {
grok {
match => { "message" => "%{COMMONAPACHELOG}" }
}
}
output {
stdout { codec => rubydebug }
}
この”%{COMMONAPACHELOG}”の部分がGrokのパターンです。
他のパターンを使いたい場合は、この部分を変えましょう。
LogstashでGrokを使うフィルターを実際に試したい
Logstashが既に入っているサーバで実行する場合
Logstashが既に入っているサーバで実行する場合は、以下のコマンドでフィルターのテストを行いましょう。
cat sample.log | sudo /usr/share/logstash/bin/logstash -f sample.conf
- sample.logは、フィルターを通して構造化したいログファイルのサンプルを入れます
- sample.confは、先ほど説明したinput, filter, outputを定義したファイルを使います
Logstashが既に入っているサーバがない場合(ローカルで実行)
Logstashが入っていない場合は、Dockerを使ってローカルでLogstashサーバを用意して試しましょう。
まずは、DockerのLogstashイメージをダウンロード。バージョンはお好きなバージョンを入れてください(今回は8.6.0を使ってます)
docker pull docker.elastic.co/logstash/logstash:8.6.0
次に、ダウンロードしたDockerのイメージIDを確認します
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker.elastic.co/logstash/logstash 8.6.0 d5c34d1abe55 14 months ago 747MB
Dockerを起動しつつ、Dockerに入ります
docker run -it --rm docker.elastic.co/logstash/logstash:8.6.0 /bin/bash
vi コマンドで、ログのサンプルファイルを作成します
vi sample.log
vi コマンドがDocker内にない場合は、ローカルでsample.logファイルを作り、ローカルからDockerにコピーしましょう
# docker psコマンドでimage IDを確認します
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0abcfeea57a3 docker.elastic.co/logstash/logstash:8.6.0 "/usr/local/bin/dock…" 8 minutes ago Up 8 minutes 5044/tcp, 9600/tcp compassionate_goodall
# docker cpコマンドで docker内にsample.logをコピーします
docker cp sample.log 0abcfeea57a3:/usr/share/logstash/sample.log
vi コマンドで、フィルターのサンプルファイルを作成します
vi sample.conf
viコマンドがDocker内にない場合は、sample.logと同様にローカルでsample.confファイルを作り、ローカルからDockerにコピーしましょう
catコマンドで、sample.logの内容を標準出力し、logstashコマンドに渡します。使うフィルターファイルを指定しつつ実行することで、Logstashのフィルターを試すことができます。
cat sample.log | /usr/share/logstash/bin/logstash -f sample.conf
こんな感じの結果が出ます。
{
"timestamp" => "10/Oct/2000:13:55:36 -0700",
"url" => {
"original" => "/apache_pb.gif"
},
"message" => "127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] \"GET /apache_pb.gif HTTP/1.0\" 200 2326",
"@timestamp" => 2024-03-29T03:44:07.097214358Z,
"event" => {
"original" => "127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] \"GET /apache_pb.gif HTTP/1.0\" 200 2326"
},
"http" => {
"request" => {
"method" => "GET"
},
"version" => "1.0",
"response" => {
"body" => {
"bytes" => 2326
},
"status_code" => 200
}
},
"user" => {
"name" => "frank"
},
"host" => {
"hostname" => "d92b7409dc20"
},
"@version" => "1",
"source" => {
"address" => "127.0.0.1"
}
}
うまくいかない場合は、以下の様にLogstashを起動した状態で、直接sample.logの内容をコピペしてもOKです。(stdinでLogstashが待機してくれているので、コピペでも受け付けてくれます)
/usr/share/logstash/bin/logstash -f sample.conf
環境つくるの面倒だなぁ、Grokフィルタ試せるサイトないの?
英語ですが、Grok Constructorというサービスがあります。こちらでは、入力とGrokフィルターを書くことで、どのような構造化がされるか試すことができます。
https://grokconstructor.appspot.com/do/match
最後に
いかがでしたでしょうか?
Grokの設定は最初は分かりづらいかもしれません。しかし、小さなサンプルから始めることで色んなパターンを試したりするとっかかりになると思います。
ELKスタックなどLogstashを触る機会が増えている昨今、Grokを学び、よりよいエンジニアライフを過ごしましょう!
では、またお会いしましょう!