nginxのログからステータスコード毎のリクエスト数をMackerelに投稿する方法

# 概要
やりたいことは表題の通りです。
Mackerelの公式ドキュメントでも紹介されているようにfluentdを経由してリクエスト数をサービスメトリックに投稿します。
https://mackerel.io/ja/docs/entry/advanced/fluentd#example-nginx
おおよそのフローは公式にある通りですが、細かい手順でハマりどころがあるので具体的な方法についての説明をします。

# 主なフロー
1. nginxのログをLTSV形式にする
2. fluentdをインストールする
3. fluentdのpluginをインストールする
4. fluentdの設定をする

# 実践
## 1. nginxのログをLTSV形式にする
LTSV形式とは
http://ltsv.org/
 http://d.hatena.ne.jp/naoya/20130209/1360381374
>  Labeled Tab-Separated Values という、テキストのフォーマットの仕様です。CSV や TSV や JSON そのほかと同じ、テキストデータのフォーマット名。主にログ、特に httpd のアクセスログなどに適用すると便利です。
> LTSV ってタブ区切りで値に名前を付けただけのもの?
はい、そうです。

nginxのログをその名の通りラベル付きのタブで分割されたフォーマットに変更します。
nginxのログをLTSV形式にするためには、configファイルで[log_format](http://nginx.org/en/docs/http/ngx_http_log_module.html)ディレクティブを用いてタブ区切りのフォーマットを指定します。

```/etc/nginx/nginx.conf
log_format ltsv "time:$time_local\t"
                "host:$remote_addr\t"
                "forwardedfor:$http_x_forwarded_for\t"
                "req:$request\t"
                "status:$status\t"
                "size:$body_bytes_sent\t"
                "referer:$http_referer\t"
                "ua:$http_user_agent\t"
                "reqtime:$request_time\t"
                "cache:$upstream_http_x_cache\t"
                "runtime:$upstream_http_x_runtime\t"
                "vhost:$host";

access_log  /var/log/nginx/access.log  ltsv;
```

## 2. fluentdをインストールする
fluentdとは
http://www.fluentd.org/
> Fluentd is an open source data collector for unified logging layer.

今回はUbuntu 16.04のAmazon EC2にfluentdをインストールします。
[Installing Fluentd Using deb Package](http://docs.fluentd.org/articles/install-by-deb)

```bash
# For Ubuntu 16.04 Xenial
$ curl -L https://toolbelt.treasuredata.com/sh/install-ubuntu-xenial-td-agent2.sh | sh
```

環境が異なる場合は、適切なインストール方法を選択してください。
[Step1: Installing Fluentd](http://docs.fluentd.org/articles/quickstart#step1-installing-fluentd)

上記のコマンドで **td-agent** がインストールされ、td-agentコマンドが使えるようになります。("td"は多分"treasure data"の略)
`td-agent start` でdaemonが起動します。

```bash
$ /etc/init.d/td-agent start
$ /etc/init.d/td-agent stop
$ /etc/init.d/td-agent restart
$ /etc/init.d/td-agent status
```

td-agentはデフォルトで`/var/log/td-agent/td-agent.log`にログを出力します。
以下のコマンドで正常にログが出力されるかどうか動作確認します。

```bash
$ curl -X POST -d 'json={"json":"message"}' http://localhost:8888/debug.test
```

## 3. fluentdのpluginをインストールする
Mackerelにサービスメトリックを投稿するための[fluent-plugin-mackerel](https://github.com/mackerelio/fluent-plugin-mackerel)と、ステータスコード毎にリクエストを集計するための[fluent-plugin-datacounter](https://github.com/tagomoris/fluent-plugin-datacounter)をインストールします。
[Plugin Management | fluentd.org](http://docs.fluentd.org/articles/plugin-management)
td-agentを利用している場合は **td-agent-gem**コマンドでインストールします。
td-agent-gemコマンドはgemコマンドをラップしているので、gemコマンドと同様のコマンドが使えます。

```bash
$ sudo td-agent-gem install fluent-plugin-mackerel fluent-plugin-datacounter --no-rdoc --no-ri
$ td-agent-gem list
```

## 4. fluentdの設定をする
`td-agent.conf`に以下の設定を追記します。

```/etc/td-agent/td-agent.conf
# 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>
```

td-agentを再起動して、Mackerelのサービスメトリックにグラフが表示されれば完了です。