mirror of
https://github.com/discourse/discourse.git
synced 2024-12-13 16:36:03 +08:00
ae1d8c50da
This commits introduces the `sidekiq_report_long_running_jobs_minutes` global setting which allows a site administrator to log a warning in the Rails log when a Sidekiq job has been running for too long. The warning is logged with the backtrace of the thread that is processing the Sidekiq job to make it easier to figure out what a sidekiq job is stuck on.
81 lines
2.0 KiB
Ruby
81 lines
2.0 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "sidekiq_long_running_job_logger"
|
|
|
|
RSpec.describe SidekiqLongRunningJobLogger do
|
|
before do
|
|
@orig_logger = Rails.logger
|
|
Rails.logger = @fake_logger = FakeLogger.new
|
|
end
|
|
|
|
after { Rails.logger = @orig_logger }
|
|
|
|
it "logs long-running jobs" do
|
|
hostname = Discourse.os_hostname
|
|
stuck_sidekiq_job_minutes = 10
|
|
|
|
Sidekiq::Workers
|
|
.expects(:new)
|
|
.returns(
|
|
[
|
|
[
|
|
"#{hostname}:1234",
|
|
"some_sidekiq_id",
|
|
{
|
|
"run_at" => (Time.now - (60 * (stuck_sidekiq_job_minutes + 1))).to_i,
|
|
"payload" => {
|
|
"jid" => "job_1",
|
|
"class" => "TestWorker",
|
|
},
|
|
},
|
|
],
|
|
[
|
|
"#{hostname}:1234",
|
|
"some_other_sidekiq_id",
|
|
{
|
|
"run_at" => Time.now.to_i,
|
|
"payload" => {
|
|
"jid" => "job_2",
|
|
"class" => "AnotherWorker",
|
|
},
|
|
},
|
|
],
|
|
],
|
|
)
|
|
.twice
|
|
|
|
thread = mock("Thread")
|
|
thread.expects(:[]).with("sidekiq_tid").returns("some_sidekiq_id").once
|
|
thread.expects(:backtrace).returns(%w[line lines]).once
|
|
Thread.expects(:list).returns([thread]).once
|
|
|
|
begin
|
|
checker = described_class.new(stuck_sidekiq_job_minutes:)
|
|
|
|
loops = 0
|
|
|
|
checker.start { loops += 1 }
|
|
|
|
wait_for { loops == 1 }
|
|
|
|
expect(@fake_logger.warnings.size).to eq(1)
|
|
|
|
expect(@fake_logger.warnings).to include(
|
|
"Sidekiq job `TestWorker` has been running for more than 10 minutes\nline\nlines\n",
|
|
)
|
|
|
|
checker.thread.wakeup # Force the thread to run the next loop
|
|
|
|
wait_for { loops == 2 }
|
|
|
|
expect(@fake_logger.warnings.size).to eq(1)
|
|
|
|
expect(@fake_logger.warnings).to include(
|
|
"Sidekiq job `TestWorker` has been running for more than 10 minutes\nline\nlines\n",
|
|
)
|
|
ensure
|
|
checker.stop
|
|
end
|
|
end
|
|
end
|