読者です 読者をやめる 読者になる 読者になる

クラウドワークス エンジニアブログ

日本最大級のクラウドソーシング「クラウドワークス」の開発の裏側をお届けするエンジニアブログ

Rails 4移行時のサービス監視について

Rails4移行

⠀人
/ ⁰⊖⁰ \ オカメインコエンジニアの五十嵐(@gantawitter)です。

本連載のなかでRails 3/4の環境を並行稼動させたことについては既にお話させていただきました。 この状態で今までどおりの監視をしていると、何か問題が発生したときにRails 4が原因なのかが切り分けづらくなってしまいます。そのため、次のようなことを追加で行うようにしました。

  • Rails 3と4でエラーアラートの通知を分離
  • Rails 3と4のパフォーマンスのメトリクスを比較

これによってRails 3のときとは異なる事象を発見したり、エラーの原因の調査に役立つことが期待できます。 実際にアプリケーションサーバーでRails 3のときよりも負荷の上がる事象が発生し、特定のコントローラーで問題が発生していることがすぐに特定できました。

今回はこれらの設定方法について紹介します。

f:id:ganta0087:20160714183514p:plain

Rails 3と4でエラーアラートの通知を分離

クラウドワークスではアプリケーションエラーの検知にRollbarを利用しており、検知時にはSlackへ通知されるように設定しています。

rollbar.com

ここではRollbarでアラート通知を分離する方法を紹介します。

Rollbar Projectの分離

Slackへの通知時に条件指定して分離できるようにがんばるのではなく、単純にRollbarのプロジェクトをRails 4用として新たに作成することで分離しました。 Rollbarはプロジェクトごとにアクセストークンが異なるため、それを利用して区別することができます。

また、Rollbarの料金プランは月間イベント数上限によって定まり、プロジェクト数に制約はないためコストも変わりません。

f:id:ganta0087:20160714160932p:plain

とくに条件分岐を考えることなく、新たに生成されたアクセストークンをRails 4サーバー側に設定すれば対応完了です。

Rollbarプロジェクトの設定は基本的に元のRails 3用プロジェクトと同じものを設定すればよいです。 Slackへの通知文面だけ、Rails 4とわかるようにしておきます。

f:id:ganta0087:20160714160621p:plain

余談ですがクラウドワークスではRollbarの1次受けを当番制にしています。
スプレッドシートに設定した当番を毎朝自動で設定し、Rollbarのアラートが発生したときにBOTがSlackのメンションを飛ばすしくみを設けています。

このように設定しておけば、一目でRails 4側に問題が発生したのかがわかります。
そしてRails 4へ移行完了した際には特に設定を変更することなく、Rails 3用のRollbarプロジェクトを削除するだけで済みます。

Rails 3と4のパフォーマンスのメトリクスを比較

クラウドワークスではモニタリングサービスにDatadogを利用しています。 簡単にグラフ表示が行え、柔軟なしきい値設定によるアラート通知もできてとても便利です。

www.datadoghq.com

アプリケーションサーバーにはDatadogエージェントをインストールしてあります。 Rubyからエージェントを利用したイベント送信はdogstatsd-rubyという公式のGemを用いています。 ここではこのGemを使ってRailsで取得できるパフォーマンス情報をDatadogに送信する方法を紹介します。

RailsアプリケーションからDatadogへ情報を送信

通常、Statsdというクラスを用いてイベントを送信しますが、送信データの文字列が長いとイベントが送信されない問題の対策や自前の加工を行うため、ラッパークラスを用意しています。

require 'statsd'

class DatadogClient
  def self.instance
    @instance ||= DatadogClient.new
  end

  def initialize(statsd: nil)
    @statsd = statsd || Statsd.new
  end
  
  ...(略)...
end

そしてinitializerでActiveSupport::Notificationsを利用してDatadogへのイベント送信を行います。ActiveSupport::Notificationsを用いることで出版-購読型モデルを容易に実現できます。

Datadogへのイベント送信はコントローラーのアクションの実行タイミングで行います。 アクションの実行の検知は、process_action.action_controllerという名前でRailsが用意しているのでこれを購読します。

イベントの送信方法としてここでは2つのパターンを使用しています。 incrementはイベントのたびにキーの値がインクリメントされていくもので、histogramはキーに対して値がイベントのたびに保存されていくものです。

ActiveSupport::Notifications.subscribe('process_action.action_controller') do |*args|
  key_prefix = "crowdworks.rails.performance"

  client = DatadogClient.instance
  event = ActiveSupport::Notifications::Event.new(*args)
  payload = event.payload

  # ["action:samplecontroller.index", "controller:samplecontroller", ...]
  # という形式でタグを生成
  tags = {
    action: "#{payload[:controller]}.#{payload[:action]}",
    controller: payload[:controller],
    format: (payload[:format] && payload[:format] != "*/*") ? payload[:format] : "all",
    method: payload[:method],
    status: payload[:status],
    rails_env: Rails.env,
    rails_version: Rails::VERSION::MAJOR
  }.map { |key, value| "#{key}:#{value}" }

  # リクエスト応答時間
  client.histogram("#{key_prefix}.request.total_duration", event.duration, { tags: tags })
  # クエリー実行時間
  client.histogram("#{key_prefix}.database.query.time", payload[:db_runtime], { tags: tags })
  # ビューのレンダリング時間
  client.histogram("#{key_prefix}.web.view.time", payload[:view_runtime], { tags: tags })
  # HTTPステータスコード毎のカウント
  client.increment("#{key_prefix}.request.status.#{payload[:status]}", { tags: tags })
end

他にも様々なケースの購読が可能です。詳しくはActive Support Instrumentation — Ruby on Rails Guidesを参照してみてください。

Datadogでグラフ化

Railsから送信した値を活用してDatadogでグラフ化します。

f:id:ganta0087:20160714165403p:plain

DatadogのDashbordにはTemplate Variablesという機能があり、Tag Groupをパラメーター化しておくことができます。 具体的にはRAILS_ENVやRailsのバージョン、リクエストメソッドをパラメーター化することで、ダッシュボードの表示を簡単に切り替えることができます。

f:id:ganta0087:20160714165414p:plain

ダッシュボード右上の設定から「Edit Template Variables」を選択すると設定することができます。

f:id:ganta0087:20160714165222p:plain f:id:ganta0087:20160714165246p:plain

設定したパラメーターはグラフを作成するときのクエリーで次のように設定します。

f:id:ganta0087:20160714184557p:plain

また、Rails 4のアクセス比率を出して移行状況を見ることもできます。

f:id:ganta0087:20160714165313p:plain

気になるコントローラーやアクションをピンポイントでグラフ化することもできて便利です。

今回、Railsから取得した値に加え、Datadogエージェントがデフォルトで取得するサーバーリソースの状況もRails 3/4で一望できるようにしておきました。

f:id:ganta0087:20160714165338p:plain

おわりに

以上、RollbarとDatadogを具体例として紹介しましたが、他のサービスでも応用できると思います。 特にRailsのパフォーマンス通知についてはRails 4移行後も活用していますので、ご参考になれば幸いです。

We're hiring!

クラウドソーシングのクラウドワークスでは、がんばらないようがんばるエンジニアを募集しています!

www.wantedly.com

© 2016 CrowdWorks, Inc., All rights reserved.