Query Log Tagsにクエリ本文を渡せるように変更

rails/rails

query_log_tagsのコンテキストにSQL文字列が追加され、クエリの内容に応じた動的なタグ付けが可能になりました。これにより、SQLクエリの特性に基づいた詳細なデバッグ情報の付与が実現します。

背景

本番環境でSQLクエリがデータベースレプリカにヒットしない問題をデバッグする際、既存のバックトレース行だけでは情報が不足していました。ActiveSupport::Notifications.subscribe("sql.active_record")を使ったカスタムロジックでも解決可能ですが、設定ベースのアプローチの方がシンプルです。#56683は、クエリログタグの仕組みにSQL文字列を渡すことで、この課題を解決しています。

クエリの内容に応じて異なるデバッグ情報を付与したいというニーズは、レプリカ振り分けのデバッグ以外にも、クエリの複雑さやパフォーマンス特性の分析など、幅広いユースケースに応用できます。

技術的な変更

コンテキストへのSQL追加が主要な変更です。activerecord/lib/active_record/query_logs.rbcallメソッドが、SQL文字列をコンテキストに含めるよう修正されました。

変更前:

def call(sql, connection)
  comment = self.comment(connection)
  # ...
end

変更後:

def call(sql, connection)
  comment = self.comment(sql: sql, connection: connection)
  # ...
end

commentメソッドおよびuncached_commentメソッドのシグネチャも、単一のconnection引数からextra_contextハッシュに変更されています。これにより、:sqlキーでSQL文字列にアクセスできるようになりました。

使用例は以下の通りです。クエリの長さをタグとして記録する場合:

config.active_record.query_log_tags = [
  sql_length: ->(context) { context[:sql].length }
]

実行されるクエリには/*sql_length:8*/のような形式でタグが付与されます。

コンテキストキーの文書化も同時に行われました。activerecord/lib/active_record/query_logs.rbのモジュールコメントに、コンテキストに含まれる4つのキー(:controller:job:connection:sql)の説明が追加されています。

セキュリティへの配慮

SQL文字列の直接ログ出力に対する警告が文書に追加されました。

CHANGELOGとモジュールコメントの両方に、:sqlをタグとして直接使用することの危険性が明記されています。SQL文字列にはセンシティブなデータが含まれる可能性があり、フィルタリングなしでログに出力することは安全ではありません。

# 安全でない例
config.active_record.query_log_tags = [:sql]

# 安全な例
config.active_record.query_log_tags = [
  sql_length: ->(context) { context[:sql].length }
]

この警告は、新機能の提供と同時に誤用を防ぐための設計判断を示しています。SQL文字列そのものではなく、その派生情報(長さ、パターンマッチの結果など)を使用することを推奨しています。

まとめ

本PRは、クエリログタグのコンテキストにSQL文字列を追加することで、クエリの特性に基づいた動的なタグ付けを可能にしました。既存の設定インターフェースを拡張する形での実装により、ActiveSupport::Notificationsを使ったカスタムロジックよりもシンプルな解決策を提供しています。同時に、SQL文字列の直接ログ出力に対する明確な警告を含めることで、セキュリティリスクの軽減も図られています。

記事メタデータ

Generated by:
Claude Sonnet 4.5 for DiffDaily

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
リトライ後承認
Review Count:
3回 (改善を経て承認)
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文(総論)→背景・技術詳細(各論)→まとめ(結論)という3部構成が明確に適用されており、非常に分かりやすいです。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライト、PR番号のリンク記法ともに正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

内容は専門知識を持つエンジニア向けに書かれており、過度な初心者向けの解説がなく、対象読者に適合しています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論→各論で構成され、各段落はトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が守られており、可読性が高いです。

Diff内容との照合 ⚠ WARNING

コードブロックとDiff内容の一致

「技術的な変更」セクションの「変更前」コード引用が、Diffで実際に変更された行と完全には一致していません。ただし、説明の文脈上、意図は理解できるためWARNINGとします。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

「query_log_tags」「ActiveSupport::Notifications」などの技術用語が正確かつ適切に使用されています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

メソッドシグネチャの変更やコンテキストキーの追加に関する説明は、提供されたDiffの内容と完全に一致しており、技術的に正確です。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

記事内のすべての主張(デバッグの背景、代替案、セキュリティへの配慮など)はPRのDescriptionやDiffの内容で裏付けられており、ハルシネーションは見られません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#56683)が正確に記載されています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトルはPRの主題「Pass sql query to query log tags」を的確に反映しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

記事にはPR情報に基づかない外部知識(バージョン情報、リリース予定など)は含まれていません。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

記事内の時間表現はPR情報と矛盾しておらず、正確です。