背景
webサービスを運用してるんですが、ログをもっと有効活用しようぜ!って話になり、とりあえず手元でfluentd+elasticsearch+kibanaを使って環境を作ってみました。
アプリが入ったサーバには極力負荷をかけたくないので、パース作業は別のサーバで行いました。そのへんでいい感じにまとまってる情報が見つからなかったので、備忘録を兼ねてメモ。
サーバ構成
アプリケーションサーバ(今回はmac) -> fluentdを入れてログの送信だけやらせる。
VM(ubuntu14.04) -> fluentd, elasticsearch, kibanaを入れてログのパース〜蓄積〜表示まで。実運用では変わるだろうけどまあ練習ということで。
ハマった点・困った点
1. アプリケーションサーバからログをそのまま送信するのってどうやるんや
2. 正規表現苦手なんだけど
3. parserプラグインで型変換できねーじゃん(これしないと、kibanaで平均値とか出せない) -> parserプラグインでもtypes使えました。@repeatedlyさんご指摘ありがとうございました!
対応策は、下記の(*n)の部分
導入手順
アプリケーションサーバ側
fluentdの導入
fluentd -> http://www.fluentd.org/download
confを開く
sudo vi /etc/td-agent/td-agent.conf
tailプラグインの設定
<source> type tail path /var/log/hoge/access.* pos_file /var/log/hoge/access.log.pos tag td.access format none <- (*1) </source>
本来はformatに[apache2]とか任意の正規表現を書くんだけど、noneって書くとmessageっていう1つのキーにまとめてくれるんですって。素敵。
これでアプリケーションサーバにそこまで負荷かけなくてすみますね。
送信設定
<match td.access> type file path /var/log/td-agent/access type forward <server> host [受信するfluentdがのっかったサーバのIP] port 24224 </server> flush_interval 10s
今回はファイルとして残しつつ、受信側のfluentdまでforward。
portはデフォルトの24224をそのまま使いました。
flush_intervalは見たまんまだけど、どれくらいの頻度で送信するか。
どれくらいが適切かは分からんが、今回はローカルですぐ反応が欲しかったため10sで設定。
VM側の設定
fluentd, elasticsearch, kibanaの導入
fluentd -> http://www.fluentd.org/download
elasticsearch -> http://www.elasticsearch.org/overview/elkdownloads/
kibana -> http://www.elasticsearch.org/overview/elkdownloads/
kibanaは、昔はnginxと連携しないといけなかったみたいだけど、現在のはkibana単体で動作するようになってました。4からなのかな。
fluentdで受信設定
confを開いて、下記を追記
<source> type forward port 24224 </source>
パース
sudo /opt/td-agent/embedded/bin/fluent-gem install fluent-plugin-parser
でparserプラグインを導入。
<match td.access> type parser remove_prefix raw add_prefix parsed format /~~~/ <- (*2) time_format %a, %d %b %Y %H:%M:%S %z key_name message </match>
(*2): http://fluentular.herokuapp.com/ を参考にせこせこ頑張りました。地道に手元で頑張るよりはるかに効率良く書けました。
Tomohiro (Tomohiro TAIRA) · GitHubさんありがとうございます♡
だがしかし、ここで問題が!
typesオプションねーじゃん!!!
tailプラグインにはあるのになんでや。
と思ったら
typecasts · Issue #12 · tagomoris/fluent-plugin-parser · GitHub
動きはあるみたい。junて、、って思ったけどまあそのうち導入されるでしょう。
ということで、型変換のプラグインを別で使うことにしました。 <- (*3)
sudo /opt/td-agent/embedded/bin/fluent-gem install fluent-plugin-typecast
でtypecastプラグインを導入して、
<match parsed.td.access> type typecast item_types response-time:float,content-size:integer prefix casted </match>
こんな感じ。
前述したけど、数値型じゃないと最小、最大、平均など計算できないから、kibanaでpathごとのレスポンスタイムの平均見たいっす、ってのができない。 -> typesオプション使えました
elasticsearchに渡す
sudo /opt/td-agent/embedded/bin/fluent-gem install fluent-plugin-elasticsearch
でelasticsearchプラグインを導入。
が、必要なパッケージがなかったらしく、
sudo apt-get install libcurl3-dev
したらうまくいきました。
で、confに追記。
<match casted.parsed.td.access> type copy <store> index_name hoge type_name hoge type elasticsearch include_tag_key true tag_key @log_name host localhost port 9200 logstash_format true flush_interval 3s </store> <store> type file path /var/log/td-agent/access_log buffer_chunk_limit 1G </store> </match>
elasticsearchは同じサーバの9200で起動させてたので、こんな感じで設定。
あとはkibanaのdirで
./bin/kibana
叩いて起動して、5601ポートにアクセス!
書いてて思ったけど、elasticsearchとkibanaの連携何やったか全然覚えてません。まあいいか。
で、kibanaのグラフ的なところで、y-axisにaverage: response-time、x-axisにpathを設定すれば、めでたくpathごとのレスポンスタイムが表示されましたとさ。
めでたしめでたし。
他にもっとスマートなやり方あるで、みたいなのあればぜひ教えてくださいまし!