lib/honeybadger/monitor/worker.rb in honeybadger-1.10.2 vs lib/honeybadger/monitor/worker.rb in honeybadger-1.10.3
- old
+ new
@@ -3,23 +3,37 @@
module Honeybadger
module Monitor
class Worker
include Singleton
+ # Sub-class thread so we have a named thread (useful for debugging in Thread.list).
+ class MetricsThread < Thread
+ end
+
def initialize
init_metrics
@delay = 60
@per_request = 100
@sender = Monitor::Sender.new(Honeybadger.configuration)
- @thread = Thread.new do
- while true do
+ @lock = Mutex.new
+ start
+ at_exit { stop }
+ end
+
+ def start
+ @thread = MetricsThread.new do
+ until Thread.current[:should_exit] do
send_metrics
sleep @delay
end
end
end
+ def stop
+ @thread[:should_exit] = true if @thread
+ end
+
def timing(name, value)
add_metric(name, value, :timing)
end
def increment(name, value)
@@ -30,14 +44,21 @@
def init_metrics
@metrics = { :timing => {}, :counter => {} }
end
+ def collect_metrics
+ @lock.synchronize do
+ metrics = @metrics
+ init_metrics
+ metrics
+ end
+ end
+
def send_metrics
- metrics = @metrics.dup
+ metrics = collect_metrics
return unless metrics[:timing].any? || metrics[:counter].any?
- init_metrics
[].tap do |m|
metrics[:counter].each do |metric, values|
m << "#{metric} #{values.sum}"
end
metrics[:timing].each do |metric, values|
@@ -49,18 +70,20 @@
m << "#{metric}:stddev #{values.standard_dev}" if values.count > 1
m << "#{metric} #{values.count}"
end
end.each_slice(@per_request) do |mm|
begin
- @sender.send_metrics({ :metrics => mm, :environment => Honeybadger.configuration.environment_name, :hostname => Honeybadger.configuration.hostname })
+ @sender.send_metrics({ :metrics => mm.compact, :environment => Honeybadger.configuration.environment_name, :hostname => Honeybadger.configuration.hostname })
rescue Exception => e
log(:error, "[Honeybadger::Monitor::Worker#send_metrics] Failed to send #{mm.count} metrics: #{e.class} - #{e.message}\nBacktrace:\n#{e.backtrace.join("\n\t")}")
end
end
end
def add_metric(name, value, kind)
- (@metrics[kind][name] ||= Honeybadger::Array.new) << value
+ @lock.synchronize do
+ (@metrics[kind][name] ||= Honeybadger::Array.new) << value
+ end
end
def log(level, message)
Honeybadger.write_verbose_log(message, level)
end