class NewRelic::LocalEnvironment

This class is responsible for determining the ‘dispatcher’ in use by the current process. The dispatcher might be a recognized web server such as unicorn or passenger, a background job processor such as resque or sidekiq, or nil for unknown.

Dispatcher detection is best-effort, and serves two purposes:

  1. For some dispatchers, we need to apply specific workarounds in order for the agent to work correctly.

  2. When reading logs, since multiple processes on a given host might write into the same log, it’s useful to be able to identify what kind of process a given PID mapped to.

Overriding the dispatcher is possible via the NEW_RELIC_DISPATCHER environment variable, but this should not generally be necessary unless you’re on a dispatcher that falls into category 1 above, and our detection logic isn’t working correctly.

If the environment can’t be determined, it will be set to nil.

NewRelic::LocalEnvironment should be accessed through NewRelic::Control#local_env (via the NewRelic::Control singleton).

Public Class Methods

new() click to toggle source
# File lib/new_relic/local_environment.rb, line 36
def initialize
  # Extend self with any submodules of LocalEnvironment.  These can override
  # the discover methods to discover new frameworks and dispatchers.
  NewRelic::LocalEnvironment.constants.each do |const|
    mod = NewRelic::LocalEnvironment.const_get(const)
    self.extend(mod) if mod.instance_of?(Module)
  end

  @discovered_dispatcher = nil
  discover_dispatcher
end

Public Instance Methods

discovered_dispatcher() click to toggle source
# File lib/new_relic/local_environment.rb, line 31
def discovered_dispatcher
  discover_dispatcher unless @discovered_dispatcher
  @discovered_dispatcher
end
executable() click to toggle source
# File lib/new_relic/local_environment.rb, line 212
def executable
  File.basename($0)
end
find_class_in_object_space(klass) click to toggle source

Runs through all the objects in ObjectSpace to find the first one that match the provided class

# File lib/new_relic/local_environment.rb, line 50
def find_class_in_object_space(klass)
  if NewRelic::LanguageSupport.object_space_usable?
    ObjectSpace.each_object(klass) do |x|
      return x
    end
  end
  return nil
end
to_s() click to toggle source

outputs a human-readable description

# File lib/new_relic/local_environment.rb, line 208
def to_s
  %Q(LocalEnvironment[#{";dispatcher=#{@discovered_dispatcher}" if @discovered_dispatcher}])
end

Private Instance Methods

check_for_delayed_job() click to toggle source
# File lib/new_relic/local_environment.rb, line 148
def check_for_delayed_job
  if $0 =~ /delayed_job$/ || (File.basename($0) == 'rake' && ARGV.include?('jobs:work'))
    @discovered_dispatcher = :delayed_job
  end
end
check_for_falcon() click to toggle source
# File lib/new_relic/local_environment.rb, line 144
def check_for_falcon
  @discovered_dispatcher = :falcon if defined?(::Falcon::Server) && File.basename($PROGRAM_NAME) == 'falcon'
end
check_for_fastcgi() click to toggle source
# File lib/new_relic/local_environment.rb, line 117
def check_for_fastcgi
  return unless defined?(::FCGI)

  @discovered_dispatcher = :fastcgi
end
check_for_glassfish() click to toggle source
# File lib/new_relic/local_environment.rb, line 92
def check_for_glassfish
  return unless defined?(::JRuby) &&
    (((com.sun.grizzly.jruby.rack.DefaultRackApplicationFactory rescue nil) &&
      defined?(com::sun::grizzly::jruby::rack::DefaultRackApplicationFactory)) ||
     (jruby_rack? && defined?(::GlassFish::Server)))

  @discovered_dispatcher = :glassfish
end
check_for_litespeed() click to toggle source
# File lib/new_relic/local_environment.rb, line 187
def check_for_litespeed
  return unless caller.pop.include?('fcgi-bin/RailsRunner.rb')

  @discovered_dispatcher = :litespeed
end
check_for_mongrel() click to toggle source

this case covers starting by mongrel_rails

# File lib/new_relic/local_environment.rb, line 124
def check_for_mongrel
  return unless defined?(::Mongrel) && defined?(::Mongrel::HttpServer)

  @discovered_dispatcher = :mongrel
end
check_for_passenger() click to toggle source
# File lib/new_relic/local_environment.rb, line 193
def check_for_passenger
  return unless defined?(::PhusionPassenger)

  @discovered_dispatcher = :passenger
end
check_for_puma() click to toggle source
# File lib/new_relic/local_environment.rb, line 138
def check_for_puma
  return unless defined?(::Puma) && File.basename($0) == 'puma'

  @discovered_dispatcher = :puma
end
check_for_resque() click to toggle source
# File lib/new_relic/local_environment.rb, line 154
def check_for_resque
  has_queue = ENV['QUEUE'] || ENV['QUEUES']
  resque_rake = executable == 'rake' && ARGV.include?('resque:work')
  resque_pool_rake = executable == 'rake' && ARGV.include?('resque:pool')
  resque_pool_executable = executable == 'resque-pool' && defined?(::Resque::Pool)

  using_resque = defined?(::Resque) &&
    (has_queue && resque_rake) ||
    (resque_pool_executable || resque_pool_rake)

  @discovered_dispatcher = :resque if using_resque
end
check_for_serverless() click to toggle source
# File lib/new_relic/local_environment.rb, line 199
def check_for_serverless
  return unless NewRelic::Agent.config[:'serverless_mode.enabled']

  @discovered_dispatcher = :serverless
end
check_for_sidekiq() click to toggle source
# File lib/new_relic/local_environment.rb, line 167
def check_for_sidekiq
  if defined?(::Sidekiq) && File.basename($0) == 'sidekiq'
    @discovered_dispatcher = :sidekiq
  end
end
check_for_thin() click to toggle source
# File lib/new_relic/local_environment.rb, line 173
def check_for_thin
  if defined?(::Thin) && defined?(::Thin::Server)
    # If ObjectSpace is available, use it to search for a Thin::Server
    # instance. Otherwise, just the presence of the constant is sufficient.
    if NewRelic::LanguageSupport.object_space_usable?
      ObjectSpace.each_object(Thin::Server) do |thin_dispatcher|
        @discovered_dispatcher = :thin
      end
    else
      @discovered_dispatcher = :thin
    end
  end
end
check_for_torquebox() click to toggle source
# File lib/new_relic/local_environment.rb, line 85
def check_for_torquebox
  return unless defined?(::JRuby) &&
    (org.torquebox::TorqueBox rescue nil)

  @discovered_dispatcher = :torquebox
end
check_for_trinidad() click to toggle source
# File lib/new_relic/local_environment.rb, line 101
def check_for_trinidad
  return unless defined?(::JRuby) && jruby_rack? && defined?(::Trinidad::Server)

  @discovered_dispatcher = :trinidad
end
check_for_unicorn() click to toggle source
# File lib/new_relic/local_environment.rb, line 130
def check_for_unicorn
  return unless (defined?(::Unicorn) && defined?(::Unicorn::HttpServer)) &&
    NewRelic::LanguageSupport.object_space_usable?

  v = find_class_in_object_space(::Unicorn::HttpServer)
  @discovered_dispatcher = :unicorn if v
end
check_for_webrick() click to toggle source
# File lib/new_relic/local_environment.rb, line 111
def check_for_webrick
  return unless defined?(::WEBrick) && defined?(::WEBrick::VERSION)

  @discovered_dispatcher = :webrick
end
discover_dispatcher() click to toggle source
# File lib/new_relic/local_environment.rb, line 61
def discover_dispatcher
  dispatchers = %w[
    serverless
    puma
    sidekiq
    falcon
    delayed_job
    unicorn
    passenger
    resque
    torquebox
    trinidad
    glassfish
    thin
    mongrel
    litespeed
    webrick
    fastcgi
  ]
  while dispatchers.any? && @discovered_dispatcher.nil?
    send('check_for_' + (dispatchers.shift))
  end
end
jruby_rack?() click to toggle source
# File lib/new_relic/local_environment.rb, line 107
def jruby_rack?
  defined?(JRuby::Rack::VERSION)
end