Mackerel と fluentd でサービスの状態を可視化する

この記事ははてなエンジニアアドベントカレンダー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 に送信する

f:id:hatz48:20141208160908j:plain

※ 上の図には集約用の中間 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 を使ってログを集計します

それぞれ一分間ごとにログ集計するための設定例を紹介します。レスポンスタイムは平均値の他に 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_percentageaccess_rate.2xx_percentage... となります。 これで、以下のようなグラフが出力されます

f:id:hatz48:20141208190026p:plain

※ 上のグラフは access_rate.* の Graph Type を stack に変更しています。Graph Type の変更はグラフ右上の設定ボタンから出来ます

おわり

fluentd を使ってMackerel にサービスメトリックを送信する方法をご紹介しました。 「推測するな、計測せよ」とあるように、サービスの性能改善には計測がかかせません。Mackerel でアプリケーションの性能を可視化して、より品質の高いサービス開発に役立ててみてはいかがでしょうか。(また、サービスメトリックの監視機能が現在開発中です!急なパフォーマンスの劣化などをアラートすることも出来るようになります!)

はてなのサービスの品質を高めたいエンジニアはこちらからどうぞ!

採用情報 - 株式会社はてな