0
0

バリデーションにおけるRailsログの理解とカスタムログの活用

Posted at

はじめに

Railsアプリケーションを開発している際に、デバッグやエラーの特定は日常的な作業です。Railsのログはデータベースのトランザクションやリクエスト処理の詳細を提供しますが、バリデーションエラーのようなアプリケーションレベルのイベントは標準のログには詳細が記録されないことがあります。この記事では、Railsのログがどのように機能しているかを解説し、カスタムログを活用してデバッグ情報を充実させる方法を紹介します。

Railsのログが出る場合と出ない場合

Railsのログが出る場合:

1. リクエストログ

これはHTTPリクエストを処理するたびに生成されます。リクエストメソッド、パス、完了ステータス、所要時間などが含まれます。

2. データベースクエリログ

ActiveRecordを通じてデータベースに発行される各クエリの詳細が記録されます。これにはSQL文とクエリの実行時間が含まれます。たとえば、以下のバリデーションにおけるエラーログなどがそれにあたります。

  def unique_future_reservation_per_customer_and_company
    return if date.blank? || customer_id.blank? || company_id.blank? || date < Date.today
    future_reservations = Reservation.where(customer_id: customer_id, company_id: company_id).where('date >= ?', Date.today)
    future_reservations = future_reservations.where(deleted_at: nil)
    future_reservations = future_reservations.where.not(id: id) unless new_record?
    if future_reservations.exists?
      errors.add(:base, "予約は1つしか作成できません")
    end
  end
  ↳ app/models/reservation.rb:36:in `unique_future_reservation_per_customer_and_company'
  TRANSACTION (0.8ms)  ROLLBACK
  ↳ app/controllers/reservations_controller.rb:104:in `toggle_approval'

3. エラーログ

システムのエラーや例外が発生した場合に生成されます。これにはエラーメッセージとスタックトレースが含まれることが多いです。

Railsのログが出ない場合:

4. モデルバリデーションエラー

モデルのバリデーションはデータベースレベルの処理ではなく、オブジェクトがデータベースに保存される前のメモリ内で処理されます。そのため、標準のログにはこれらの詳細は記録されません。たとえば、以下のバリデーションではログが出力されません。

  def date_cannot_be_in_the_past
    if date.present? && date < Date.today
      errors.add(:date, "は今日以降の日付を選択してください")
    end
  end

以下はログです。エラーが生じてロールバックしているが、エラーに関する情報が記載されていません。

 Customer Load (1.1ms)  SELECT "customers".* FROM "customers" WHERE "customers"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
  ↳ app/controllers/reservations_controller.rb:104:in `toggle_approval'
  TRANSACTION (0.6ms)  ROLLBACK
  ↳ app/controllers/reservations_controller.rb:104:in `toggle_approval'
Redirected to http://localhost:3000/reservations
Completed 302 Found in 27ms (ActiveRecord: 7.4ms | Allocations: 9009)

対策: カスタムログの実装

アプリケーションレベルの処理においてログを出力するにはカスタムログを設定する必要があります。アプリケーションの特定の処理でカスタムログを記録することで、デバッグが容易になり、運用時の問題解析が迅速に行えるようになります。例として、モデルバリデーションのカスタムログを追加する方法を示します:

class Reservation < ApplicationRecord
  validate :date_cannot_be_in_the_past

  def date_cannot_be_in_the_past
    if date.present? && date < Date.today
      Rails.logger.info "Validation Failed - Date cannot be in the past: #{date}"
      errors.add(:date, "は今日以降の日付を選択してください")
    end
  end
end

このコードは、Reservation モデルにカスタムバリデーションを追加し、バリデーションが失敗するたびにログに記録します。こうすることで、開発中はもちろん、本番環境での問題発生時にも、ログから迅速に情報を得ることができます。

ログレベルの管理

Railsでは、環境ごとにログレベルを設定することができます。例えば、開発環境ではdebugレベルで詳細な情報を出力し、本番環境ではinfoレベルに設定して情報量を制限することが一般的です。

# config/environments/production.rb
config.log_level = :info

まとめ

Railsのログは強力なデバッグと監視のツールですが、すべての情報が自動的に記録されるわけではありません。カスタムログを適切に実装することで、アプリケーションの挙動をより詳細に把握し、開発と運用の効率を大幅に向上させることができます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0