Skip to content

Commit f0f5ce3

Browse files
authored
AP-513 & AP-186 improve log tracing (#18)
* 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. Closes AP-513 & AP-186 Co-authored-by @steve-sullivan
1 parent 27c9926 commit f0f5ce3

4 files changed

Lines changed: 102 additions & 0 deletions

File tree

app/controllers/application_controller.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ class ApplicationController < ActionController::Base
33
include AuthSupport
44
include ExceptionHandling
55

6+
before_action :set_current_request_id
7+
68
# @!group Class Attributes
79
# @!attribute [rw]
810
# Value of the "Questions?" mailto link in the footer
@@ -19,6 +21,10 @@ class ApplicationController < ActionController::Base
1921

2022
private
2123

24+
def set_current_request_id
25+
Current.request_id = request.request_id
26+
end
27+
2228
helper_method :authenticated?
2329

2430
# @return Regexp Pattern determining whether a request should be "hidden"

app/jobs/application_job.rb

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,26 @@
11
class ApplicationJob < ActiveJob::Base
2+
attr_reader :request_id
3+
4+
before_enqueue do
5+
arguments << { request_id: Current.request_id } if Current.request_id
6+
end
7+
8+
around_perform do |job, block|
9+
@request_id = job.arguments.pop[:request_id] if job.arguments.last.is_a?(Hash) && job.arguments.last.key?(:request_id)
10+
block.call
11+
end
12+
13+
around_perform :log_job_metadata
14+
215
def today
316
@today ||= Time.zone.now.strftime('%Y%m%d')
417
end
518

19+
def log_job_metadata
20+
logger.with_fields = { activejob_id: job_id, request_id: @request_id }
21+
yield
22+
end
23+
624
# Log an exception
725
def log_error(error)
826
# TODO: share code w/ApplicationController

app/models/current.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# see AP-513. We're bringing in Current here in order to attach the original request_id to a queued job
2+
class Current < ActiveSupport::CurrentAttributes
3+
attribute :request_id
4+
5+
end

spec/jobs/application_job_spec.rb

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
require 'rails_helper'
2+
3+
class TestJob < ApplicationJob
4+
def perform(*args); end
5+
end
6+
7+
RSpec.describe ApplicationJob, type: :job do
8+
include ActiveJob::TestHelper
9+
10+
after do
11+
ActiveJob::Base.queue_adapter.enqueued_jobs.clear
12+
end
13+
14+
describe 'jobs with request_id' do
15+
let(:request_id) { SecureRandom.uuid }
16+
17+
context 'when Current.request_id is set' do
18+
before do
19+
allow(Current).to receive(:request_id).and_return(request_id)
20+
end
21+
22+
it 'enqueues the job with the request_id' do
23+
expect do
24+
TestJob.perform_later('some_arg')
25+
end.to have_enqueued_job(TestJob).with('some_arg', { request_id: request_id })
26+
end
27+
28+
it 'sets @request_id and removes it from the arguments' do
29+
job = TestJob.new('some_arg', { request_id: request_id })
30+
perform_enqueued_jobs { job.perform_now }
31+
32+
expect(job.instance_variable_get(:@request_id)).to eq(request_id)
33+
expect(job.arguments).to eq(['some_arg'])
34+
end
35+
36+
it 'logs the activejob_id and request_id' do
37+
job = TestJob.new('some_arg', { request_id: request_id })
38+
allow(job.logger).to receive(:with_fields=)
39+
40+
perform_enqueued_jobs { job.perform_now }
41+
42+
expect(job.logger).to have_received(:with_fields=).with(hash_including(activejob_id: job.job_id, request_id: request_id))
43+
end
44+
end
45+
end
46+
47+
describe 'jobs without a request_id' do
48+
context 'when Current.request_id is not set' do
49+
it 'enqueues the job without a request_id' do
50+
expect do
51+
TestJob.perform_later('some_arg')
52+
end.to have_enqueued_job(TestJob).with('some_arg')
53+
end
54+
55+
it 'does not set @request_id if not provided' do
56+
job = TestJob.new('some_arg')
57+
perform_enqueued_jobs { job.perform_now }
58+
59+
expect(job.instance_variable_get(:@request_id)).to be_nil
60+
expect(job.arguments).to eq(['some_arg'])
61+
end
62+
63+
it 'logs the activejob_id without a request_id' do
64+
job = TestJob.new('some_arg')
65+
allow(job.logger).to receive(:with_fields=)
66+
67+
perform_enqueued_jobs { job.perform_now }
68+
69+
expect(job.logger).to have_received(:with_fields=).with(hash_including(activejob_id: job.job_id, request_id: nil))
70+
end
71+
end
72+
end
73+
end

0 commit comments

Comments
 (0)