@@ -33,6 +33,8 @@ module Sidekiq
33
33
gauge :jobs_dead_count , tags : [ ] , comment : "The number of jobs exceeded their retry count."
34
34
gauge :active_processes , tags : [ ] , comment : "The number of active Sidekiq worker processes."
35
35
gauge :queue_latency , tags : %i[ queue ] , comment : "The queue latency, the difference in seconds since the oldest job in the queue was enqueued"
36
+ gauge :running_job_runtime , tags : %i[ queue worker ] , aggregation : :max , unit : :seconds ,
37
+ comment : "How long currently running jobs are running (useful for detection of hung jobs)"
36
38
37
39
histogram :job_latency , comment : "The job latency, the difference in seconds between enqueued and running time" ,
38
40
unit : :seconds , per : :job ,
@@ -59,6 +61,8 @@ module Sidekiq
59
61
sidekiq_queue_latency . set ( { queue : queue . name } , queue . latency )
60
62
end
61
63
64
+ Yabeda ::Sidekiq . track_max_job_runtime
65
+
62
66
# That is quite slow if your retry set is large
63
67
# I don't want to enable it by default
64
68
# retries_by_queues =
@@ -105,6 +109,22 @@ def custom_tags(worker, job)
105
109
106
110
worker . method ( :yabeda_tags ) . arity . zero? ? worker . yabeda_tags : worker . yabeda_tags ( *job [ "args" ] )
107
111
end
112
+
113
+ # Hash of hashes containing all currently running jobs' start timestamps
114
+ # to calculate maximum durations of currently running not yet completed jobs
115
+ # { { queue: "default", worker: "SomeJob" } => { "jid1" => 100500, "jid2" => 424242 } }
116
+ attr_accessor :jobs_started_at
117
+
118
+ def track_max_job_runtime
119
+ now = Process . clock_gettime ( Process ::CLOCK_MONOTONIC )
120
+ ::Yabeda ::Sidekiq . jobs_started_at . each do |labels , jobs |
121
+ oldest_job_started_at = jobs . values . min
122
+ oldest_job_duration = oldest_job_started_at ? ( now - oldest_job_started_at ) . round ( 3 ) : 0
123
+ Yabeda . sidekiq . running_job_runtime . set ( labels , oldest_job_duration )
124
+ end
125
+ end
108
126
end
127
+
128
+ self . jobs_started_at = Concurrent ::Hash . new { |hash , key | hash [ key ] = Concurrent ::Hash . new }
109
129
end
110
130
end
0 commit comments