lib/barnes/instruments/puma_backlog.rb in barnes-0.0.4 vs lib/barnes/instruments/puma_backlog.rb in barnes-0.0.5

- old
+ new

@@ -1,11 +1,56 @@ # frozen_string_literal: true module Barnes module Instruments class PumaBacklog + # This class is responsible for consuming a puma + # generated stats hash that can come in two "flavors" + # one is a "single process" server which will look like this: + # + # { "backlog": 0, "running": 0, "pool_capacity": 16 } + # + # The other is a multiple cluster server that will look like this: + # + # {"workers"=>2, "phase"=>0, "booted_workers"=>2, "old_workers"=>0, "worker_status"=>[{"pid"=>35020, "index"=>0, "phase"=>0, "booted"=>true, "last_checkin"=>"2018-05-21T19:53:18Z", "last_status"=>{"backlog"=>0, "running"=>5, "pool_capacity"=>5}}, {"pid"=>35021, "index"=>1, "phase"=>0, "booted"=>true, "last_checkin"=>"2018-05-21T19:53:18Z", "last_status"=>{"backlog"=>0, "running"=>5, "pool_capacity"=>5}}]} + # + class StatValue + attr_reader :stats, :key + + def initialize(stats, key) + @stats = stats + @key = key + @cluster = stats.key?("worker_status") + end + + def single? + !cluster? + end + + def cluster? + @cluster + end + + # For single worker process use value directly + # for multiple workers use the sum. + # + # https://github.com/puma/puma/pull/1532 + def value + return stats[key] if single? + first_worker = stats["worker_status"].first + return nil unless first_worker && first_worker["last_status"].key?(key) + + value = 0 + stats["worker_status"].each do |worker_status| + value += worker_status["last_status"][key] || 0 + end + return value + end + end + def initialize(sample_rate=nil) + @debug = ENV["BARNES_DEBUG_PUMA_STATS"] end def valid? defined?(Puma) && Puma.respond_to?(:stats) && @@ -24,25 +69,20 @@ raise e unless e.message =~ /nil/ raise e unless e.message =~ /stats/ return {} end - # For single worker process use backlog directly - # for multiple workers sum backlog. - # - # https://github.com/puma/puma/pull/1532 def instrument!(state, counters, gauges) - stats = self.json_stats + stats = json_stats return if stats.empty? - backlog = stats["backlog"] - if backlog.nil? - backlog = stats["worker_status"].map do |worker_status| - worker_status["last_status"]["backlog"] - end.reduce(0, :+) - end + puts "Puma debug stats from barnes: #{stats}" if @debug - gauges[:'backlog.requests'] = backlog + pool_capacity = StatValue.new(stats, "pool_capacity").value + backlog = StatValue.new(stats, "backlog").value + + gauges[:'pool.capacity'] = pool_capacity if pool_capacity + gauges[:'backlog.requests'] = backlog if backlog end end end end