ActiveJob の `perform_start` イベントにアダプタ情報を追加

rails/rails

ActiveJob の構造化イベント active_job.started のペイロードから欠落していた :adapter キーを補完し、ログ出力とイベント消費側の情報整合性を回復した変更です。

背景

ActiveJob::StructuredEventSubscriber#perform_start が生成するペイロードには、他のイベント(enqueueenqueue_atenqueue_allperform)と異なり :adapter が含まれていませんでした。その結果、ActiveJob::LogSubscriber#startedqueue_name ヘルパーで期待する adapter(queue) 形式の文字列が生成できず、実行ログが「Performing … from (default)」という形でアダプタ名を省略して表示されました。

この不整合は、同一ジョブに対して開始ログと完了ログで情報が食い違うという見た目上の問題を生み、構造化イベントを利用する外部ツールでもアダプタ情報が取得できないという実用上の欠点をもたらしていました。

技術的な変更

ペイロードに :adapter を追加

perform_start メソッド内でイベントペイロードから adapter = event.payload[:adapter] を取得し、生成するハッシュに adapter: ActiveJob.adapter_name(adapter) を加えるよう修正しました。

def perform_start(event)
  job = event.payload[:job]
  adapter = event.payload[:adapter]
  payload = {
    job_class: job.class.name,
    job_id: job.job_id,
    queue: job.queue_name,
    adapter: ActiveJob.adapter_name(adapter),
    enqueued_at: job.enqueued_at&.utc&.iso8601(9),
  }
  if job.class.log_arguments?
    # ...
  end
end

テストの拡張

ペイロード検証テスト test_perform_start_jobadapter: アサートを追加し、ActiveJob.adapter_name(ActiveJob::Base.queue_adapter) が正しく含まれることを確認するよう変更しました。

assert_event_reported("active_job.started", payload: {
  job_class: TestJob.name,
  queue: "default",
  adapter: ActiveJob.adapter_name(ActiveJob::Base.queue_adapter)
}) do
  TestJob.perform_now
end

テスト結果は、修正前は active_job.started:adapter が欠如し失敗(RED)だったのが、修正後は全テストが成功(GREEN)し、期待通りのペイロードが生成されることを示しています。

設計判断

既存インストゥルメンテーションを活用した最小限の修正

ActiveJob::Instrumentation#instrument はすべての通知で payload[:adapter] = queue_adapter を設定しているため、情報はすでに通知ペイロードに存在していました。StructuredEventSubscriber がそれを単に転送し忘れていた点を修正しただけで、他のコンポーネントや外部インターフェースへの影響はありません。

このアプローチは、後方互換性を保ちつつ情報ロスを防ぐという設計方針に沿っており、余計なロジック追加や新しい設定項目の導入を避けています。結果として、既存の perform_start ロジックはほぼ変わらず、アダプタ情報の可視化だけが向上しました。

まとめ

perform_start イベントで失われていた :adapter キーを正しく転送することで、ログ出力と構造化イベントの情報が一貫し、ユーザーおよびツールがジョブ実行時のアダプタを正確に把握できるようになりました。修正はインストゥルメンテーションが提供する情報を活かした最小限のコード追加で実現され、既存機能への影響はありません。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
21518d75

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

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

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

リード文、背景、技術的変更、設計判断(任意)、まとめの構成が明確で、各要素が揃っています。

カスタムMarkdown構文 ⚠ WARNING

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

コードブロックのファイル名付きハイライトは正しい形式ですが、PRリンクが `[PR #57725](URL)` となっており、仕様の `[#123](URL)` 形式と完全に一致していません。

対象読者への適合性 ✓ PASS

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

専門的なエンジニア向けの内容で、不要な初心者向け説明はありません。

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

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

各セクションが総論→各論→結論の流れで構成され、段落はトピックセンテンスで始まり、1段落1トピック・適切な長さです。

Diff内容との照合 ✓ PASS

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

記事内のコードブロックは提供されたDiffと正確に一致しています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

使用されている技術用語は正確で、PR情報と整合しています。

説明の技術的正確性 ✓ PASS

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

技術的な説明はPRの内容と合致しており、誤りはありません。

事実の突合 ✓ PASS

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

全ての主張がPRのタイトル・説明・Diffに裏付けられており、ハルシネーションは見られません。

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

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

PR番号 #57725 など数値・固有名詞は正確です。

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

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

記事タイトルはPRタイトルの内容を正確に反映しています。

外部知識の正確性 ✓ PASS

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

外部知識(バージョン支援状況等)は記載されていません。

時間表現の正確性 ✓ PASS

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

時間表現の歪曲はなく、PRの記述と一致しています。