⠀人
/ ⁰⊖⁰ \ オカメインコエンジニアの五十嵐(@ganta0087)です。
本連載のなかでRails 3/4の環境を並行稼動させたことについては既にお話させていただきました。 この状態で今までどおりの監視をしていると、何か問題が発生したときにRails 4が原因なのかが切り分けづらくなってしまいます。そのため、次のようなことを追加で行うようにしました。
これによってRails 3のときとは異なる事象を発見したり、エラーの原因の調査に役立つことが期待できます。 実際にアプリケーションサーバーでRails 3のときよりも負荷の上がる事象が発生し、特定のコントローラーで問題が発生していることがすぐに特定できました。
今回はこれらの設定方法について紹介します。
Rails 3と4でエラーアラートの通知を分離
クラウドワークスではアプリケーションエラーの検知にRollbarを利用しており、検知時にはSlackへ通知されるように設定しています。
ここではRollbarでアラート通知を分離する方法を紹介します。
Rollbar Projectの分離
Slackへの通知時に条件指定して分離できるようにがんばるのではなく、単純にRollbarのプロジェクトをRails 4用として新たに作成することで分離しました。 Rollbarはプロジェクトごとにアクセストークンが異なるため、それを利用して区別することができます。
また、Rollbarの料金プランは月間イベント数上限によって定まり、プロジェクト数に制約はないためコストも変わりません。
とくに条件分岐を考えることなく、新たに生成されたアクセストークンをRails 4サーバー側に設定すれば対応完了です。
Rollbarプロジェクトの設定は基本的に元のRails 3用プロジェクトと同じものを設定すればよいです。 Slackへの通知文面だけ、Rails 4とわかるようにしておきます。
余談ですがクラウドワークスではRollbarの1次受けを当番制にしています。
スプレッドシートに設定した当番を毎朝自動で設定し、Rollbarのアラートが発生したときにBOTがSlackのメンションを飛ばすしくみを設けています。
このように設定しておけば、一目でRails 4側に問題が発生したのかがわかります。
そしてRails 4へ移行完了した際には特に設定を変更することなく、Rails 3用のRollbarプロジェクトを削除するだけで済みます。
Rails 3と4のパフォーマンスのメトリクスを比較
クラウドワークスではモニタリングサービスにDatadogを利用しています。 簡単にグラフ表示が行え、柔軟なしきい値設定によるアラート通知もできてとても便利です。
アプリケーションサーバーには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でグラフ化します。
DatadogのDashbordにはTemplate Variablesという機能があり、Tag Groupをパラメーター化しておくことができます。
具体的にはRAILS_ENV
やRailsのバージョン、リクエストメソッドをパラメーター化することで、ダッシュボードの表示を簡単に切り替えることができます。
ダッシュボード右上の設定から「Edit Template Variables」を選択すると設定することができます。
設定したパラメーターはグラフを作成するときのクエリーで次のように設定します。
また、Rails 4のアクセス比率を出して移行状況を見ることもできます。
気になるコントローラーやアクションをピンポイントでグラフ化することもできて便利です。
今回、Railsから取得した値に加え、Datadogエージェントがデフォルトで取得するサーバーリソースの状況もRails 3/4で一望できるようにしておきました。
おわりに
以上、RollbarとDatadogを具体例として紹介しましたが、他のサービスでも応用できると思います。 特にRailsのパフォーマンス通知についてはRails 4移行後も活用していますので、ご参考になれば幸いです。
We’re hiring!
クラウドソーシングのクラウドワークスでは、がんばらないようがんばるエンジニアを募集しています!