lib/honeybadger/agent.rb in honeybadger-2.6.1 vs lib/honeybadger/agent.rb in honeybadger-2.7.0

- old
+ new

@@ -11,18 +11,12 @@ class Agent extend Forwardable include Logging::Helper - # Internal: Sub-class thread so we have a named thread (useful for debugging in Thread.list). - class Thread < ::Thread; end - autoload :Worker, 'honeybadger/agent/worker' autoload :NullWorker, 'honeybadger/agent/worker' - autoload :Batch, 'honeybadger/agent/batch' - autoload :MetricsCollector, 'honeybadger/agent/metrics_collector' - autoload :TraceCollection, 'honeybadger/agent/trace_collection' class << self extend Forwardable def_delegators :callbacks, :exception_filter, :exception_fingerprint, :backtrace_filter @@ -81,25 +75,13 @@ @instance.stop(*args) if @instance @instance = nil end def self.fork(*args) - self.instance ? self.instance.fork(*args) : false + # noop end - def self.trace(*args) - self.instance ? self.instance.trace(*args) : false - end - - def self.timing(*args) - self.instance ? self.instance.timing(*args) : false - end - - def self.increment(*args) - self.instance ? self.instance.increment(*args) : false - end - def self.flush(&block) if self.instance self.instance.flush(&block) elsif !block_given? false @@ -130,25 +112,21 @@ else @config ||= Config.new end end - attr_reader :delay, :workers, :pid, :thread, :traces, :metrics + attr_reader :workers def initialize(config) @config = config - @delay = config.debug? ? 10 : 60 @mutex = Mutex.new - @pid = Process.pid unless config.backend.kind_of?(Backend::Server) warn('Initializing development backend: data will not be reported.') end init_workers - init_traces - init_metrics at_exit do # Fix for https://bugs.ruby-lang.org/issues/5218 if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ruby' && RUBY_VERSION =~ /1\.9/ exit_status = $!.status if $!.is_a?(SystemExit) @@ -160,53 +138,18 @@ exit(exit_status) if exit_status end end - # Internal: Spawn the agent thread. This method is idempotent. - # - # Returns false if the Agent is stopped, otherwise true. - def start - mutex.synchronize do - return false unless pid - return true if thread && thread.alive? - - debug { 'starting agent' } - - @pid = Process.pid - @thread = Thread.new { run } - end - - true - end - def stop(force = false) - debug { 'stopping agent' } - - mutex.synchronize do - @pid = nil - end - - # Kill the collector - Thread.kill(thread) if thread - - unless force - flush_traces - flush_metrics - end - workers.each_pair do |key, worker| worker.send(force ? :shutdown! : :shutdown) end true end - def fork - # noop - end - def notice(opts) opts.merge!(callbacks: self.class.callbacks) notice = Notice.new(config, opts) if !opts[:force] && notice.ignore? @@ -217,59 +160,19 @@ push(:notices, notice) notice.id end end - def trace(trace) - return false unless config.traces? - - start - - if trace.duration > config[:'traces.threshold'] - debug { sprintf('agent adding trace duration=%s feature=traces id=%s', trace.duration.round(2), trace.id) } - mutex.synchronize { traces.push(trace) } - flush_traces if traces.flush? - true - else - debug { sprintf('agent discarding trace duration=%s feature=traces id=%s', trace.duration.round(2), trace.id) } - false - end - end - - def timing(*args, &block) - return false unless config.metrics? - - start - - mutex.synchronize { metrics.timing(*args, &block) } - flush_metrics if metrics.flush? - - true - end - - def increment(*args, &block) - return false unless config.metrics? - - start - - mutex.synchronize { metrics.increment(*args, &block) } - flush_metrics if metrics.flush? - - true - end - # Internal: Flush the workers. See Honeybadger#flush. # # block - an option block which is executed before flushing data. # # Returns value from block if block is given, otherwise true. def flush return true unless block_given? yield ensure - flush_metrics - flush_traces workers.values.each(&:flush) end private @@ -284,65 +187,12 @@ workers[feature].push(object) true end - def run - loop { work } - rescue Exception => e - error { - msg = "error in agent thread (shutting down) class=%s message=%s\n\t%s" - sprintf(msg, e.class, e.message.dump, Array(e.backtrace).join("\n\t")) - } - ensure - d { sprintf('stopping agent') } - end - - def work - flush_metrics if metrics.flush? - flush_traces if traces.flush? - sleep(delay) - rescue StandardError => e - error { - msg = "error in agent thread class=%s message=%s\n\t%s" - sprintf(msg, e.class, e.message.dump, Array(e.backtrace).join("\n\t")) - } - sleep(delay) - end - def init_workers @workers = Hash.new(NullWorker.new) workers[:notices] = Worker.new(config, :notices) - workers[:traces] = Worker.new(config, :traces) - workers[:metrics] = Worker.new(config, :metrics) - end - - def init_traces - @traces = Batch.new(config, :traces, max: 20, interval: config.debug? ? 10 : 60, collection: TraceCollection.new) - end - - def init_metrics - @metrics = MetricsCollector.new(config, config.debug? ? 10 : 60) - end - - def flush_metrics - mutex.synchronize do - if (count = metrics.size) > 0 - debug { sprintf('agent flushing metrics feature=metrics count=%d', count) } - end - metrics.chunk(100, &method(:push).to_proc.curry[:metrics]) - init_metrics - end - end - - def flush_traces - mutex.synchronize do - if (count = traces.size) > 0 - debug { sprintf('agent flushing traces feature=traces count=%d', count) } - end - push(:traces, traces) unless traces.empty? - init_traces - end end def notify_at_exit(ex) return unless ex return unless config[:'exceptions.notify_at_exit']