module TingYun::Agent::InstanceMethods::Start

Public Instance Methods

after_fork(options={}) click to toggle source

This method should be called in a forked process after a fork. It assumes the parent process initialized the agent, but does not assume the agent started.

The call is idempotent, but not re-entrant.

  • It clears any metrics carried over from the parent process

  • Restarts the sampler thread if necessary

  • Initiates a new agent run and worker loop unless that was done in the parent process and :force_reconnect is not true

Options:

  • :force_reconnect => true to force the spawned process to establish a new connection, such as when forking a long running process. The default is false–it will only connect to the server if the parent had not connected.

  • :keep_retrying => false if we try to initiate a new connection, this tells me to only try it once so this method returns quickly if there is some kind of latency with the server.

# File lib/ting_yun/agent/instance_methods/start.rb, line 131
def after_fork(options={})
  needs_restart = false
  @after_fork_lock.synchronize do
    needs_restart = @dispatcher.needs_restart?
    @dispatcher.mark_started
  end

  return if !needs_restart ||
      !Agent.config[:'agent_enabled'] || disconnected?

  ::TingYun::Agent.logger.debug "Starting the worker thread in #{Process.pid} (parent #{Process.ppid}) after forking."

  # Clear out locks and stats left over from parent process
  reset_objects_with_locks
  drop_buffered_data

  setup_and_start_agent(options)
end
agent_should_start?() click to toggle source

Check to see if the agent should start, returning true if it should. should hava the vaild app_name, unstart-state and able to start 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/ting_yun/agent/instance_methods/start.rb, line 17
def agent_should_start?
  return false if already_started? || !TingYun::Agent.config[:'agent_enabled']
  unless app_name_configured?
    TingYun::Agent.logger.error "No application name configured.",
                       "The Agent cannot start without at least one. Please check your ",
                       "tingyun.yml and ensure that it is valid and has at least one ",
                       "value set for app_name in the",
                       "environment."
    return false
  end
  return true
end
already_started?() click to toggle source

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

# File lib/ting_yun/agent/instance_methods/start.rb, line 35
def already_started?
  if started?
    TingYun::Agent.logger.info("Agent Started Already!")
    true
  end
end
app_name_configured?() click to toggle source

Logs the configured application names

# File lib/ting_yun/agent/instance_methods/start.rb, line 67
def app_name_configured?
  names = TingYun::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/ting_yun/agent/instance_methods/start.rb, line 88
def check_config_and_start_agent
  return unless  has_correct_license_key?
  return if is_using_forking_dispatcher?
  setup_and_start_agent
end
has_correct_license_key?() click to toggle source

A correct license key exists and is of the proper length

# File lib/ting_yun/agent/instance_methods/start.rb, line 56
def has_correct_license_key?
  if TingYun::Agent.config[:license_key] && TingYun::Agent.config[:license_key].length > 0
    true
  else
    TingYun::Agent.logger.warn("No license key found. " +
                                   "This often means your tingyun.yml file was not found, or it lacks a section for the running environment,'#{::TingYun::Frameworks.framework.env}'. You may also want to try linting your tingyun.yml to ensure it is valid YML.")
    false
  end
end
is_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/ting_yun/agent/instance_methods/start.rb, line 76
def is_using_forking_dispatcher?
  if [:puma, :passenger, :rainbows, :unicorn].include? TingYun::Agent.config[:dispatcher]
    TingYun::Agent.logger.info "Deferring startup of agent reporting thread because #{TingYun::Agent.config[:dispatcher]} may fork."
    true
  else
    false
  end
end
log_startup() click to toggle source
# File lib/ting_yun/agent/instance_methods/start.rb, line 43
def log_startup
  Agent.logger.info "Environment: #{::TingYun::Frameworks.framework.env}" # log_environment
  dispatcher_name = TingYun::Agent.config[:dispatcher].to_s
  if dispatcher_name.empty?
    TingYun::Agent.logger.info 'No known dispatcher detected.'
  else
    TingYun::Agent.logger.info "Dispatcher: #{dispatcher_name}"
  end # log_dispatcher
  TingYun::Agent.logger.info "Application: #{TingYun::Agent.config.app_names.join(", ")}" # log_app_name
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/ting_yun/agent/instance_methods/start.rb, line 98
def setup_and_start_agent(options={})
  @started = true
  @dispatcher.mark_started
  generate_environment_report
  install_exit_handler
  @middleware.load_samplers # cpu and memory load

  if TingYun::Agent.config[:sync_startup]
    connect_in_sync
  else
    start_worker_thread(options)
  end
end
started?() click to toggle source
# File lib/ting_yun/agent/instance_methods/start.rb, line 30
def started?
  @started
end