HerokuをMackerelで監視する

Herokuはウェブアプリケーションを動かすためのPaaSです。 ここでは、Mackerelを利用してHeroku上のアプリケーションを監視する方法を紹介します。

Dynoを監視する

Herokuは自動でホスト(Dyno)が増減しますので、Auto Scaling環境で使うの設定をHerokuに合わせて利用します。

Herokuでアプリケーションを起動するための Procfile では、シェルスクリプト start.sh を起動するようにし、start.sh の中で各種設定を行います。

start.sh<API-KEY> , <SERVICE>, <ROLE> は適切に書き換えてください。 <RUN-APP>はアプリケーションの起動コマンド(例えば、node.jsであれば node index.js など)に書き換えてください。

  • Procfile
web: ./start.sh
  • start.sh
#!/bin/sh
set -x
# install mackerel-agent
mackerel_agent=/app/mackerel-agent/mackerel-agent
mackerel_agent_conf=/app/mackerel-agent/mackerel-agent.conf

cd /app/ && \
  curl -O http://file.mackerel.io/agent/tgz/mackerel-agent-latest.tar.gz && \
  tar xvfz mackerel-agent-latest.tar.gz
sh << SCRIPT
cat > $mackerel_agent_conf <<'EOF';
pidfile = "/app/mackerel-agent/mackerel-agent.pid"
root = "/app/mackerel-agent"
apikey = "<API-KEY>"
roles = [ "<SERVICE>:<ROLE>" ]
EOF
SCRIPT
trap "$mackerel_agent retire -conf $mackerel_agent_conf -force" TERM
$mackerel_agent -conf $mackerel_agent_conf -v &

<RUN-APP>

サービスメトリックを投稿する

HerokuではLog Drainsを使うことでアクセスログを含む各種ログを取得することができます。

https://cdn-ak.f.st-hatena.com/images/fotolife/m/mackerelio/20151022/20151022145204_original.png

ここではHeroku上のRailsのログからレスポンスタイムとエラーレートを計算し、Mackerelのサービスメトリックに投稿する方法を紹介します。

HerokuでRailsを動かす方法は公式ガイドを参照してください。

RailsでJSON形式のログを出力する

logrageを利用します。

# Gemfile
gem 'lograge'
# config/application.rb
module Testapp
  class Application < Rails::Application
    ...
    config.log_level = :info
    config.lograge.enabled = true
    config.lograge.formatter = Lograge::Formatters::Json.new
    ...
  end
end

rsyslogを設定する

rsyslogとfluentdを動かすホストを用意します。まずはrsyslogの設定を行います。5140番ポートでHerokuからのログを受けつけますので、ファイアウォールの設定で5140番ポートを空けるようにしてください。

# /etc/rsyslog.conf
$ModLoad imtcp
$InputTCPServerRun 5140

Heroku Drainsを設定する

<IPADDR> はrsyslogとfluentdを動かすホストのIPアドレスに置換してください。

# heroku drains:add syslog://<IPADDR>:5140
Successfully added drain syslog://<IPADDR>:5140

fluentdを設定する

まずはtd-agentをインストールします。公式ガイドに従ってください。

次に必要なプラグインをインストールします。

# /usr/sbin/td-agent-gem install fluent-plugin-mackerel fluent-plugin-numeric-monitor fluent-plugin-datacounter

td-agentの設定ファイルに以下を追記します。 <API-KEY> はAPIキーを、 <APP> は投稿先のサービス名に置換してください。 後半のfluent-plugin-mackerelの利用方法の詳細はfluentdでサービスメトリックを投稿するをあわせて参照してください。

# /etc/td-agent/td-agent.conf
<source>
  type tail
  path /var/log/heroku
  pos_file /var/log/td-agent/posfile_heroku.pos
  format /^(?<time>[^ ]*\s+[^ ]*\s+[^ ]*) (?<host>[^ ]*) (?<ident>[a-zA-Z0-9_\/\.\-]*)(?:\[(?<pid>[a-zA-Z0-9\.]+)\])? *(?<message>.*)$/
  time_format %b %d %H:%M:%S
  tag heroku.syslog
</source>

<match heroku.syslog>
  type rewrite_tag_filter
  rewriterule1 message ^{" raw.heroku.access_log
</match>

<match raw.heroku.access_log>
  type parser
  remove_prefix raw
  key_name message
  format json
  reserve_data true
</match>

<match heroku.access_log>
  type copy
  <store>
    type numeric_monitor
    count_interval 60s
    monitor_key duration
    output_per_tag yes
    percentiles 90,99
    tag_prefix aggregated
    input_tag_remove_prefix heroku
  </store>
  <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$
    outcast_unmatched yes
    tag_prefix status_aggregated
    input_tag_remove_prefix heroku
  </store>
</match>

<match status_aggregated.access_log>
  type copy
  <store>
    type rewrite_tag_filter
    capitalize_regex_backreference yes
    rewriterule1 2xx_count      .+ status_count.access_log
    rewriterule2 3xx_count      .+ status_count.access_log
    rewriterule3 4xx_count      .+ status_count.access_log
    rewriterule4 5xx_count      .+ status_count.access_log
  </store>
  <store>
    type rewrite_tag_filter
    capitalize_regex_backreference yes
    rewriterule3 4xx_percentage .+ error_status_percentage.access_log
    rewriterule4 5xx_percentage .+ error_status_percentage.access_log
  </store>
</match>

<match status_count.access_log>
  type mackerel
  flush_interval 60s
  api_key <API-KEY>
  out_keys 2xx_count,3xx_count,4xx_count,5xx_count
  remove_prefix
  service <APP>
  metrics_name access_num.${out_key}
</match>

<match aggregated.access_log>
  type mackerel
  flush_interval 60s
  api_key <API-KEY>
  out_keys avg,percentile_90,percentile_99
  remove_prefix
  service <APP>
  metrics_name access_latency.${out_key}
</match>

<match error_status_percentage.access_log>
  type mackerel
  flush_interval 60s
  api_key <API-KEY>
  out_keys 4xx_percentage,5xx_percentage
  remove_prefix
  service <APP>
  metrics_name error_access_rate.${out_key}
</match>

サービスメトリックの監視ルールを追加する

https://cdn-ak.f.st-hatena.com/images/fotolife/m/mackerelio/20151022/20151022145201_original.png

最後に設定したレスポンスタイムとエラーレートのサービスメトリックそれぞれに対して、監視ルールを追加しましょう。

具体的な方法は監視・通知を設定するCLIツール mkr を使うを参照してください。