Add Delayed Job pending and enqueued counts (#95)

Add Delayed Job pending and enqueued counts (#95)

diff --git a/lib/prometheus_exporter/instrumentation/delayed_job.rb b/lib/prometheus_exporter/instrumentation/delayed_job.rb
index ca7888e..5141d1b 100644
--- a/lib/prometheus_exporter/instrumentation/delayed_job.rb
+++ b/lib/prometheus_exporter/instrumentation/delayed_job.rb
@@ -13,7 +13,9 @@ module PrometheusExporter::Instrumentation
           callbacks do |lifecycle|
             lifecycle.around(:invoke_job) do |job, *args, &block|
               max_attempts = Delayed::Worker.max_attempts
-              instrumenter.call(job, max_attempts, *args, &block)
+              enqueued_count = Delayed::Job.count
+              pending_count = Delayed::Job.where(attempts: 0, locked_at: nil).count
+              instrumenter.call(job, max_attempts, enqueued_count, pending_count, *args, &block)
             end
           end
         end
@@ -26,7 +28,7 @@ module PrometheusExporter::Instrumentation
       @client = client || PrometheusExporter::Client.default
     end
 
-    def call(job, max_attempts, *args, &block)
+    def call(job, max_attempts, enqueued_count, pending_count, *args, &block)
       success = false
       start = ::Process.clock_gettime(::Process::CLOCK_MONOTONIC)
       attempts = job.attempts + 1 # Increment because we're adding the current attempt
@@ -42,7 +44,9 @@ module PrometheusExporter::Instrumentation
         success: success,
         duration: duration,
         attempts: attempts,
-        max_attempts: max_attempts
+        max_attempts: max_attempts,
+        enqueued: enqueued_count,
+        pending: pending_count
       )
     end
   end
diff --git a/lib/prometheus_exporter/server/delayed_job_collector.rb b/lib/prometheus_exporter/server/delayed_job_collector.rb
index 6e21f1d..8318ed3 100644
--- a/lib/prometheus_exporter/server/delayed_job_collector.rb
+++ b/lib/prometheus_exporter/server/delayed_job_collector.rb
@@ -21,12 +21,15 @@ module PrometheusExporter::Server
       @delayed_job_duration_seconds_summary.observe(obj["duration"], status: "success") if obj["success"]
       @delayed_job_duration_seconds_summary.observe(obj["duration"], status: "failed")  if !obj["success"]
       @delayed_job_attempts_summary.observe(obj["attempts"]) if obj["success"]
+      @delayed_jobs_enqueued.observe(obj["enqueued"])
+      @delayed_jobs_pending.observe(obj["pending"])
     end
 
     def metrics
       if @delayed_jobs_total
         [@delayed_job_duration_seconds, @delayed_jobs_total, @delayed_failed_jobs_total,
-         @delayed_jobs_max_attempts_reached_total, @delayed_job_duration_seconds_summary, @delayed_job_attempts_summary]
+         @delayed_jobs_max_attempts_reached_total, @delayed_job_duration_seconds_summary, @delayed_job_attempts_summary,
+         @delayed_jobs_enqueued, @delayed_jobs_pending]
       else
         []
       end
@@ -45,6 +48,14 @@ module PrometheusExporter::Server
         PrometheusExporter::Metric::Counter.new(
           "delayed_jobs_total", "Total number of delayed jobs executed.")
 
+        @delayed_jobs_enqueued =
+        PrometheusExporter::Metric::Gauge.new(
+          "delayed_jobs_enqueued", "Number of enqueued delayed jobs.")
+
+        @delayed_jobs_pending =
+        PrometheusExporter::Metric::Gauge.new(
+          "delayed_jobs_pending", "Number of pending delayed jobs.")
+
         @delayed_failed_jobs_total =
         PrometheusExporter::Metric::Counter.new(
           "delayed_failed_jobs_total", "Total number failed delayed jobs executed.")
diff --git a/test/server/collector_test.rb b/test/server/collector_test.rb
index 36d20a4..2112fd7 100644
--- a/test/server/collector_test.rb
+++ b/test/server/collector_test.rb
@@ -350,7 +350,7 @@ class PrometheusCollectorTest < Minitest::Test
     job.expect(:handler, "job_class: Class")
     job.expect(:attempts, 0)
 
-    instrument.call(job, 20, nil, "default") do
+    instrument.call(job, 20, 10, 0, nil, "default") do
       # nothing
     end
 
@@ -359,7 +359,7 @@ class PrometheusCollectorTest < Minitest::Test
     failed_job.expect(:attempts, 1)
 
     begin
-      instrument.call(failed_job, 25, nil, "default") do
+      instrument.call(failed_job, 25, 10, 0, nil, "default") do
         boom
       end
     rescue
@@ -370,6 +370,8 @@ class PrometheusCollectorTest < Minitest::Test
     assert(result.include?("delayed_failed_jobs_total{job_name=\"Object\"} 1"), "has failed job")
     assert(result.include?("delayed_jobs_total{job_name=\"Class\"} 1"), "has working job")
     assert(result.include?("delayed_job_duration_seconds"), "has duration")
+    assert(result.include?("delayed_jobs_enqueued 10"), "has enqueued count")
+    assert(result.include?("delayed_jobs_pending 0"), "has pending count")
     job.verify
     failed_job.verify
   end
@@ -384,7 +386,7 @@ class PrometheusCollectorTest < Minitest::Test
     job.expect(:handler, "job_class: Class")
     job.expect(:attempts, 0)
 
-    instrument.call(job, 25, nil, "default") do
+    instrument.call(job, 25, 10, 0, nil, "default") do
       # nothing
     end
 
@@ -393,7 +395,7 @@ class PrometheusCollectorTest < Minitest::Test
     failed_job.expect(:attempts, 1)
 
     begin
-      instrument.call(failed_job, 25, nil, "default") do
+      instrument.call(failed_job, 25, 10, 0, nil, "default") do
         boom
       end
     rescue
@@ -404,6 +406,8 @@ class PrometheusCollectorTest < Minitest::Test
     assert(result.include?('delayed_failed_jobs_total{job_name="Object",service="service1"} 1'), "has failed job")
     assert(result.include?('delayed_jobs_total{job_name="Class",service="service1"} 1'), "has working job")
     assert(result.include?('delayed_job_duration_seconds{job_name="Class",service="service1"}'), "has duration")
+    assert(result.include?("delayed_jobs_enqueued 10"), "has enqueued count")
+    assert(result.include?("delayed_jobs_pending 0"), "has pending count")
     job.verify
     failed_job.verify
   end

GitHub sha: e598fd47