この記事ははてなエンジニアアドベントカレンダー2014の9日目です。
こんにちは、はてなアプリケーションエンジニアの id:hatz48 です。
今日は Mackerel と fluentd を利用してサービスの状態(レスポンスタイムやステータスコードのレートなど)を可視化するために、自分のチームで行っている方法を紹介します。
Mackerel とは
Mackerel ははてなで提供しているサーバー管理ツールです。 mackerel-agent をインストールするだけで簡単にホストの基本的な情報(loadavg, cpu使用率など)を可視化・監視することが出来ます。基本的な情報の他にも、plugin を使うことでカスタムメトリックを取ったり、APIを使うことでホストに紐づかないメトリックも収集することができます。plugin, API の詳細はこちらからどうぞ
今回はこの API と fluentd を用いて、アプリケーション全体のレスポンスタイムと、ステータスコードのレートをグラフにしてみます。
※ fluentd は OSS のデータコレクターです。この記事では fluentd の知識はあるものとして話を進めます
Mackerel を使う準備
※ Mackerel のアカウントはお持ちでなければ今すぐ サインアップ! GitHub のアカウントでもサインアップ出来ます
サービスメトリックを送信するのに必要な準備は、「API Key の取得」「サービスの作成」の二つだけです。どちらも簡単で、API Key は organization のトップページから取得することが出来ます。サービスもサービスのトップページから「New Service」ボタンで作成することができます。
ここで取得した API Key とサービス名を、メトリック送信時に利用します
全体の構成
基本的な構成は、以下の通りです。
- Application サーバーに同居している fluentd で各ホストからアクセスログを拾う
- ログには各アクセスのレスポンスタイムと HTTP ステータスコードが記録されているものとする
- (割愛) fluentd(Aggregator)を通して、feeder にログを転送する
- 集計用の fluentd(Feeder) で集計をする
- Mackerel に送信する
※ 上の図には集約用の中間 fluentd サーバーが書いてありますが、今回は App -> Feeder と直接つないでいるとして説明します
fluentd で Application のログを拾い、集計用の fluentd に転送する
fluentd の in_tail プラグインでアクセスログを拾い、 out_forward プラグインで feeder に転送します。
このあたりは fluentd 一般に言える話で、Mackerel はあまり関係無いですが設定の一例を紹介します
<source>
type tail
format ltsv
time_format ...
path /path/to/access.log
tag hoge.access.log
pos_file /tmp/access.log.pos
</source>
<match **>
type forward
...
<server>
name feeder
host {feeder のip}
port 24224
</server>
</match>
ログフォーマットは ltsv、 tag には hoge.access.log を指定しました。ログにはとりあえず ステータスコード(status) とレスポンスタイム(taken) が入っているものとします
time:06/Dec/2014:16:39:13 +0000 host:**** req:GET /hoge HTTP/1.1 status:200 taken:0.033
ログを集計する
以下の fluentd plugin を使ってログを集計します
- ステータスコード : fluent-plugin-datacounter
- レスポンスタイム : fluent-plugin-numeric-monitor
それぞれ一分間ごとにログ集計するための設定例を紹介します。レスポンスタイムは平均値の他に 90%ile と 99%ile も出してみましょう
<source>
type forward
port 24224
bind 0.0.0.0
</source>
<match **>
type copy
<store>
type datacounter
count_interval 60s
count_key status
output_per_tag yes
pattern1 2xx ^2\\d\\d$
pattern2 3xx ^3\\d\\d$
pattern3 4xx ^4\\d\\d$
pattern4 5xx ^5\\d\\d$
tag_prefix status
</store>
<store>
type numeric_monitor
count_interval 60s
monitor_key taken
output_per_tag yes
percentiles 90,99
tag_prefix taken
</store>
</match>
これで、 status.hoge.access.log というタグでステータスコードのレート、 taken.hoge.accedd.log というタグでレスポンスタイムの平均、90%ile、99%ile が出力されます
fluentd-plugin-mackerel を用いて Mackerel に送信する
冒頭に「Mackerel の API を使って」と書きましたが、 Mackerel に送信する fluentd plugin があるのでそれを使います。けっきょく最後まで fluentd の話になってしまいました。 fluent-plugin-mackerel の設定例を紹介します
<match status.**>
type mackerel
flush_interval 60s
api_key {API_Key} # API Key を記入
out_keys 2xx_percentage,3xx_percentage,4xx_percentage,5xx_percentage
service {サービス名} # サービス名を記入
metrics_name access_rate.${out_key}
</match>
<match taken.**>
type mackerel
flush_interval 60s
api_key {API Key} # API Key を記入
out_keys num,avg,percentile_90,percentile_99
service {サービス名} # サービス名を記入
metrics_name access_latency.${out_key}
</match>
上で取得した API Key とサービス名を記入してください。これで指定したサービスにメトリックが送信されるようになります。
ステータスコードのメトリック名は access_rate.2xx_percentage、access_rate.2xx_percentage... となります。
これで、以下のようなグラフが出力されます
※ 上のグラフは access_rate.* の Graph Type を stack に変更しています。Graph Type の変更はグラフ右上の設定ボタンから出来ます
おわり
fluentd を使ってMackerel にサービスメトリックを送信する方法をご紹介しました。 「推測するな、計測せよ」とあるように、サービスの性能改善には計測がかかせません。Mackerel でアプリケーションの性能を可視化して、より品質の高いサービス開発に役立ててみてはいかがでしょうか。(また、サービスメトリックの監視機能が現在開発中です!急なパフォーマンスの劣化などをアラートすることも出来るようになります!)
はてなのサービスの品質を高めたいエンジニアはこちらからどうぞ!