Class: NewRelic::Agent::NewRelicService
- Inherits:
-
Object
- Object
- NewRelic::Agent::NewRelicService
show all
- Defined in:
- lib/new_relic/agent/new_relic_service.rb,
lib/new_relic/agent/new_relic_service/encoders.rb,
lib/new_relic/agent/new_relic_service/marshaller.rb,
lib/new_relic/agent/new_relic_service/json_marshaller.rb,
lib/new_relic/agent/new_relic_service/security_policy_settings.rb more...
Defined Under Namespace
Modules: Encoders, SecurityPolicySettings
Classes: JsonMarshaller, Marshaller
Constant Summary
collapse
- PROTOCOL_VERSION =
Specifies the version of the agent’s communication protocol with the NewRelic hosted site.
17
- CONNECTION_ERRORS =
These include Errno connection errors, and all indicate that the underlying TCP connection may be in a bad state.
[Net::OpenTimeout, Net::ReadTimeout, EOFError, SystemCallError, SocketError]
- MAX_ATTEMPTS =
The maximum number of times to attempt an HTTP request
2
- MIN_BYTE_SIZE_TO_COMPRESS =
Don’t perform compression on the payload unless its uncompressed size is greater than or equal to this number of bytes. In testing with Ruby 2.2 - 3.1, we determined an absolute minimum value for ASCII to be 535 bytes to obtain at least a 10% savings in size. It is recommended that this value be kept above that 535 number. It is also important to consider the CPU cost involved with performing compression and to find a balance between CPU cycles spent and bandwidth saved. A good reasonable default here is 2048 bytes, which is a tried and true Apache Tomcat default (as of v8.5.78)
2048
Instance Attribute Summary collapse
Instance Method Summary
collapse
Constructor Details
permalink
#initialize(license_key = nil, collector = control.server) ⇒ NewRelicService
Returns a new instance of NewRelicService.
[View source]
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 46
def initialize(license_key = nil, collector = control.server)
@license_key = license_key
@collector = collector
@configured_collector = collector
@request_timeout = Agent.config[:timeout]
@ssl_cert_store = nil
@in_session = nil
@agent_id = nil
@shared_tcp_connection = nil
@request_headers_map = nil
reset_remote_method_uris
prep_audit_logger
prep_marshaller
end
|
Instance Attribute Details
permalink
#agent_id ⇒ Object
Returns the value of attribute agent_id.
44
45
46
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 44
def agent_id
@agent_id
end
|
permalink
#collector ⇒ Object
Returns the value of attribute collector.
44
45
46
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 44
def collector
@collector
end
|
permalink
#marshaller ⇒ Object
Returns the value of attribute marshaller.
44
45
46
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 44
def marshaller
@marshaller
end
|
permalink
#request_timeout ⇒ Object
Returns the value of attribute request_timeout.
43
44
45
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 43
def request_timeout
@request_timeout
end
|
Instance Method Details
permalink
#agent_command_results(results) ⇒ Object
[View source]
185
186
187
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 185
def agent_command_results(results)
invoke_remote(:agent_command_results, [@agent_id, results])
end
|
permalink
#analytic_event_data(data) ⇒ Object
[View source]
189
190
191
192
193
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 189
def analytic_event_data(data)
_, items = data
invoke_remote(:analytic_event_data, [@agent_id, *data],
:item_count => items.size)
end
|
permalink
#build_metric_data_array(stats_hash) ⇒ Object
The collector wants to receive metric data in a format that’s different from how we store it internally, so this method handles the translation.
[View source]
134
135
136
137
138
139
140
141
142
143
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 134
def build_metric_data_array(stats_hash)
metric_data_array = []
stats_hash.each do |metric_spec, stats|
unless stats.is_reset?
metric_data_array << NewRelic::MetricData.new(metric_spec, stats)
end
end
metric_data_array
end
|
permalink
#cert_file_path ⇒ Object
The path to the certificate file used to verify the SSL connection if verify_peer is enabled
[View source]
385
386
387
388
389
390
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 385
def cert_file_path
if path_override = NewRelic::Agent.config[:ca_bundle_path]
NewRelic::Agent.logger.warn("Couldn't find CA bundle from configured ca_bundle_path: #{path_override}") unless File.exist?(path_override)
path_override
end
end
|
permalink
#close_shared_connection ⇒ Object
[View source]
277
278
279
280
281
282
283
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 277
def close_shared_connection
if @shared_tcp_connection
::NewRelic::Agent.logger.debug("Closing shared TCP connection to #{@shared_tcp_connection.address}:#{@shared_tcp_connection.port}")
@shared_tcp_connection.finish if @shared_tcp_connection.started?
@shared_tcp_connection = nil
end
end
|
permalink
#connect(settings = {}) ⇒ Object
[View source]
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 88
def connect(settings = {})
@request_headers_map = nil
security_policies = nil
if response = preconnect
if host = response['redirect_host']
@collector = NewRelic::Control.instance.server_from_host(host)
end
if policies = response['security_policies']
security_policies = SecurityPolicySettings.preliminary_settings(policies)
settings.merge!(security_policies)
end
end
response = invoke_remote(:connect, [settings])
@request_headers_map = response['request_headers_map']
self.agent_id = response['agent_run_id']
response.merge!(security_policies) if security_policies
response
end
|
permalink
#create_and_start_http_connection ⇒ Object
[View source]
374
375
376
377
378
379
380
381
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 374
def create_and_start_http_connection
conn = create_http_connection
start_connection(conn)
conn
rescue Net::OpenTimeout
::NewRelic::Agent.logger.info('Timed out while attempting to connect. For SSL issues, you may need to install system-level CA Certificates to be used by Net::HTTP.')
raise
end
|
permalink
#create_http_connection ⇒ Object
[View source]
348
349
350
351
352
353
354
355
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 348
def create_http_connection
conn = prep_connection
setup_connection_for_ssl(conn)
setup_connection_timeouts(conn)
::NewRelic::Agent.logger.debug("Created net/http handle to #{conn.address}:#{conn.port}")
conn
end
|
permalink
#custom_event_data(data) ⇒ Object
[View source]
195
196
197
198
199
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 195
def custom_event_data(data)
_, items = data
invoke_remote(:custom_event_data, [@agent_id, *data],
:item_count => items.size)
end
|
permalink
#error_data(unsent_errors) ⇒ Object
[View source]
159
160
161
162
163
164
165
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 159
def error_data(unsent_errors)
return NewRelic::Agent.agent.serverless_handler.error_data(unsent_errors) if NewRelic::Agent.agent.serverless?
invoke_remote(:error_data, [@agent_id, unsent_errors],
:item_count => unsent_errors.size)
end
|
permalink
#error_event_data(data) ⇒ Object
[View source]
206
207
208
209
210
211
212
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 206
def error_event_data(data)
metadata, items = data
response = invoke_remote(:error_event_data, [@agent_id, *data], :item_count => items.size)
NewRelic::Agent.record_metric('Supportability/Events/TransactionError/Sent', :count => items.size)
NewRelic::Agent.record_metric('Supportability/Events/TransactionError/Seen', :count => metadata[:events_seen])
response
end
|
permalink
#establish_shared_connection ⇒ Object
[View source]
272
273
274
275
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 272
def establish_shared_connection
@shared_tcp_connection ||= create_and_start_http_connection
@shared_tcp_connection
end
|
permalink
#force_restart ⇒ Object
[View source]
128
129
130
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 128
def force_restart
close_shared_connection
end
|
permalink
#get_agent_commands ⇒ Object
[View source]
181
182
183
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 181
def get_agent_commands
invoke_remote(:get_agent_commands, [@agent_id])
end
|
permalink
#has_shared_connection? ⇒ Boolean
[View source]
285
286
287
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 285
def has_shared_connection?
!@shared_tcp_connection.nil?
end
|
permalink
#http_connection ⇒ Object
Return a Net::HTTP connection object to make a call to the collector. We’ll reuse the same handle for cases where we’re using keep-alive, or otherwise create a new one.
[View source]
303
304
305
306
307
308
309
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 303
def http_connection
if @in_session
establish_shared_connection
else
create_http_connection
end
end
|
permalink
#metric_data(stats_hash) ⇒ Object
[View source]
145
146
147
148
149
150
151
152
153
154
155
156
157
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 145
def metric_data(stats_hash)
return NewRelic::Agent.agent.serverless_handler.metric_data(stats_hash) if NewRelic::Agent.agent.serverless?
timeslice_start = stats_hash.started_at
timeslice_end = stats_hash.harvested_at || Process.clock_gettime(Process::CLOCK_REALTIME)
metric_data_array = build_metric_data_array(stats_hash)
invoke_remote(
:metric_data,
[@agent_id, timeslice_start, timeslice_end, metric_data_array],
:item_count => metric_data_array.size
)
end
|
permalink
#preconnect ⇒ Object
[View source]
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 107
def preconnect
token = Agent.config[:security_policies_token]
if token && !token.empty?
response = invoke_remote(:preconnect, [{'security_policies_token' => token, 'high_security' => false}])
validator = SecurityPolicySettings::Validator.new(response)
validator.validate_matching_agent_config!
response
elsif Agent.config[:high_security]
invoke_remote(:preconnect, [{'high_security' => true}])
else
invoke_remote(:preconnect, [{'high_security' => false}])
end
end
|
permalink
#prep_audit_logger ⇒ Object
[View source]
62
63
64
65
66
67
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 62
def prep_audit_logger
@audit_logger = ::NewRelic::Agent::AuditLogger.new
Agent.config.register_callback(:'audit_log.enabled') do |enabled|
@audit_logger.enabled = enabled
end
end
|
permalink
#prep_connection ⇒ Object
[View source]
357
358
359
360
361
362
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 357
def prep_connection
return Net::HTTP.new(@collector.name, @collector.port) unless Agent.config[:proxy_host]
::NewRelic::Agent.logger.debug("Using proxy server #{Agent.config[:proxy_host]}:#{Agent.config[:proxy_port]}")
prep_proxy_connection
end
|
permalink
#prep_marshaller ⇒ Object
[View source]
69
70
71
72
73
74
75
76
77
78
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 69
def prep_marshaller
Agent.config.register_callback(:marshaller) do |marshaller|
if marshaller != 'json'
::NewRelic::Agent.logger.warn("Non-JSON marshaller '#{marshaller}' requested but not supported, using " \
'JSON marshaller instead. pruby marshalling has been removed as of version 3.14.0.')
end
@marshaller = JsonMarshaller.new
end
end
|
permalink
#prep_proxy_connection ⇒ Object
[View source]
364
365
366
367
368
369
370
371
372
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 364
def prep_proxy_connection
proxy = Net::HTTP::Proxy(
Agent.config[:proxy_host],
Agent.config[:proxy_port],
Agent.config[:proxy_user],
Agent.config[:proxy_pass]
)
proxy.new(@collector.name, @collector.port)
end
|
permalink
#profile_data(profile) ⇒ Object
[View source]
177
178
179
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 177
def profile_data(profile)
invoke_remote(:profile_data, [@agent_id, profile], :skip_normalization => true) || ''
end
|
permalink
#session(&block) ⇒ Object
One session with the service’s endpoint. In this case the session represents 1 tcp connection which may transmit multiple HTTP requests via keep-alive.
[View source]
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 239
def session(&block)
raise ArgumentError, "#{self.class}#shared_connection must be passed a block" unless block
begin
t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC)
@in_session = true
if NewRelic::Agent.config[:aggressive_keepalive]
session_with_keepalive(&block)
else
session_without_keepalive(&block)
end
rescue *CONNECTION_ERRORS => e
elapsed = Process.clock_gettime(Process::CLOCK_MONOTONIC) - t0
raise NewRelic::Agent::ServerConnectionException, "Recoverable error connecting to #{@collector} after #{elapsed} seconds: #{e}"
ensure
@in_session = false
end
end
|
permalink
#session_with_keepalive(&block) ⇒ Object
[View source]
258
259
260
261
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 258
def session_with_keepalive(&block)
establish_shared_connection
yield
end
|
permalink
#session_without_keepalive(&block) ⇒ Object
[View source]
263
264
265
266
267
268
269
270
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 263
def session_without_keepalive(&block)
begin
establish_shared_connection
yield
ensure
close_shared_connection
end
end
|
permalink
#set_cert_store(conn) ⇒ Object
[View source]
323
324
325
326
327
328
329
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 323
def set_cert_store(conn)
if NewRelic::Agent.config[:ca_bundle_path]
conn.cert_store = ssl_cert_store
else
::NewRelic::Agent.logger.debug('Using default security certificates')
end
end
|
permalink
#setup_connection_for_ssl(conn) ⇒ Object
[View source]
311
312
313
314
315
316
317
318
319
320
321
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 311
def setup_connection_for_ssl(conn)
conn.use_ssl = true
conn.verify_mode = OpenSSL::SSL::VERIFY_PEER
set_cert_store(conn)
rescue StandardError, LoadError
msg = 'SSL is not available in the environment; please install SSL support.'
raise UnrecoverableAgentException.new(msg)
end
|
permalink
#setup_connection_timeouts(conn) ⇒ Object
[View source]
336
337
338
339
340
341
342
343
344
345
346
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 336
def setup_connection_timeouts(conn)
conn.open_timeout = @request_timeout
conn.read_timeout = @request_timeout
conn.write_timeout = @request_timeout if conn.respond_to?(:write_timeout=)
if conn.respond_to?(:keep_alive_timeout) && NewRelic::Agent.config[:aggressive_keepalive]
conn.keep_alive_timeout = NewRelic::Agent.config[:keep_alive_timeout]
end
end
|
permalink
#shutdown(time) ⇒ Object
[View source]
124
125
126
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 124
def shutdown(time)
invoke_remote(:shutdown, [@agent_id, time.to_i]) if @agent_id
end
|
permalink
#span_event_data(data) ⇒ Object
[View source]
214
215
216
217
218
219
220
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 214
def span_event_data(data)
metadata, items = data
response = invoke_remote(:span_event_data, [@agent_id, *data], :item_count => items.size)
NewRelic::Agent.record_metric('Supportability/Events/SpanEvents/Sent', :count => items.size)
NewRelic::Agent.record_metric('Supportability/Events/SpanEvents/Seen', :count => metadata[:events_seen])
response
end
|
permalink
#sql_trace_data(sql_traces) ⇒ Object
[View source]
172
173
174
175
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 172
def sql_trace_data(sql_traces)
invoke_remote(:sql_trace_data, [sql_traces],
:item_count => sql_traces.size)
end
|
permalink
#ssl_cert_store ⇒ Object
[View source]
289
290
291
292
293
294
295
296
297
298
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 289
def ssl_cert_store
path = cert_file_path
if !@ssl_cert_store || path != @cached_cert_store_path
::NewRelic::Agent.logger.debug("Creating SSL certificate store from file at #{path}")
@ssl_cert_store = OpenSSL::X509::Store.new
@ssl_cert_store.add_file(path)
@cached_cert_store_path = path
end
@ssl_cert_store
end
|
permalink
#start_connection(conn) ⇒ Object
[View source]
331
332
333
334
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 331
def start_connection(conn)
NewRelic::Agent.logger.debug("Opening TCP connection to #{conn.address}:#{conn.port}")
conn.start
end
|
permalink
#transaction_sample_data(traces) ⇒ Object
[View source]
167
168
169
170
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 167
def transaction_sample_data(traces)
invoke_remote(:transaction_sample_data, [@agent_id, traces],
:item_count => traces.size)
end
|
permalink
#valid_to_marshal?(data) ⇒ Boolean
[View source]
392
393
394
395
396
397
398
|
# File 'lib/new_relic/agent/new_relic_service.rb', line 392
def valid_to_marshal?(data)
@marshaller.dump(data)
true
rescue StandardError, SystemStackError => e
NewRelic::Agent.logger.warn('Unable to marshal environment report on connect.', e)
false
end
|