From 2d4a88fd9cd858c2d105636c09c0749b5b287b45 Mon Sep 17 00:00:00 2001 From: Jason Raitz Date: Fri, 6 Feb 2026 16:40:04 -0500 Subject: [PATCH 1/8] adds a few values to good_job logs when available When active_jobs are enqueued, this will add current_attributes for jobid, request_id, and ip_address. --- app/controllers/application_controller.rb | 7 +++++++ app/jobs/application_job.rb | 19 +++++++++++++++++++ app/models/current.rb | 4 ++++ 3 files changed, 30 insertions(+) create mode 100644 app/models/current.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 4072691a..d684e962 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,6 +3,8 @@ class ApplicationController < ActionController::Base include AuthSupport include ExceptionHandling + before_action :set_current_request_id_and_ip_address + # @!group Class Attributes # @!attribute [rw] # Value of the "Questions?" mailto link in the footer @@ -19,6 +21,11 @@ class ApplicationController < ActionController::Base private + def set_current_request_id_and_ip_address + Current.request_id = request.request_id + Current.ip_address = request.remote_ip + end + helper_method :authenticated? # @return Regexp Pattern determining whether a request should be "hidden" diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index 0885213c..425d8262 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -1,8 +1,27 @@ class ApplicationJob < ActiveJob::Base + before_enqueue do + self.arguments << { current_attributes: Current.attributes } + end + + around_perform do |job, block| + current_attributes = job.arguments.pop[:current_attributes] || {} + Current.set(current_attributes) do + block.call + end + end + + around_perform :log_activejob_id + def today @today ||= Time.zone.now.strftime('%Y%m%d') end + # AP-186: Add the ActiveJob ID to job logs + def log_activejob_id + logger.with_fields = { activejob_id: job_id, request_id: Current.request_id, ip_address: Current.ip_address } + yield + end + # Log an exception def log_error(error) # TODO: share code w/ApplicationController diff --git a/app/models/current.rb b/app/models/current.rb new file mode 100644 index 00000000..3a1c269b --- /dev/null +++ b/app/models/current.rb @@ -0,0 +1,4 @@ +class Current < ActiveSupport::CurrentAttributes + attribute :request_id, :ip_address + +end From 5a771ee90437cb46b7efbbb24cce2d7ad93df70e Mon Sep 17 00:00:00 2001 From: Jason Raitz Date: Mon, 9 Feb 2026 15:19:17 -0500 Subject: [PATCH 2/8] better request_id passing - removes remote_ip from log message --- app/controllers/application_controller.rb | 5 ++--- app/jobs/application_job.rb | 12 ++++++------ app/models/current.rb | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index d684e962..be65889b 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,7 +3,7 @@ class ApplicationController < ActionController::Base include AuthSupport include ExceptionHandling - before_action :set_current_request_id_and_ip_address + before_action :set_current_request_id # @!group Class Attributes # @!attribute [rw] @@ -21,9 +21,8 @@ class ApplicationController < ActionController::Base private - def set_current_request_id_and_ip_address + def set_current_request_id Current.request_id = request.request_id - Current.ip_address = request.remote_ip end helper_method :authenticated? diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index 425d8262..ffd80181 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -1,13 +1,13 @@ class ApplicationJob < ActiveJob::Base + attr_reader :request_id + before_enqueue do - self.arguments << { current_attributes: Current.attributes } + self.arguments << { request_id: Current.request_id } end around_perform do |job, block| - current_attributes = job.arguments.pop[:current_attributes] || {} - Current.set(current_attributes) do - block.call - end + @request_id = job.arguments.pop[:request_id] || '' + block.call end around_perform :log_activejob_id @@ -18,7 +18,7 @@ def today # AP-186: Add the ActiveJob ID to job logs def log_activejob_id - logger.with_fields = { activejob_id: job_id, request_id: Current.request_id, ip_address: Current.ip_address } + logger.with_fields = { activejob_id: job_id, request_id: @request_id } yield end diff --git a/app/models/current.rb b/app/models/current.rb index 3a1c269b..a2bfd247 100644 --- a/app/models/current.rb +++ b/app/models/current.rb @@ -1,4 +1,4 @@ class Current < ActiveSupport::CurrentAttributes - attribute :request_id, :ip_address + attribute :request_id end From 22114513a43c12bfc37868cb8600006193cd6820 Mon Sep 17 00:00:00 2001 From: Jason Raitz Date: Mon, 9 Feb 2026 15:29:53 -0500 Subject: [PATCH 3/8] update method name --- app/jobs/application_job.rb | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index ffd80181..c227b649 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -2,7 +2,7 @@ class ApplicationJob < ActiveJob::Base attr_reader :request_id before_enqueue do - self.arguments << { request_id: Current.request_id } + arguments << { request_id: Current.request_id } end around_perform do |job, block| @@ -10,14 +10,13 @@ class ApplicationJob < ActiveJob::Base block.call end - around_perform :log_activejob_id + around_perform :log_job_metadata def today @today ||= Time.zone.now.strftime('%Y%m%d') end - # AP-186: Add the ActiveJob ID to job logs - def log_activejob_id + def log_job_metadata logger.with_fields = { activejob_id: job_id, request_id: @request_id } yield end From 8f6918800230f17d68d19251c3aa00cda7a02e6a Mon Sep 17 00:00:00 2001 From: Jason Raitz Date: Mon, 9 Feb 2026 16:09:09 -0500 Subject: [PATCH 4/8] guard job queue for no request_id - only add a request_id to the job if there is a request_id specs tend not to stub out request_id --- app/jobs/application_job.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index c227b649..77cbed89 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -2,11 +2,13 @@ class ApplicationJob < ActiveJob::Base attr_reader :request_id before_enqueue do - arguments << { request_id: Current.request_id } + arguments << { request_id: Current.request_id } if Current.request_id end around_perform do |job, block| - @request_id = job.arguments.pop[:request_id] || '' + if job.arguments.last.is_a?(Hash) && job.arguments.last.key?(:request_id) + @request_id = job.arguments.pop[:request_id] + end block.call end From baf555b9d9ef6b5fec3cc275118dfd5b0b8a3244 Mon Sep 17 00:00:00 2001 From: Jason Raitz Date: Mon, 9 Feb 2026 16:12:28 -0500 Subject: [PATCH 5/8] rubocop fix --- app/jobs/application_job.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb index 77cbed89..76d43bdb 100644 --- a/app/jobs/application_job.rb +++ b/app/jobs/application_job.rb @@ -6,9 +6,7 @@ class ApplicationJob < ActiveJob::Base end around_perform do |job, block| - if job.arguments.last.is_a?(Hash) && job.arguments.last.key?(:request_id) - @request_id = job.arguments.pop[:request_id] - end + @request_id = job.arguments.pop[:request_id] if job.arguments.last.is_a?(Hash) && job.arguments.last.key?(:request_id) block.call end From 1f2d06a87dfcca2b21573775c863d39c1f6d80e2 Mon Sep 17 00:00:00 2001 From: Jason Raitz Date: Wed, 11 Feb 2026 14:50:31 -0500 Subject: [PATCH 6/8] add spec for application_job - tests request_id manipulation around queues - tests attaching activejob_id and request_id to logs --- spec/jobs/application_job_spec.rb | 81 +++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 spec/jobs/application_job_spec.rb diff --git a/spec/jobs/application_job_spec.rb b/spec/jobs/application_job_spec.rb new file mode 100644 index 00000000..8f0c1938 --- /dev/null +++ b/spec/jobs/application_job_spec.rb @@ -0,0 +1,81 @@ +require 'rails_helper' + +class TestJob < ApplicationJob + def perform(*args); end +end + +RSpec.describe ApplicationJob, type: :job do + include ActiveJob::TestHelper + + # # not sure if needed + # around do |example| + # original_log_level = Rails.logger.level + # Rails.logger.level = :debug + # example.run + # Rails.logger.level = original_log_level + # end + + after do + ActiveJob::Base.queue_adapter.enqueued_jobs.clear + end + + describe 'jobs with request_id' do + let(:request_id) { SecureRandom.uuid } + + context 'when Current.request_id is set' do + before do + Current.request_id = request_id + end + + it 'enqueues the job with the request_id' do + expect do + TestJob.perform_later('some_arg') + end.to have_enqueued_job(TestJob).with('some_arg', { request_id: request_id }) + end + + it 'sets @request_id and removes it from the arguments' do + job = TestJob.new('some_arg', { request_id: request_id }) + perform_enqueued_jobs { job.perform_now } + + expect(job.instance_variable_get(:@request_id)).to eq(request_id) + expect(job.arguments).to eq(['some_arg']) + end + + it 'logs the activejob_id and request_id' do + job = TestJob.new('some_arg', { request_id: request_id }) + allow(job.logger).to receive(:with_fields=) + + perform_enqueued_jobs { job.perform_now } + + expect(job.logger).to have_received(:with_fields=).with(hash_including(activejob_id: job.job_id, request_id: request_id)) + end + end + end + + describe 'jobs without a request_id' do + context 'when Current.request_id is not set' do + it 'enqueues the job without a request_id' do + expect do + TestJob.perform_later('some_arg') + end.to have_enqueued_job(TestJob).with('some_arg') + end + + it 'does not set @request_id if not provided' do + job = TestJob.new('some_arg') + perform_enqueued_jobs { job.perform_now } + + expect(job.instance_variable_get(:@request_id)).to be_nil + expect(job.arguments).to eq(['some_arg']) + end + + it 'logs the activejob_id without a request_id' do + job = TestJob.new('some_arg') + allow(job.logger).to receive(:with_fields=) + + perform_enqueued_jobs { job.perform_now } + + expect(job.logger).to have_received(:with_fields=).with(hash_including(activejob_id: job.job_id, request_id: nil)) + end + end + end +end From efcdc45f6a7a4691c03523d8b875c122f688eff0 Mon Sep 17 00:00:00 2001 From: Jason Raitz Date: Wed, 11 Feb 2026 14:53:23 -0500 Subject: [PATCH 7/8] removing unnecessary comments --- spec/jobs/application_job_spec.rb | 8 -------- 1 file changed, 8 deletions(-) diff --git a/spec/jobs/application_job_spec.rb b/spec/jobs/application_job_spec.rb index 8f0c1938..bbfb257d 100644 --- a/spec/jobs/application_job_spec.rb +++ b/spec/jobs/application_job_spec.rb @@ -7,14 +7,6 @@ def perform(*args); end RSpec.describe ApplicationJob, type: :job do include ActiveJob::TestHelper - # # not sure if needed - # around do |example| - # original_log_level = Rails.logger.level - # Rails.logger.level = :debug - # example.run - # Rails.logger.level = original_log_level - # end - after do ActiveJob::Base.queue_adapter.enqueued_jobs.clear end From 80fa6919ff4cc032dd9084961b97de53eeb5339d Mon Sep 17 00:00:00 2001 From: Jason Raitz Date: Thu, 12 Feb 2026 15:00:35 -0500 Subject: [PATCH 8/8] clean up - adding a note to the inclusion of Current class - improving Current.request_id testing --- app/models/current.rb | 1 + spec/jobs/application_job_spec.rb | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/current.rb b/app/models/current.rb index a2bfd247..c649f440 100644 --- a/app/models/current.rb +++ b/app/models/current.rb @@ -1,3 +1,4 @@ +# see AP-513. We're bringing in Current here in order to attach the original request_id to a queued job class Current < ActiveSupport::CurrentAttributes attribute :request_id diff --git a/spec/jobs/application_job_spec.rb b/spec/jobs/application_job_spec.rb index bbfb257d..47f1c5dc 100644 --- a/spec/jobs/application_job_spec.rb +++ b/spec/jobs/application_job_spec.rb @@ -16,7 +16,7 @@ def perform(*args); end context 'when Current.request_id is set' do before do - Current.request_id = request_id + allow(Current).to receive(:request_id).and_return(request_id) end it 'enqueues the job with the request_id' do