module Mmtrix::Agent::Agent::InstanceMethods::Start

Herein lies the corpse of the former ‘start’ method. May its unmatched flog score rest in pieces.

Public Instance Methods

already_started?() click to toggle source

Check whether we have already started, which is an error condition

# File lib/mmtrix/agent/agent.rb, line 282
def already_started?
  if started?
    ::Mmtrix::Agent.logger.error("Agent Started Already!")
    true
  end
end
app_name_configured?() click to toggle source

Logs the configured application names

# File lib/mmtrix/agent/agent.rb, line 335
def app_name_configured?
  names = Agent.config.app_names
  return names.respond_to?(:any?) && names.any?
end
check_config_and_start_agent() click to toggle source

Sanity-check the agent configuration and start the agent, setting up the worker thread and the exit handler to shut down the agent

# File lib/mmtrix/agent/agent.rb, line 476
def check_config_and_start_agent
  return unless monitoring? && has_correct_license_key?
  return if using_forking_dispatcher?
  setup_and_start_agent
end
connect_in_foreground() click to toggle source

Connecting in the foreground blocks further startup of the agent until we have a connection - useful in cases where you’re trying to log a very-short-running process and want to get statistics from before a server connection (typically 20 seconds) exists

# File lib/mmtrix/agent/agent.rb, line 345
def connect_in_foreground
  Mmtrix::Agent.disable_all_tracing { connect(:keep_retrying => false) }
end
correct_license_length() click to toggle source

A license key is an arbitrary 40 character string, usually looks something like a SHA1 hash

# File lib/mmtrix/agent/agent.rb, line 436
def correct_license_length
  key = Agent.config[:license_key]

  true
  # if key.length == 40
  #   true
  # else
  #   ::Mmtrix::Agent.logger.error("Invalid license key: #{key}")
  #   false
  # end
end
defer_for_resque?() click to toggle source

Return true if we’re using resque and it hasn’t had a chance to (potentially) daemonize itself. This avoids hanging when there’s a Thread started before Resque calls Process.daemon (Jira RUBY-857)

# File lib/mmtrix/agent/agent.rb, line 463
def defer_for_resque?
  Mmtrix::Agent.config[:dispatcher] == :resque &&
    Mmtrix::LanguageSupport.can_fork? &&
    !Mmtrix::Agent::PipeChannelManager.listener.started?
end
disabled?() click to toggle source

The agent is disabled when it is not force enabled by the ‘agent_enabled’ option (e.g. in a manual start), or enabled normally through the configuration file

# File lib/mmtrix/agent/agent.rb, line 292
def disabled?
  !Agent.config[:agent_enabled]
end
has_correct_license_key?() click to toggle source

A correct license key exists and is of the proper length

# File lib/mmtrix/agent/agent.rb, line 430
def has_correct_license_key?
  has_license_key? && correct_license_length
end
has_license_key?() click to toggle source

Tell the user when the license key is missing so they can fix it by adding it to the file

# File lib/mmtrix/agent/agent.rb, line 419
def has_license_key?
  if Agent.config[:license_key] && Agent.config[:license_key].length > 0
    true
  else
    ::Mmtrix::Agent.logger.warn("No license key found. " +
      "This often means your mmtrix.yml file was not found, or it lacks a section for the running environment, '#{Mmtrix::Control.instance.env}'. You may also want to try linting your mmtrix.yml to ensure it is valid YML.")
    false
  end
end
in_resque_child_process?() click to toggle source
# File lib/mmtrix/agent/agent.rb, line 469
def in_resque_child_process?
  @service.is_a?(Mmtrix::Agent::PipeService)
end
install_exit_handler() click to toggle source
# File lib/mmtrix/agent/agent.rb, line 385
def install_exit_handler
  return unless should_install_exit_handler?
  Mmtrix::Agent.logger.debug("Installing at_exit handler")
  at_exit do
    if need_exit_code_workaround?
      exit_status = $!.status if $!.is_a?(SystemExit)
      shutdown
      exit exit_status if exit_status
    else
      shutdown
    end
  end
end
log_app_name() click to toggle source
# File lib/mmtrix/agent/agent.rb, line 322
def log_app_name
  ::Mmtrix::Agent.logger.info "Application: #{Agent.config.app_names.join(", ")}"
end
log_dispatcher() click to toggle source

Logs the dispatcher to the log file to assist with debugging. When no debugger is present, logs this fact to assist with proper dispatcher detection

# File lib/mmtrix/agent/agent.rb, line 312
def log_dispatcher
  dispatcher_name = Agent.config[:dispatcher].to_s

  if dispatcher_name.empty?
    ::Mmtrix::Agent.logger.info 'No known dispatcher detected.'
  else
    ::Mmtrix::Agent.logger.info "Dispatcher: #{dispatcher_name}"
  end
end
log_environment() click to toggle source

Log the environment the app thinks it’s running in. Useful in debugging, as this is the key for config YAML lookups.

# File lib/mmtrix/agent/agent.rb, line 305
def log_environment
  ::Mmtrix::Agent.logger.info "Environment: #{Mmtrix::Control.instance.env}"
end
log_ignore_url_regexes() click to toggle source
# File lib/mmtrix/agent/agent.rb, line 326
def log_ignore_url_regexes
  regexes = Mmtrix::Agent.config[:'rules.ignore_url_regexes']

  unless regexes.empty?
    ::Mmtrix::Agent.logger.info "Ignoring URLs that match the following regexes: #{regexes.map(&:inspect).join(", ")}."
  end
end
log_startup() click to toggle source

Log startup information that we almost always want to know

# File lib/mmtrix/agent/agent.rb, line 297
def log_startup
  log_environment
  log_dispatcher
  log_app_name
end
log_version_and_pid() click to toggle source

Classy logging of the agent version and the current pid, so we can disambiguate processes in the log file and make sure they’re running a reasonable version

# File lib/mmtrix/agent/agent.rb, line 402
def log_version_and_pid
  ::Mmtrix::Agent.logger.debug "Mmtrix Ruby Agent #{Mmtrix::VERSION::STRING} Initialized: pid = #{$$}"
end
monitoring?() click to toggle source

Warn the user if they have configured their agent not to send data, that way we can see this clearly in the log file

# File lib/mmtrix/agent/agent.rb, line 408
def monitoring?
  if Agent.config[:monitor_mode]
    true
  else
    ::Mmtrix::Agent.logger.warn('Agent configured not to send data in this environment.')
    false
  end
end
need_exit_code_workaround?() click to toggle source

There’s an MRI 1.9 bug that loses exit codes in at_exit blocks. A workaround is necessary to get correct exit codes for the agent’s test suites. bugs.ruby-lang.org/issues/5218

# File lib/mmtrix/agent/agent.rb, line 381
def need_exit_code_workaround?
  defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby" && RUBY_VERSION.match(/^1\.9/)
end
setup_and_start_agent(options={}) click to toggle source

This is the shared method between the main agent startup and the after_fork call restarting the thread in deferred dispatchers.

Treatment of @started and env report is important to get right.

# File lib/mmtrix/agent/agent.rb, line 486
def setup_and_start_agent(options={})
  @started = true
  @harvester.mark_started

  unless in_resque_child_process?
    generate_environment_report
    install_exit_handler
    @harvest_samplers.load_samplers unless Agent.config[:disable_samplers]
  end

  connect_in_foreground if Agent.config[:sync_startup]
  start_worker_thread(options)
end
should_install_exit_handler?() click to toggle source
# File lib/mmtrix/agent/agent.rb, line 368
def should_install_exit_handler?
  (
    Agent.config[:send_data_on_exit]                  &&
    !Mmtrix::LanguageSupport.using_engine?('rbx')   &&
    !Mmtrix::LanguageSupport.using_engine?('jruby') &&
    !sinatra_classic_app?
  )
end
sinatra_classic_app?() click to toggle source

This matters when the following three criteria are met:

  1. A Sinatra ‘classic’ application is being run

  2. The app is being run by executing the main file directly, rather than via a config.ru file.

  3. mmtrix_rpm is required after sinatra

In this case, the entire application runs from an at_exit handler in Sinatra, and if we were to install ours, it would be executed before the one in Sinatra, meaning that we’d shutdown the agent too early and never collect any data.

# File lib/mmtrix/agent/agent.rb, line 360
def sinatra_classic_app?
  (
    defined?(Sinatra::Application) &&
    Sinatra::Application.respond_to?(:run) &&
    Sinatra::Application.run?
  )
end
using_forking_dispatcher?() click to toggle source

If we’re using a dispatcher that forks before serving requests, we need to wait until the children are forked before connecting, otherwise the parent process sends useless data

# File lib/mmtrix/agent/agent.rb, line 451
def using_forking_dispatcher?
  if [:puma, :passenger, :rainbows, :unicorn].include? Agent.config[:dispatcher]
    ::Mmtrix::Agent.logger.info "Deferring startup of agent reporting thread because #{Agent.config[:dispatcher]} may fork."
    true
  else
    false
  end
end