サービスメトリックは、特定のサーバとは直接紐付かないメトリックを可視化、監視するための仕組みです。例えば、あるウェブサービス全体のレスポンスタイムや、ステータスコードの分布を可視化し、レスポンスが遅くなったり、エラー率が上昇していないか確認できます。
このサービスメトリックはfluent-plugin-mackerelを利用することでfluentd経由で投稿できます。
また具体的なサービスメトリックへの投稿例を2つ紹介しています。
セットアップ
まずfluentdとfluent-plugin-mackerelをセットアップします。
$ gem install fluentd fluent-plugin-mackerel
サービスメトリックを投稿する
fluent-plugin-mackerelでサービスメトリックを投稿するための設定は以下のようになります。
<match ...>
@type mackerel
api_key <投稿先オーガニゼーションのAPIキー>
service <投稿先のサービス名>
remove_prefix
metrics_name http_status.${out_key}
out_keys <投稿するメトリックのキー。例: 2xx_count,3xx_count,4xx_count,5xx_count>
</match>
ホストのカスタムメトリックを投稿する
fluent-plugin-mackerelはホストのカスタムメトリックを投稿することもできます。その場合の設定は以下のようになります。
ホストIDを直接指定する場合
ホストID(用語集参照)を設定ファイルに書く場合は次のように設定します。
<match ...>
@type mackerel
api_key <投稿先オーガニゼーションのAPIキー>
hostid xyz
metrics_name http_status.${out_key}
out_keys <投稿するメトリックのキー。例: 2xx_count,3xx_count,4xx_count,5xx_count>
</match>
またホストIDが格納されているファイルを指定することもできます。mackerel-agentが動作しているホストから直接Mackerelに投稿する場合に便利です。
<match ...>
@type mackerel
api_key <投稿先オーガニゼーションのAPIキー>
hostid_path /var/lib/mackerel-agent/id
metrics_name http_status.${out_key}
out_keys <投稿するメトリックのキー。例: 2xx_count,3xx_count,4xx_count,5xx_count>
</match>
使用例
ここでは、サービスメトリックへの投稿例を2つ紹介します。
Nginxのアクセスログからステータスコードごとにリクエスト数をサービスメトリックに投稿する
ここでは次のようなステータスコード別にリクエスト数がカウントされたグラフを作ります。

まずNginxからアクセスログをLTSV形式で出力するようにします。
log_format ltsv "time:$time_local"
"\thost:$remote_addr"
"\tforwardedfor:$http_x_forwarded_for"
"\treq:$request"
"\tstatus:$status"
"\tsize:$body_bytes_sent"
"\treferer:$http_referer"
"\tua:$http_user_agent"
"\treqtime:$request_time"
"\tcache:$upstream_http_x_cache"
"\truntime:$upstream_http_x_runtime"
"\tvhost:$host";
access_log /var/log/nginx/access.log ltsv;
またステータスコードごとにリクエスト数を数えるためにfluent-plugin-datacounterを利用しますので、このプラグインをインストールします。
gem install fluent-plugin-datacounter
そしてNginxのアクセスログを読みこみ集計、Mackerelへの投稿を行うfluentdの設定を用意します。
# LTSV形式のログファイルを読み込む
<source>
@type tail
format ltsv
time_format %d/%b/%Y:%H:%M:%S %z
path /var/log/nginx/access.log
pos_file /var/log/nginx/access_log.pos
tag access.nginx
</source>
# fluent-plugin-datacounterでステータスコード別に集計する
<match access.nginx>
@type datacounter
count_interval 1m
count_key status
aggregate all
tag nginx.status
pattern1 2xx ^2\d\d$
pattern2 3xx ^3\d\d$
pattern3 4xx ^4\d\d$
pattern4 5xx ^5\d\d$
</match>
# fluent-plugin-mackerelによりサービスメトリックを投稿する
<match nginx.status.**>
@type mackerel
api_key <投稿先オーガニゼーションのAPIキー>
service <投稿先サービス名>
remove_prefix
metrics_name access_num.${out_key}
out_keys 2xx_count,3xx_count,4xx_count,5xx_count
</match>
これにより冒頭で示したようなグラフが描画されるようになります。またグラフの右上のギアマークからグラフの設定もできます。例えば、重ね合わせグラフから積み重ねグラフに変更できます。

AWSのCloudWatchのメトリックからELB関連のメトリックをサービスメトリックに投稿する
AWSのCloudWatchではロードバランサーのELBのリクエスト数(全体とステータスコード別)、応答時間といったメトリックデータを取得できます。それらをサービスメトリックとして投稿すると次のようなグラフが得られます。

AWSのCloudWatchからメトリックデータを読み込むためにfluent-plugin-cloudwatchを利用しますので、このプラグインをインストールします。
gem install fluent-plugin-cloudwatch
そしてCloudWatchからELBの情報を取り出し、Mackerelへの投稿を行うfluentdの設定を用意します。
# fluent-plugin-cloudwatchでCloudWatchからデータを取得
<source>
@type cloudwatch
tag cloudwatch-latency.elb01
aws_key_id <aws-key>
aws_sec_key <aws-sec-key>
cw_endpoint monitoring.ap-northeast-1.amazonaws.com
namespace AWS/ELB
metric_name Latency
dimensions_name LoadBalancerName
dimensions_value elb01
interval 60
period 60
delayed_start true
</source>
<source>
@type cloudwatch
tag cloudwatch-status.elb01
aws_key_id <aws-key>
aws_sec_key <aws-sec-key>
cw_endpoint monitoring.ap-northeast-1.amazonaws.com
namespace AWS/ELB
statistics Sum
metric_name HTTPCode_Backend_2XX,HTTPCode_Backend_3XX,HTTPCode_Backend_4XX,HTTPCode_Backend_5XX,RequestCount
dimensions_name LoadBalancerName
dimensions_value elb01
interval 60
period 60
delayed_start true
</source>
# Mackerelへサービスメトリックとして投稿する
<match cloudwatch-status.*>
@type copy
<store>
@type mackerel
api_key <api-key>
service <投稿先サービス名>
remove_prefix
metrics_name ${[1]}-status.${out_key}
out_keys HTTPCode_Backend_2XX,HTTPCode_Backend_3XX,HTTPCode_Backend_4XX,HTTPCode_Backend_5XX
</store>
<store>
@type mackerel
api_key <api-key>
service <投稿先サービス名>
remove_prefix
metrics_name ${[1]}-count.${out_key}
out_keys RequestCount
</store>
</match>
<match cloudwatch-latency.*>
@type mackerel
api_key <api-key>
service <投稿先サービス名>
remove_prefix
metrics_name ${[1]}-latency.${out_key}
out_keys Latency
</match>