OK Computer で Deep Health Check する
Leaner 開発チームの黒曜(@kokuyouwind)です。
Kaigi on Rails 2023 の参加登録が始まりましたね。私も現地参加するのでよろしくお願いします。
Deep Health Check パターン
Web サービスを運用する際、アクセスが正しく受け付けられるかを確認するためにヘルスチェック用のエンドポイントを用意するのは定番パターンです。
Leaner でも、元々はヘルスチェック用のエンドポイントを以下のように用意していました。
class HealthController < ActionController::API
def index
render json: { status: 'OK' }
end
end
コンテナ自体のヘルスチェックなど、 Rails サーバーが正常に動作しているか確認する目的であればこういった実装が適切です。
一方で「サービスが問題なく利用できるか」という観点では、「Web サーバーは応答しているがデータベースに繋がっていない」「メール送信サービスに繋がっていない」「非同期ジョブワーカーが動いておらずジョブが実行されていない」など、ミドルウェアや関連コンポーネントの状態も確認したくなってきます。
こうしたシステム全体の健全性をチェックするのが Deep Health Check パターンです。
Leaner でも APM からの外形監視のために Deep Health Check 用のエンドポイントを導入することにしました。
OK Computer gem
Rails で Deep Health Check を行うための gem はいくつかありますが、今回はOK Computer gemを導入しました。
デフォルトで用意されているチェック項目が豊富で、特に DelayedJob
のジョブ数チェックが用意されていたのが決め手です。
チェック項目の設定
公式 README を見れば大体書いてありますが、 config/initializers/okcomputer.rb
でチェック項目をカスタマイズできます。
現状は以下のようにしています。
# エンドポイントを `/health` 及び `/health/all` にする
# /health が Web サーバー自体の死活監視用、 /health/all が Deep Health Check 用のエンドポイントになる
OkComputer.mount_at = 'health'
# SMTP サーバーに接続できるかのチェック
OkComputer::Registry.register 'action_mailer', OkComputer::ActionMailerCheck.new
# データベースのマイグレーションが完了しているかのチェック
OkComputer::Registry.register 'database_migration', OkComputer::ActiveRecordMigrationsCheck.new
# Rails Cache が利用できるかのチェック
OkComputer::Registry.register 'cache', OkComputer::GenericCacheCheck.new
# DelayedJob のキューが溜まっていないかのチェック
# 優先度 0 の Job が 50 個以上溜まっていたらエラー
OkComputer::Registry.register 'job_queue', OkComputer::DelayedJobBackedUpCheck.new(0, 50)
# Ruby バージョンの表示
OkComputer::Registry.register 'ruby_version', OkComputer::RubyVersionCheck.new
この状態で /health/all
にアクセスすると、以下のようなレスポンスを返します。[1]
Default Collection
action_mailer: PASSED ActionMailer::Base check to xxxx:1025 successful (0.000s)
cache: PASSED Able to read and write via Null store (0.000s)
database: PASSED Schema version: xxxx (0.002s)
database_migration: PASSED NO pending migrations (0.003s)
default: PASSED Application is running (0.000s)
job_queue: PASSED Delayed Jobs with priority lower than '0' at reasonable level (0) (0.003s)
ruby_version: PASSED Ruby 3.2.2-p53 (0.000s)
ActionMailer が SMTP サーバーに接続できるかや DelayedJob のジョブ数など、各種サービスをチェックした上で全て PASSED
になっているのが確認できますね。
あとは APM から /health/all
のステータスチェックを定期的に行い、エラーになった場合はアラートを上げるようにすれば安心です。
利用できるチェック項目について
設定できるチェック用クラスは okcomputer/lib/ok_computer/built_in_checks/ から確認できる他、カスタムチェッククラスの実装も可能です。
個人的には DelayedJob のジョブ数チェックが便利だと感じます。この監視をどこでやるかが結構悩ましかったのですが、 Deep Health Check に組み込んでしまうことでヘルスチェックアラートに一元化できました[2]。
まとめ
OK Computer gem での Deep Health Check については他の方の記事も大いに参考にさせていただきました。
Zenn ではまだ OK Computer gem に関する記事がなさそうだったことと、 DelayedJobBackedUpCheck
を使った例があまりなさそうだったため、そのあたりでこの記事が誰かの役に立てば幸いです。
Discussion