class ElasticAPM::Agent

@api private
rubocop:disable Metrics/ClassLength

def self.instance # rubocop:disable Style/TrivialAccessors

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)
  return @instance if @instance
  config = Config.new(config) unless config.is_a?(Config)
  LOCK.synchronize do
    return @instance if @instance
    unless config.active?
      config.logger.debug format(
        '%sAgent disabled with active: false',
        Logging::PREFIX
      )
      return
    end
    @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)
  transport.add_filter(key, callback)
end

def build_context(rack_env)

def build_context(rack_env)
  @context_builder.build(rack_env)
end

def current_span

def current_span
  instrumenter.current_span
end

def current_transaction

def current_transaction
  instrumenter.current_transaction
end

def end_span

def end_span
  instrumenter.end_span
end

def end_transaction(result = nil)

def end_transaction(result = nil)
  instrumenter.end_transaction(result)
end

def enqueue(obj)

def enqueue(obj)
  transport.submit obj
end

def initialize(config)

def initialize(config)
  @config = config
  @stacktrace_builder = StacktraceBuilder.new(config)
  @context_builder = ContextBuilder.new(config)
  @error_builder = ErrorBuilder.new(self)
  @transport = Transport::Base.new(config)
  @instrumenter = Instrumenter.new(
    config,
    stacktrace_builder: stacktrace_builder
  ) { |event| enqueue event }
  @metrics = Metrics.new(config) { |event| enqueue event }
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
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
end

def set_custom_context(context)

def set_custom_context(context)
  instrumenter.set_custom_context(context)
end

def set_tag(key, value)

def set_tag(key, value)
  instrumenter.set_tag(key, value)
end

def set_user(user)

def set_user(user)
  instrumenter.set_user(user)
end

def start

def start
  info '[%s] Starting agent, reporting to %s', VERSION, config.server_url
  transport.start
  instrumenter.start
  metrics.start
  config.enabled_spies.each do |lib|
    require "elastic_apm/spies/#{lib}"
  end
  self
end

def start_span(

def start_span(
  name = nil,
  type = nil,
  backtrace: nil,
  context: nil,
  trace_context: nil
)
  instrumenter.start_span(
    name,
    type,
    backtrace: backtrace,
    context: context,
    trace_context: trace_context
  )
end

def start_transaction(

def start_transaction(
  name = nil,
  type = nil,
  context: nil,
  trace_context: nil
)
  instrumenter.start_transaction(
    name,
    type,
    context: context,
    trace_context: trace_context
  )
end

def stop

def stop
  debug 'Stopping agent'
  instrumenter.stop
  transport.stop
  metrics.stop
  self
end