module OneApm::Agent::Agent::Start

Public Instance Methods

already_started?() click to toggle source

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

# File lib/one_apm/agent/agent/start.rb, line 41
def already_started?
  if started?
    OneApm::Manager.logger.error("Agent Started Already!")
    true
  end
end
app_name_configured?() click to toggle source

Logs the configured application names

# File lib/one_apm/agent/agent/start.rb, line 77
def app_name_configured?
  app_name = OneApm::Manager.config.app_name
  return app_name.respond_to?(:empty?) && !app_name.empty?
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/one_apm/agent/agent/start.rb, line 11
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/one_apm/agent/agent/start.rb, line 93
def connect_in_foreground
  OneApm::Manager.disable_all_tracing { connect(:keep_retrying => false) }
end
defer_for_background_jobs?() click to toggle source
# File lib/one_apm/agent/agent/start.rb, line 151
def defer_for_background_jobs?
  if defer_for_delayed_job?
    OneApm::Manager.logger.debug "Deferring startup for DelayedJob"
    return true
  end

  if defer_for_resque?
    OneApm::Manager.logger.debug "Deferring startup for Resque in case it daemonizes"
    return true
  end

  false
end
defer_for_delayed_job?() click to toggle source
# File lib/one_apm/agent/agent/start.rb, line 167
def defer_for_delayed_job?
  OneApm::Manager.config[:dispatcher] == :delayed_job &&
    !OneApm::DelayedJobInjection.worker_name
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/one_apm/agent/agent/start.rb, line 175
def defer_for_resque?
  OneApm::Manager.config[:dispatcher] == :resque &&
    OneApm::LanguageSupport.can_fork? &&
    !OneApm::Support::ForkedProcessChannel.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/one_apm/agent/agent/start.rb, line 72
def disabled?
  !Manager.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/one_apm/agent/agent/start.rb, line 135
def has_correct_license_key?
  has_license_key?
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/one_apm/agent/agent/start.rb, line 124
def has_license_key?
  if OneApm::Manager.config[:license_key] && OneApm::Manager.config[:license_key].length > 0
    true
  else
    OneApm::Manager.logger.warn("No license key found. " +
      "This often means your oneapm.yml file was not found, or it lacks a section for the running environment, '#{OneApm::Probe.instance.env}'. You may also want to try linting your oneapm.yml to ensure it is valid YML.")
    false
  end
end
in_resque_child_process?() click to toggle source
# File lib/one_apm/agent/agent/start.rb, line 181
def in_resque_child_process?
  @service.is_a?(OneApm::Collector::ForkedProcessService)
end
install_exit_handler() click to toggle source

Installs our exit handler, which exploits the weird behavior of at_exit blocks to make sure it runs last, by doing an at_exit within an at_exit block.

# File lib/one_apm/agent/agent/start.rb, line 51
def install_exit_handler
  if OneApm::Manager.config[:send_data_on_exit] && !weird_ruby?
    at_exit do
      # Workaround for MRI 1.9 bug that loses exit codes in at_exit blocks.
      # This is necessary to get correct exit codes for the agent's
      # test suites.
      # http://bugs.ruby-lang.org/issues/5218
      if defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby" && RUBY_VERSION.match(/^1\.9/)
        exit_status = $!.status if $!.is_a?(SystemExit)
        shutdown
        exit exit_status if exit_status
      else
        shutdown
      end
    end
  end
end
log_app_name() click to toggle source
# File lib/one_apm/agent/agent/start.rb, line 219
def log_app_name
  OneApm::Manager.logger.info "Application: #{Manager.config.app_name}"
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/one_apm/agent/agent/start.rb, line 209
def log_dispatcher
  dispatcher_name = OneApm::Manager.config[:dispatcher].to_s

  if dispatcher_name.empty?
    OneApm::Manager.logger.info 'No known dispatcher detected.'
  else
    OneApm::Manager.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/one_apm/agent/agent/start.rb, line 202
def log_environment
  OneApm::Manager.logger.info "Environment: #{OneApm::Probe.instance.env}"
end
log_ignore_url_regexes() click to toggle source
# File lib/one_apm/agent/agent/start.rb, line 228
def log_ignore_url_regexes
  regexes = OneApm::Manager.config[:'rules.ignore_url_regexes']

  unless regexes.empty?
    OneApm::Manager.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/one_apm/agent/agent/start.rb, line 186
def log_startup
  log_environment
  log_dispatcher
  log_app_name
  log_tier_name
end
log_tier_name() click to toggle source
# File lib/one_apm/agent/agent/start.rb, line 223
def log_tier_name
  OneApm::Manager.logger.info "Tiername: #{Manager.config.tier_names.join(", ")}"
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/one_apm/agent/agent/start.rb, line 196
def log_version_and_pid
  OneApm::Manager.logger.debug "OneApm Ruby Agent #{OneApm::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/one_apm/agent/agent/start.rb, line 113
def monitoring?
  if OneApm::Manager.config[:monitor_mode]
    true
  else
    OneApm::Manager.logger.warn('Agent configured not to send data in this environment.')
    false
  end
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/one_apm/agent/agent/start.rb, line 21
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 OneApm::Manager.config[:disable_samplers]
  end

  connect_in_foreground if OneApm::Manager.config[:sync_startup]
  start_worker_thread(options)
end
started?() click to toggle source

True if we have initialized and completed 'start'

# File lib/one_apm/agent/agent/start.rb, line 36
def started?
  @started
end
tier_name_configured?() click to toggle source

Logs the configured application tier names

# File lib/one_apm/agent/agent/start.rb, line 83
def tier_name_configured?
  tier_names = OneApm::Manager.config.tier_names
  return tier_names.respond_to?(:any?) && tier_names.any?
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/one_apm/agent/agent/start.rb, line 142
def using_forking_dispatcher?
  if [:puma, :passenger, :rainbows, :unicorn].include? OneApm::Manager.config[:dispatcher]
    OneApm::Manager.logger.info "Deferring startup of agent reporting thread because #{Manager.config[:dispatcher]} may fork."
    true
  else
    false
  end
end
using_sinatra?() click to toggle source

If we're using sinatra, old versions run in an at_exit block so we should probably know that

# File lib/one_apm/agent/agent/start.rb, line 99
def using_sinatra?
  defined?(Sinatra::Application)
end
weird_ruby?() click to toggle source

we should not set an at_exit block if people are using these as they don't do standard at_exit behavior per MRI/YARV

# File lib/one_apm/agent/agent/start.rb, line 105
def weird_ruby?
  OneApm::LanguageSupport.using_engine?('rbx') ||
    OneApm::LanguageSupport.using_engine?('jruby') ||
    using_sinatra?
end