module OneApm::Agent::Agent::Start
Public Instance Methods
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
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
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
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
# 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
# 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
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
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
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
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
# File lib/one_apm/agent/agent/start.rb, line 181 def in_resque_child_process? @service.is_a?(OneApm::Collector::ForkedProcessService) end
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
# File lib/one_apm/agent/agent/start.rb, line 219 def log_app_name OneApm::Manager.logger.info "Application: #{Manager.config.app_name}" end
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 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
# 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 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
# 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
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
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
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
True if we have initialized and completed 'start'
# File lib/one_apm/agent/agent/start.rb, line 36 def started? @started end
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
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
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
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