接続プール単位でクエリログタグ形式を設定できるように

rails/rails

database.yml の接続プール定義に query_log_tags_format キーを追加できるようになり、プールごとにクエリログのタグフォーマットを上書き可能になりました。この変更により、マルチデータベース環境で :legacy:sqlcommenter を使い分けることが容易になります。

背景

従来、クエリログタグのフォーマットは config.active_record.query_log_tags_format でアプリケーション全体に一括設定されていました。そのため、異なるデータベース間でタグ形式を分ける必要があるケースに対応できませんでした。今回の PR は、接続プール単位でフォーマットを上書きできる設定項目を導入することで、この制約を解消します。

この背景は、マルチデータベース構成でそれぞれのデータベースが別々の監視ツールやログパイプラインに流れることが想定されている点に起因します。プールごとに適切なフォーマットを選択できることで、ログの一貫性と可観測性が向上します。

技術的な変更

HashConfig にアクセサを追加しました。activerecord/lib/active_record/database_configurations/hash_config.rbquery_log_tags_format メソッドが新設され、ハッシュから :query_log_tags_format の値を取得しシンボル化して返します。

def query_log_tags_format # :nodoc:
  return @query_log_tags_format if defined? @query_log_tags_format

  @query_log_tags_format = configuration_hash[:query_log_tags_format]&.to_sym
end

このアクセサにより、プール定義から直接フォーマット情報を取得できるようになりました。結果として、ActiveRecord::QueryLogs が接続プールごとに適切なフォーマットを決定できます。

QueryLogs のロジックを拡張しました。activerecord/lib/active_record/query_logs.rb では、キャッシュ変数名を cached_comment から cached_comments に変更し、フォーマッタごとにキャッシュを分離しました。また、tags_formatter=formatter_for(format) を呼び出すようになり、未対応フォーマットに対しては ArgumentError が発生します。

thread_mattr_accessor :cached_comments, instance_accessor: false

def tags_formatter=(format) # :nodoc:
  @formatter = formatter_for(format)
  @tags_formatter = format
end

さらに、clear_cache メソッドでキャッシュをリセットできるようにし、テストコード側でも ActiveRecord::QueryLogs.clear_cache が使用されるよう修正しました。

テストを追加し、機能の正しさを検証しました。activerecord/test/cases/query_logs_test.rb にプール単位でのフォーマット上書き、フォールバック、キャッシュ分離を確認する 3 つのテストケースが追加されています。

def test_per_pool_format_overrides_global_format
  ActiveRecord::QueryLogs.tags_formatter = :legacy
  ActiveRecord::QueryLogs.tags = [:application]

  with_query_log_tags_format("sqlcommenter") do |connection|
    assert_equal "select 1 /*application='active_record'*/",
      ActiveRecord::QueryLogs.call("select 1", connection)
  end
end

これらのテストは、プールごとの設定がグローバル設定を上書きすること、設定が無い場合はグローバルにフォールバックすること、そして異なるフォーマット間でキャッシュが混在しないことを保証します。

設計判断

接続プール設定への直接キー追加が採用されました。query_log_tags_formatdatabase.yml のプール定義に直接書けるため、既存の config.active_record.query_log_tags_format との互換性が保たれます。この設計は、追加の設定階層を導入せずに機能拡張を実現しています。

キャッシュ分離の設計意図は、フォーマットが異なるプールで同一キャッシュを共有するとコメントが混在するリスクがあるためです。cached_comments をフォーマッタ単位で保持することで、cache_query_log_tags が有効な状態でも正しいコメントが出力されます。テストでもこの分離が検証されています。

まとめ

この PR により、Rails は接続プール単位でクエリログタグのフォーマットを個別に指定できるようになり、マルチデータベース環境でのログ出力が柔軟かつ一貫性のあるものになります。既存設定への影響は最小限に抑えられ、キャッシュ分離による正確なタグ付与も保証されています。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
154725a6

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

品質レビュー結果

Review Status:
リトライ後承認
Review Count:
3回 (改善を経て承認)
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

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

リード文がタイトル直下にあり、背景・技術的変更・設計判断・まとめの各セクションが揃っていて、総論→各論→結論の流れが明確です。

カスタムMarkdown構文 ✓ PASS

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

ファイル名付きシンタックスハイライトは正しい形式 (```ruby:filepath) で記述され、PRリンクも [#57570](URL) の形で正しくリンク化されています。

対象読者への適合性 ✓ PASS

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

内容は Rails エンジニア向けに専門用語中心で書かれており、初心者向けの過度な説明はありません。

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

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

各セクションは総論パラグラフ→各論パラグラフ→結論パラグラフで構成され、段落はトピックセンテンスで始まり 1段落1トピック、長さも適切です。

Diff内容との照合 ⚠ WARNING

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

主要な変更点(hash_config.rb の accessor、query_logs.rb のキャッシュ分離、clear_cache の導入)は正しく掲載されていますが、test ファイルの追加テストケースが全て掲載されておらず一部省略されています。省略自体は理解を阻害しませんが、完全な Diff 反映とは言い難いため Warning とします。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

使用された技術用語は PR や Rails のドキュメントと一致しており、誤用は見られません。

説明の技術的正確性 ✓ PASS

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

記事の技術的説明は Diff と PR の記述と整合しており、因果関係も論理的です。

事実の突合 ✓ PASS

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

全ての主張は PR の内容やコード変更に裏付けられており、PR に記載されていない外部情報や推測はありません。

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

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

PR 番号やファイルパス等の固有名詞は正確に記載されています。

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

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

記事タイトルは PR の趣旨「Enable per‑pool query log tags formatter」を日本語で適切に表現しています。

外部知識の正確性 ✓ PASS

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

記事内に PR 以外のバージョン情報や LTS 等の外部知識は含まれていません。

時間表現の正確性 ✓ PASS

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

時間表現は使用されておらず、PR の記述と齟齬はありません。