class Mmtrix::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 MM_TRIX_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.

Mmtrix::LocalEnvironment should be accessed through Mmtrix::Control#env (via the Mmtrix::Control singleton).

Public Class Methods

new() click to toggle source
# File lib/mmtrix/local_environment.rb, line 36
def initialize
  # Extend self with any any submodules of LocalEnvironment.  These can override
  # the discover methods to discover new framworks and dispatchers.
  Mmtrix::LocalEnvironment.constants.each do | const |
    mod = Mmtrix::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/mmtrix/local_environment.rb, line 31
def discovered_dispatcher
  discover_dispatcher unless @discovered_dispatcher
  @discovered_dispatcher
end
executable() click to toggle source
# File lib/mmtrix/local_environment.rb, line 202
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/mmtrix/local_environment.rb, line 50
def find_class_in_object_space(klass)
  if Mmtrix::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/mmtrix/local_environment.rb, line 196
def to_s
  s = "LocalEnvironment["
  s << ";dispatcher=#{@discovered_dispatcher}" if @discovered_dispatcher
  s << "]"
end

Private Instance Methods

check_for_delayed_job() click to toggle source
# File lib/mmtrix/local_environment.rb, line 143
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_fastcgi() click to toggle source
# File lib/mmtrix/local_environment.rb, line 112
def check_for_fastcgi
  return unless defined?(::FCGI)
  @discovered_dispatcher = :fastcgi
end
check_for_glassfish() click to toggle source
# File lib/mmtrix/local_environment.rb, line 90
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/mmtrix/local_environment.rb, line 182
def check_for_litespeed
  if caller.pop =~ /fcgi-bin\/RailsRunner\.rb/
    @discovered_dispatcher = :litespeed
  end
end
check_for_mongrel() click to toggle source

this case covers starting by mongrel_rails

# File lib/mmtrix/local_environment.rb, line 118
def check_for_mongrel
  return unless defined?(::Mongrel) && defined?(::Mongrel::HttpServer)
  @discovered_dispatcher = :mongrel
end
check_for_passenger() click to toggle source
# File lib/mmtrix/local_environment.rb, line 188
def check_for_passenger
  if defined?(::PhusionPassenger)
    @discovered_dispatcher = :passenger
  end
end
check_for_puma() click to toggle source
# File lib/mmtrix/local_environment.rb, line 137
def check_for_puma
  if defined?(::Puma) && File.basename($0) == 'puma'
    @discovered_dispatcher = :puma
  end
end
check_for_rainbows() click to toggle source
# File lib/mmtrix/local_environment.rb, line 130
def check_for_rainbows
  if (defined?(::Rainbows) && defined?(::Rainbows::HttpServer)) && Mmtrix::LanguageSupport.object_space_usable?
    v = find_class_in_object_space(::Rainbows::HttpServer)
    @discovered_dispatcher = :rainbows if v
  end
end
check_for_resque() click to toggle source
# File lib/mmtrix/local_environment.rb, line 149
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_sidekiq() click to toggle source
# File lib/mmtrix/local_environment.rb, line 162
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/mmtrix/local_environment.rb, line 168
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 Mmtrix::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/mmtrix/local_environment.rb, line 84
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/mmtrix/local_environment.rb, line 98
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/mmtrix/local_environment.rb, line 123
def check_for_unicorn
  if (defined?(::Unicorn) && defined?(::Unicorn::HttpServer)) && Mmtrix::LanguageSupport.object_space_usable?
    v = find_class_in_object_space(::Unicorn::HttpServer)
    @discovered_dispatcher = :unicorn if v
  end
end
check_for_webrick() click to toggle source
# File lib/mmtrix/local_environment.rb, line 107
def check_for_webrick
  return unless defined?(::WEBrick) && defined?(::WEBrick::VERSION)
  @discovered_dispatcher = :webrick
end
discover_dispatcher() click to toggle source
# File lib/mmtrix/local_environment.rb, line 61
def discover_dispatcher
  dispatchers = %w[
    passenger
    torquebox
    trinidad
    glassfish
    resque
    sidekiq
    delayed_job
    puma
    thin
    mongrel
    litespeed
    webrick
    fastcgi
    rainbows
    unicorn
  ]
  while dispatchers.any? && @discovered_dispatcher.nil?
    send 'check_for_'+(dispatchers.shift)
  end
end
jruby_rack?() click to toggle source
# File lib/mmtrix/local_environment.rb, line 103
def jruby_rack?
  defined?(JRuby::Rack::VERSION)
end