接続プール単位でクエリログタグ形式を設定できるように
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.rb に query_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_format は database.yml のプール定義に直接書けるため、既存の config.active_record.query_log_tags_format との互換性が保たれます。この設計は、追加の設定階層を導入せずに機能拡張を実現しています。
キャッシュ分離の設計意図は、フォーマットが異なるプールで同一キャッシュを共有するとコメントが混在するリスクがあるためです。cached_comments をフォーマッタ単位で保持することで、cache_query_log_tags が有効な状態でも正しいコメントが出力されます。テストでもこの分離が検証されています。
まとめ
この PR により、Rails は接続プール単位でクエリログタグのフォーマットを個別に指定できるようになり、マルチデータベース環境でのログ出力が柔軟かつ一貫性のあるものになります。既存設定への影響は最小限に抑えられ、キャッシュ分離による正確なタグ付与も保証されています。