class ElasticAPM::Agent
@api private
rubocop:disable Metrics/ClassLength
def self.instance # rubocop:disable Style/TrivialAccessors
def self.instance # rubocop:disable Style/TrivialAccessors @instance end
def self.running?
def self.running? !!@instance end
def self.start(config) # rubocop:disable Metrics/MethodLength
def self.start(config) # rubocop:disable Metrics/MethodLength return @instance if @instance config = Config.new(config) unless config.is_a?(Config) unless config.enabled_environments.include?(config.environment) puts format( '%sNot tracking anything in "%s" env', Log::PREFIX, config.environment ) return end LOCK.synchronize do return @instance if @instance @instance = new(config).start end end
def self.stop
def self.stop LOCK.synchronize do return unless @instance @instance.stop @instance = nil end end
def add_filter(key, callback)
def add_filter(key, callback) @http.filters.add(key, callback) end
def boot_worker
def boot_worker debug 'Booting worker' @worker_thread = Thread.new do TimedWorker.new( config, messages, pending_transactions, http ).run_forever end end
def build_context(rack_env)
def build_context(rack_env) @context_builder.build(rack_env) end
def current_transaction
def current_transaction instrumenter.current_transaction end
def enqueue_error(error)
def enqueue_error(error) boot_worker unless worker_running? messages.push(TimedWorker::ErrorMsg.new(error)) end
def enqueue_transaction(transaction)
def enqueue_transaction(transaction) boot_worker unless worker_running? pending_transactions.push(transaction) end
def initialize(config)
def initialize(config) @config = config @messages = Queue.new @pending_transactions = Queue.new @http = Http.new(config) @instrumenter = Instrumenter.new(config, self) @context_builder = ContextBuilder.new(config) @error_builder = ErrorBuilder.new(config) end
def inspect
def inspect '<ElasticAPM::Agent>' end
def kill_worker
def kill_worker messages << TimedWorker::StopMsg.new if @worker_thread && !@worker_thread.join(5) # 5 secs raise 'Failed to wait for worker, not all messages sent' end @worker_thread = nil end
def report(exception, handled: true)
def report(exception, handled: true) return if config.filter_exception_types.include?(exception.class.to_s) error = @error_builder.build_exception( exception, handled: handled ) enqueue_error error end
def report_message(message, backtrace: nil, **attrs)
def report_message(message, backtrace: nil, **attrs) error = @error_builder.build_log( message, backtrace: backtrace, **attrs ) enqueue_error error end
def set_custom_context(*args)
def set_custom_context(*args) instrumenter.set_custom_context(*args) end
def set_tag(*args)
def set_tag(*args) instrumenter.set_tag(*args) end
def set_user(*args)
def set_user(*args) instrumenter.set_user(*args) end
def span(*args, &block)
def span(*args, &block) instrumenter.span(*args, &block) end
def start
def start debug '[%s] Starting agent, reporting to %s', VERSION, config.server_url @instrumenter.start config.enabled_injectors.each do |lib| require "elastic_apm/injectors/#{lib}" end self end
def stop
def stop @instrumenter.stop kill_worker self end
def transaction(*args, &block)
def transaction(*args, &block) instrumenter.transaction(*args, &block) end
def worker_running?
def worker_running? @worker_thread && @worker_thread.alive? end