Module: NewRelic::Agent::AgentHelpers::Harvest

Included in:
NewRelic::Agent::Agent
Defined in:
lib/new_relic/agent/agent_helpers/harvest.rb

Instance Method Summary collapse

Instance Method Details

#check_for_and_handle_agent_commandsObject


131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 131

def check_for_and_handle_agent_commands
  begin
    @agent_command_router.check_for_and_handle_agent_commands
  rescue ForceRestartException, ForceDisconnectException
    raise
  rescue UnrecoverableServerException => e
    NewRelic::Agent.agent.health_check.update_status(NewRelic::Agent::HealthCheck::FAILED_TO_CONNECT)
    NewRelic::Agent.logger.warn('get_agent_commands message was rejected by remote service, discarding. ' \
      'Error: ', e)
  rescue ServerConnectionException => e
    NewRelic::Agent.health_check.update_status(NewRelic::Agent::HealthCheck::FAILED_TO_CONNECT)
    log_remote_unavailable(:get_agent_commands, e)
  rescue => e
    NewRelic::Agent.logger.info('Error during check_for_and_handle_agent_commands, will retry later: ', e)
  end
end

#harvest_and_send_analytic_event_dataObject


81
82
83
84
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 81

def harvest_and_send_analytic_event_data
  harvest_and_send_from_container(transaction_event_aggregator, :analytic_event_data)
  harvest_and_send_from_container(synthetics_event_aggregator, :analytic_event_data)
end

#harvest_and_send_custom_event_dataObject


86
87
88
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 86

def harvest_and_send_custom_event_data
  harvest_and_send_from_container(@custom_event_aggregator, :custom_event_data)
end

#harvest_and_send_data_typesObject


102
103
104
105
106
107
108
109
110
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 102

def harvest_and_send_data_types
  harvest_and_send_errors
  harvest_and_send_error_event_data
  harvest_and_send_transaction_traces
  harvest_and_send_slowest_sql
  harvest_and_send_timeslice_data
  harvest_and_send_span_event_data
  harvest_and_send_log_event_data
end

#harvest_and_send_error_event_dataObject


90
91
92
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 90

def harvest_and_send_error_event_data
  harvest_and_send_from_container(@error_collector.error_event_aggregator, :error_event_data)
end

#harvest_and_send_errorsObject


77
78
79
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 77

def harvest_and_send_errors
  harvest_and_send_from_container(@error_collector.error_trace_aggregator, :error_data)
end

#harvest_and_send_for_agent_commandsObject


73
74
75
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 73

def harvest_and_send_for_agent_commands
  harvest_and_send_from_container(@agent_command_router, :profile_data)
end

#harvest_and_send_from_container(container, endpoint) ⇒ Object

Harvests data from the given container, sends it to the named endpoint on the service, and automatically merges back in upon a recoverable failure.

The given container should respond to:

#harvest!
  returns a payload that contains enumerable collection of data items and
  optional metadata to be sent to the collector.

#reset!
  drop any stored data and reset to a clean state.

#merge!(payload)
  merge the given payload back into the internal buffer of the
  container, so that it may be harvested again later.

26
27
28
29
30
31
32
33
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 26

def harvest_and_send_from_container(container, endpoint)
  payload = harvest_from_container(container, endpoint)
  sample_count = harvest_size(container, payload)
  if sample_count > 0
    NewRelic::Agent.logger.debug("Sending #{sample_count} items to #{endpoint}")
    send_data_to_endpoint(endpoint, payload, container)
  end
end

#harvest_and_send_log_event_dataObject


98
99
100
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 98

def harvest_and_send_log_event_data
  harvest_and_send_from_container(@log_event_aggregator, :log_event_data)
end

#harvest_and_send_slowest_sqlObject


59
60
61
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 59

def harvest_and_send_slowest_sql
  harvest_and_send_from_container(@sql_sampler, :sql_trace_data)
end

#harvest_and_send_span_event_dataObject


94
95
96
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 94

def harvest_and_send_span_event_data
  harvest_and_send_from_container(span_event_aggregator, :span_event_data)
end

#harvest_and_send_timeslice_dataObject


54
55
56
57
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 54

def harvest_and_send_timeslice_data
  TransactionTimeAggregator.harvest!
  harvest_and_send_from_container(@stats_engine, :metric_data)
end

#harvest_and_send_transaction_tracesObject

This handles getting the transaction traces and then sending them across the wire. This includes gathering SQL explanations, stripping out stack traces, and normalizing SQL. note that we explain only the sql statements whose nodes’ execution times exceed our threshold (to avoid unnecessary overhead of running explains on fast queries.)


69
70
71
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 69

def harvest_and_send_transaction_traces
  harvest_and_send_from_container(@transaction_sampler, :transaction_sample_data)
end

#harvest_from_container(container, endpoint) ⇒ Object


43
44
45
46
47
48
49
50
51
52
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 43

def harvest_from_container(container, endpoint)
  items = []
  begin
    items = container.harvest!
  rescue => e
    NewRelic::Agent.logger.error("Failed to harvest #{endpoint} data, resetting. Error: ", e)
    container.reset!
  end
  items
end

#harvest_size(container, items) ⇒ Object


35
36
37
38
39
40
41
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 35

def harvest_size(container, items)
  if container.respond_to?(:has_metadata?) && container.has_metadata? && !items.empty?
    items.last.size
  else
    items.size
  end
end

#log_remote_unavailable(endpoint, e) ⇒ Object


148
149
150
151
152
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 148

def log_remote_unavailable(endpoint, e)
  NewRelic::Agent.logger.debug("Unable to send #{endpoint} data, will try again later. Error: ", e)
  NewRelic::Agent.record_metric('Supportability/remote_unavailable', 0.0)
  NewRelic::Agent.record_metric("Supportability/remote_unavailable/#{endpoint.to_s}", 0.0)
end

#send_data_to_endpoint(endpoint, payload, container) ⇒ Object


112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/new_relic/agent/agent_helpers/harvest.rb', line 112

def send_data_to_endpoint(endpoint, payload, container)
  begin
    @service.send(endpoint, payload)
  rescue ForceRestartException, ForceDisconnectException
    raise
  rescue SerializationError => e
    NewRelic::Agent.logger.warn("Failed to serialize data for #{endpoint}, discarding. Error: ", e)
  rescue UnrecoverableServerException => e
    NewRelic::Agent.logger.warn("#{endpoint} data was rejected by remote service, discarding. Error: ", e)
  rescue ServerConnectionException => e
    NewRelic::Agent.agent.health_check.update_status(NewRelic::Agent::HealthCheck::FAILED_TO_CONNECT)
    log_remote_unavailable(endpoint, e)
    container.merge!(payload)
  rescue => e
    NewRelic::Agent.logger.info("Unable to send #{endpoint} data, will try again later. Error: ", e)
    container.merge!(payload)
  end
end