EmbulkでアクセスログをLogstash風に取り込む
トラブルシューティング時に、バッチ取り込みによるKibanaアクセスログ可視化を行う場合、ログの取り込みに掛かる時間は短い程嬉しい。
もちろん測定条件やチューニングにも依存すると思うが、手元のマシン*1においては、Logstash2.2を使うより、Embulk v0.8.5を使った方が早かった*2。
Logstashではgrokのおかげで、たとえばリクエストURLならrequestフィールドなど、フィールド名が固定化されるが、Embulkの場合、各人が自由にパースすると各々の項目に対して微妙に異なるフィールド名を付与し、チームでダッシュボードが共有しにくい。
Logstashの以下のコンフィグで読み込んだフィールドの構成と同じように、EmbulkでElasticsearchにデータをロードできないか考えたのでメモする。
input { stdin {} } filter { grok { match => { "message" => "%{COMMONAPACHELOG}" } } date { match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ] locale => "en" } mutate { convert => { "bytes" => "integer" } } } output { elasticsearch {} }
セットアップ
Embulkのインストール
curl --create-dirs -o ~/.embulk/bin/embulk -L "http://dl.embulk.org/embulk-latest.jar echo 'export PATH="$HOME/.embulk/bin:$PATH"' >> ~/.bashr source ~/.bashrc
Embulkプラグインのインストール
Logstashユーザにとって、特にembulk-parser-grokプラグインは嬉しい。Logstashを同じ感覚で、ログのパース条件を定義できる。
embulk gem install embulk-parser-grok embulk gem install embulk-filter-column embulk gem install embulk-output-elasticsearch
Embulkのコンフィグ
作業ディレクトリを適当な場所に作って、
mkdir ~/work cd ~/work vim httpd-embulk.yml
以下のようにEmbulkのコンフィグを作成。
in: type: file path_prefix: log/access_log parser: type: grok grok_pattern_files: - grok-patterns # grok_pattern: '%{COMBINEDAPACHELOG}' grok_pattern: '%{COMMONAPACHELOG}' timestamp_parser: SimpleDateFormat default_timezone: 'Japan' charset: UTF-8 newline: LF columns: - {name: COMMONAPACHELOG, type: string} - {name: clientip, type: string} - {name: ident, type: string} - {name: auth, type: string} - {name: timestamp, type: timestamp, format: '%d/%b/%Y:%T %z'} - {name: verb, type: string} - {name: request, type: string} - {name: httpversion, type: string} - {name: response, type: string} - {name: bytes, type: long} # - {name: referrer, type: string} # - {name: agent, type: string} filters: - type: column add_columns: - {name: "@timestamp", src: timestamp} - {name: "host", type: string, default: "localhost.localdomain"} - type: rename columns: COMMONAPACHELOG: message # COMBINEDAPACHELOG: message out: type: elasticsearch nodes: - {host: localhost, port: 9300} cluster_name: my-application index: logstash-1995 index_type: "access_log"
Apacheのアクセスログは、~/work/log/にaccess_logから始まるファイル名で格納する。COMBINED形式のログを読み込む時は、コメントアウトされた部分を外して、grok_pattern: '%{COMMONAPACHELOG}'をコメントアウトする。適当なアクセスログがない場合は、NASAのアクセスログが練習に便利。
localhost.localdomeinの部分は、取り込み対象のアクセスログを出力したマシンのホスト名になおす。
grokパターンはLogstashのgrokに含まれるgrok-patternsをそのまま持ってくる。
cp logstash-2.2.0/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-2.0.2/patterns/grok-patterns ~/work
インデックステンプレートの登録
Logstashでデータを取り込むと、termで集計しやすいようにrequest.rawなどの非アナライズフィールドが生成されるが、これはLogstashのElasticsearchプラグインがインデックステンプレートとしてrawフィールドを生成しているため。Embulkでも同様のフィールドを作るために、Logstashから持ってきて登録する。
cp logstash-2.2.0/vendor/bundle/jruby/1.9/gems/logstash-output-elasticsearch-2.4.1-java/lib/logstash/outputs/elasticsearch/elasticsearch-template.json ~/work curl -XPUT http://localhost:9200/_template/logstash -d @elasticsearch-template.json
Embulkで取り込み開始
embulk run httpd-embulk.yml
私の手元のマシンでは、NASAのログ(NASA_access_log_Jul95, 196MB, 1891714行)が7分程で取り込み完了。
ダッシュボードで可視化
gistにサンプルダッシュボードを張ってるので、このexport.jsonをKibanaのSettingsタブ -> Objects からimportボタンでアップロードする。
可視化したい時間帯を指定すると、以下のようにダッシュボードが表示される。
まとめ
grok.patternsとelasticsearch-template.jsonをLogstashから持ってくることにより、LogstashユーザでもEmbulkが扱いやすくなります。
Logstashを前提に色々ダッシュボードを作っていても、上記のようなやり方でEmbulkで取り込んだ時にもダッシュボードが流用できそうです。