module NewRelic::Agent::Agent::InstanceMethods::Connect

This module is an artifact of a refactoring of the connect method - all of its methods are used in that context, so it can be refactored at will. It should be fully tested

Attributes

connect_attempts[RW]

number of attempts we've made to contact the server

Public Instance Methods

apdex_f() click to toggle source

#apdex_f is always 4 times the apdex_t

# File lib/new_relic/agent/agent.rb, line 846
def apdex_f
  (4 * Agent.config[:apdex_t]).to_f
end
connect_retry_period() click to toggle source

Retry period is a minute for each failed attempt that we've made. This should probably do some sort of sane TCP backoff to prevent hammering the server, but a minute for each attempt seems to work reasonably well.

# File lib/new_relic/agent/agent.rb, line 758
def connect_retry_period
  [600, connect_attempts * 60].min
end
connect_settings() click to toggle source

Initializes the hash of settings that we send to the server. Returns a literal hash containing the options

# File lib/new_relic/agent/agent.rb, line 817
def connect_settings
  sanitize_environment_report

  settings = {
    :pid => $$,
    :host => local_host,
    :display_host => Agent.config[:'process_host.display_name'],
    :app_name => Agent.config.app_names,
    :language => 'ruby',
    :labels => Agent.config.parsed_labels,
    :agent_version => NewRelic::VERSION::STRING,
    :environment => @environment_report,
    :settings => Agent.config.to_collector_hash,
    :high_security => Agent.config[:high_security]
  }

  unless Agent.config[:disable_utilization]
    settings[:utilization] = UtilizationData.new.to_collector_hash
  end

  settings
end
connect_to_server() click to toggle source

Returns connect data passed back from the server

# File lib/new_relic/agent/agent.rb, line 841
def connect_to_server
  @service.connect(connect_settings)
end
connected?() click to toggle source
# File lib/new_relic/agent/agent.rb, line 739
def connected?
  @connect_state == :connected
end
disconnect() click to toggle source

Disconnect just sets connected to false, which prevents the agent from trying to connect again

# File lib/new_relic/agent/agent.rb, line 734
def disconnect
  @connect_state = :disconnected
  true
end
disconnected?() click to toggle source
# File lib/new_relic/agent/agent.rb, line 743
def disconnected?
  @connect_state == :disconnected
end
environment_for_connect() click to toggle source

Checks whether we should send environment info, and if so, returns the snapshot from the local environment. Generating the EnvironmentReport has the potential to trigger require calls in Rails environments, so this method should only be called synchronously from on the main thread.

# File lib/new_relic/agent/agent.rb, line 802
def environment_for_connect
  Agent.config[:send_environment_info] ? Array(EnvironmentReport.new) : []
end
finish_setup(config_data) click to toggle source

Takes a hash of configuration data returned from the server and uses it to set local variables and to initialize various parts of the agent that are configured separately.

Can accommodate most arbitrary data - anything extra is ignored unless we say to do something with it here.

# File lib/new_relic/agent/agent.rb, line 863
def finish_setup(config_data)
  return if config_data == nil

  @service.agent_id = config_data['agent_run_id']

  if config_data['agent_config']
    ::NewRelic::Agent.logger.debug "Using config from server"
  end

  ::NewRelic::Agent.logger.debug "Server provided config: #{config_data.inspect}"
  server_config = NewRelic::Agent::Configuration::ServerSource.new(config_data, Agent.config)
  Agent.config.replace_or_add_config(server_config)
  log_connection!(config_data)

  @transaction_rules = RulesEngine.create_transaction_rules(config_data)
  @stats_engine.metric_rules = RulesEngine.create_metric_rules(config_data)

  # If you're adding something else here to respond to the server-side config,
  # use Agent.instance.events.subscribe(:finished_configuring) callback instead!
end
generate_environment_report() click to toggle source
# File lib/new_relic/agent/agent.rb, line 793
def generate_environment_report
  @environment_report = environment_for_connect
end
handle_license_error(error) click to toggle source

When the server sends us an error with the license key, we want to tell the user that something went wrong, and let them know where to go to get a valid license key

After this runs, it disconnects the agent so that it will no longer try to connect to the server, saving the application and the server load

# File lib/new_relic/agent/agent.rb, line 780
def handle_license_error(error)
  ::NewRelic::Agent.logger.error(                error.message,                "Visit NewRelic.com to obtain a valid license key, or to upgrade your account.")
  disconnect
end
handle_unrecoverable_agent_error(error) click to toggle source
# File lib/new_relic/agent/agent.rb, line 787
def handle_unrecoverable_agent_error(error)
  ::NewRelic::Agent.logger.error(error.message)
  disconnect
  shutdown
end
log_collector_messages(messages) click to toggle source
# File lib/new_relic/agent/agent.rb, line 919
def log_collector_messages(messages)
  messages.each do |message|
    ::NewRelic::Agent.logger.send(message['level'].downcase, message['message'])
  end
end
log_connection!(config_data) click to toggle source

Logs when we connect to the server, for debugging purposes

  • makes sure we know if an agent has not connected

# File lib/new_relic/agent/agent.rb, line 910
def log_connection!(config_data)
  ::NewRelic::Agent.logger.debug "Connected to NewRelic Service at #{@service.collector.name}"
  ::NewRelic::Agent.logger.debug "Agent Run       = #{@service.agent_id}."
  ::NewRelic::Agent.logger.debug "Connection data = #{config_data.inspect}"
  if config_data['messages'] && config_data['messages'].any?
    log_collector_messages(config_data['messages'])
  end
end
log_error(error) click to toggle source

When we have a problem connecting to the server, we need to tell the user what happened, since this is not an error we can handle gracefully.

# File lib/new_relic/agent/agent.rb, line 769
def log_error(error)
  ::NewRelic::Agent.logger.error "Error establishing connection with New Relic Service at #{control.server}:", error
end
note_connect_failure() click to toggle source
# File lib/new_relic/agent/agent.rb, line 762
def note_connect_failure
  self.connect_attempts += 1
end
query_server_for_configuration() click to toggle source

Sets the collector host and connects to the server, then invokes the final configuration with the returned data

# File lib/new_relic/agent/agent.rb, line 852
def query_server_for_configuration
  finish_setup(connect_to_server)
end
sanitize_environment_report() click to toggle source

We've seen objects in the environment report (Rails.env in particular) that can't seralize to JSON. Cope with that here and clear out so downstream code doesn't have to check again.

# File lib/new_relic/agent/agent.rb, line 809
def sanitize_environment_report
  if !@service.valid_to_marshal?(@environment_report)
    @environment_report = []
  end
end
should_connect?(force=false) click to toggle source

Don't connect if we're already connected, or if we tried to connect and were rejected with prejudice because of a license issue, unless we're forced to by force_reconnect.

# File lib/new_relic/agent/agent.rb, line 750
def should_connect?(force=false)
  force || (!connected? && !disconnected?)
end
signal_connected() click to toggle source
# File lib/new_relic/agent/agent.rb, line 892
def signal_connected
  @wait_on_connect_writer << "."
end
wait_on_connect(timeout) click to toggle source
# File lib/new_relic/agent/agent.rb, line 896
def wait_on_connect(timeout)
  return if connected?

  @waited_on_connect = true
  NewRelic::Agent.logger.debug("Waiting on connect to complete.")
  IO.select([@wait_on_connect_reader], nil, nil, timeout)

  unless connected?
    raise WaitOnConnectTimeout, "Agent was unable to connect in #{timeout} seconds."
  end
end
waited_on_connect?() click to toggle source

Used for testing to let us know we've actually started to wait

# File lib/new_relic/agent/agent.rb, line 888
def waited_on_connect?
  @waited_on_connect
end