newrelic_rpm 3.9.0.229 → 3.9.1.236
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +4 -1
- data/CHANGELOG +73 -0
- data/install.rb +2 -2
- data/lib/new_relic/agent/agent.rb +8 -1
- data/lib/new_relic/agent/browser_token.rb +10 -7
- data/lib/new_relic/agent/configuration/default_source.rb +8 -1
- data/lib/new_relic/agent/configuration/high_security_source.rb +56 -0
- data/lib/new_relic/agent/configuration/manager.rb +35 -28
- data/lib/new_relic/agent/cross_app_monitor.rb +23 -0
- data/lib/new_relic/agent/cross_app_tracing.rb +34 -26
- data/lib/new_relic/agent/database.rb +7 -6
- data/lib/new_relic/agent/instrumentation/active_record.rb +18 -18
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +1 -1
- data/lib/new_relic/agent/instrumentation/curb.rb +18 -15
- data/lib/new_relic/agent/instrumentation/excon/connection.rb +1 -1
- data/lib/new_relic/agent/instrumentation/excon/middleware.rb +7 -4
- data/lib/new_relic/agent/instrumentation/httpclient.rb +1 -1
- data/lib/new_relic/agent/instrumentation/memcache.rb +9 -2
- data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +1 -1
- data/lib/new_relic/agent/instrumentation/net.rb +1 -1
- data/lib/new_relic/agent/instrumentation/rails3/errors.rb +1 -1
- data/lib/new_relic/agent/instrumentation/rails4/errors.rb +1 -1
- data/lib/new_relic/agent/instrumentation/typhoeus.rb +6 -4
- data/lib/new_relic/agent/javascript_instrumentor.rb +9 -1
- data/lib/new_relic/agent/new_relic_service.rb +7 -0
- data/lib/new_relic/agent/obfuscator.rb +3 -2
- data/lib/new_relic/agent/request_sampler.rb +17 -1
- data/lib/new_relic/agent/sql_sampler.rb +10 -6
- data/lib/new_relic/agent/traced_method_stack.rb +0 -12
- data/lib/new_relic/agent/transaction.rb +98 -10
- data/lib/new_relic/agent/transaction_sampler.rb +10 -3
- data/lib/new_relic/agent/transaction_state.rb +2 -12
- data/lib/new_relic/control/frameworks/sinatra.rb +0 -3
- data/lib/new_relic/control/instance_methods.rb +5 -0
- data/lib/new_relic/json_wrapper.rb +7 -1
- data/lib/new_relic/rack/browser_monitoring.rb +25 -4
- data/lib/new_relic/version.rb +1 -1
- data/newrelic_rpm.gemspec +0 -1
- data/test/agent_helper.rb +76 -0
- data/test/fixtures/cross_agent_tests/cat_map.json +299 -0
- data/test/multiverse/suites/agent_only/collector_exception_handling_test.rb +16 -0
- data/test/multiverse/suites/agent_only/cross_application_tracing_test.rb +30 -0
- data/test/multiverse/suites/agent_only/marshaling_test.rb +17 -17
- data/test/multiverse/suites/agent_only/testing_app.rb +10 -1
- data/test/multiverse/suites/deferred_instrumentation/config/newrelic.yml +0 -1
- data/test/multiverse/suites/high_security/Envfile +3 -0
- data/test/multiverse/suites/high_security/config/newrelic.yml +27 -0
- data/test/multiverse/suites/high_security/high_security_test.rb +64 -0
- data/test/multiverse/suites/rails/action_controller_live_rum_test.rb +39 -0
- data/test/multiverse/suites/rails/bad_instrumentation_test.rb +3 -1
- data/test/multiverse/suites/rails/parameter_capture_test.rb +0 -20
- data/test/new_relic/agent/agent/connect_test.rb +5 -10
- data/test/new_relic/agent/agent_test.rb +11 -0
- data/test/new_relic/agent/browser_token_test.rb +10 -6
- data/test/new_relic/agent/configuration/default_source_test.rb +6 -0
- data/test/new_relic/agent/configuration/high_security_source_test.rb +83 -0
- data/test/new_relic/agent/configuration/manager_test.rb +7 -2
- data/test/new_relic/agent/cross_app_monitor_test.rb +17 -1
- data/test/new_relic/agent/cross_app_tracing_test.rb +11 -10
- data/test/new_relic/agent/hostname_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +22 -0
- data/test/new_relic/agent/instrumentation/middleware_tracing_test.rb +37 -0
- data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +4 -2
- data/test/new_relic/agent/javascript_instrumentor_test.rb +42 -0
- data/test/new_relic/agent/memcache_instrumentation_test.rb +11 -5
- data/test/new_relic/agent/request_sampler_test.rb +9 -0
- data/test/new_relic/agent/sql_sampler_test.rb +46 -0
- data/test/new_relic/agent/stats_engine/gc_profiler_test.rb +1 -0
- data/test/new_relic/agent/transaction_sampler_test.rb +64 -4
- data/test/new_relic/agent/transaction_state_test.rb +0 -75
- data/test/new_relic/agent/transaction_test.rb +142 -0
- data/test/new_relic/control/instance_methods_test.rb +24 -4
- data/test/new_relic/fake_collector.rb +6 -13
- data/test/new_relic/fake_external_server.rb +14 -1
- data/test/new_relic/http_client_test_cases.rb +69 -21
- data/test/new_relic/json_wrapper_test.rb +10 -5
- data/test/performance/suites/rack_middleware.rb +2 -1
- data/test/performance/suites/rum_autoinsertion.rb +17 -3
- data/test/script/path_hash.rb +49 -0
- data/test/test_helper.rb +0 -10
- metadata +12 -52
- metadata.gz.sig +0 -0
@@ -23,18 +23,6 @@ module NewRelic
|
|
23
23
|
@stack = []
|
24
24
|
end
|
25
25
|
|
26
|
-
def self.tl_push_frame(tag, time = Time.now.to_f)
|
27
|
-
state = NewRelic::Agent::TransactionState.tl_get
|
28
|
-
stack = state.traced_method_stack
|
29
|
-
stack.push_frame(state, tag, time)
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.tl_pop_frame(expected_frame, name, time, deduct_call_time_from_parent=true)
|
33
|
-
state = NewRelic::Agent::TransactionState.tl_get
|
34
|
-
stack = state.traced_method_stack
|
35
|
-
stack.pop_frame(state, expected_frame, name, time, deduct_call_time_from_parent)
|
36
|
-
end
|
37
|
-
|
38
26
|
# Pushes a frame onto the transaction stack - this generates a
|
39
27
|
# TransactionSample::Segment at the end of transaction execution.
|
40
28
|
#
|
@@ -126,11 +126,21 @@ module NewRelic
|
|
126
126
|
end
|
127
127
|
|
128
128
|
txn
|
129
|
+
rescue => e
|
130
|
+
NewRelic::Agent.logger.error("Exception during Transaction.start", e)
|
131
|
+
nil
|
129
132
|
end
|
130
133
|
|
134
|
+
FAILED_TO_STOP_MESSAGE = "Failed during Transaction.stop because there is no current transaction"
|
135
|
+
|
131
136
|
def self.stop(state, end_time=Time.now)
|
132
137
|
txn = state.current_transaction
|
133
138
|
|
139
|
+
if txn.nil?
|
140
|
+
NewRelic::Agent.logger.error(FAILED_TO_STOP_MESSAGE)
|
141
|
+
return
|
142
|
+
end
|
143
|
+
|
134
144
|
if txn.frame_stack.empty?
|
135
145
|
txn.stop(state, end_time)
|
136
146
|
state.reset
|
@@ -166,6 +176,9 @@ module NewRelic
|
|
166
176
|
end
|
167
177
|
|
168
178
|
:transaction_stopped
|
179
|
+
rescue => e
|
180
|
+
NewRelic::Agent.logger.error("Exception during Transaction.stop", e)
|
181
|
+
nil
|
169
182
|
end
|
170
183
|
|
171
184
|
def self.nested_transaction_name(name)
|
@@ -188,7 +201,7 @@ module NewRelic
|
|
188
201
|
end
|
189
202
|
end
|
190
203
|
|
191
|
-
attr_reader :frame_stack
|
204
|
+
attr_reader :frame_stack, :cat_path_hashes
|
192
205
|
|
193
206
|
def initialize(category, options)
|
194
207
|
@frame_stack = []
|
@@ -209,6 +222,7 @@ module NewRelic
|
|
209
222
|
@exceptions = {}
|
210
223
|
@metrics = TransactionMetrics.new
|
211
224
|
@guid = generate_guid
|
225
|
+
@cat_path_hashes = nil
|
212
226
|
|
213
227
|
@ignore_this_transaction = false
|
214
228
|
@ignore_apdex = false
|
@@ -416,23 +430,85 @@ module NewRelic
|
|
416
430
|
# This event is fired when the transaction is fully completed. The metric
|
417
431
|
# values and sampler can't be successfully modified from this event.
|
418
432
|
def send_transaction_finished_event(state, start_time, end_time)
|
433
|
+
duration = end_time.to_f - start_time.to_f
|
419
434
|
payload = {
|
420
435
|
:name => @frozen_name,
|
421
436
|
:start_timestamp => start_time.to_f,
|
422
|
-
:duration =>
|
437
|
+
:duration => duration,
|
423
438
|
:metrics => @metrics,
|
424
439
|
:custom_params => custom_parameters
|
425
440
|
}
|
426
|
-
|
441
|
+
append_cat_info(state, duration, payload)
|
442
|
+
append_apdex_perf_zone(duration, payload)
|
427
443
|
append_referring_transaction_guid_to(state, payload)
|
428
444
|
|
429
445
|
agent.events.notify(:transaction_finished, payload)
|
430
446
|
end
|
431
447
|
|
432
|
-
def
|
433
|
-
|
434
|
-
|
435
|
-
|
448
|
+
def include_guid?(state, duration)
|
449
|
+
state.is_cross_app? ||
|
450
|
+
(state.request_token && duration > apdex_t)
|
451
|
+
end
|
452
|
+
|
453
|
+
def cat_trip_id(state)
|
454
|
+
NewRelic::Agent.instance.cross_app_monitor.client_referring_transaction_trip_id(state) || guid
|
455
|
+
end
|
456
|
+
|
457
|
+
def cat_path_hash(state)
|
458
|
+
referring_path_hash = cat_referring_path_hash(state) || '0'
|
459
|
+
seed = referring_path_hash.to_i(16)
|
460
|
+
result = NewRelic::Agent.instance.cross_app_monitor.path_hash(best_name, seed)
|
461
|
+
record_cat_path_hash(result)
|
462
|
+
result
|
463
|
+
end
|
464
|
+
|
465
|
+
def record_cat_path_hash(hash)
|
466
|
+
@cat_path_hashes ||= []
|
467
|
+
if @cat_path_hashes.size < 10 && !@cat_path_hashes.include?(hash)
|
468
|
+
@cat_path_hashes << hash
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
def cat_referring_path_hash(state)
|
473
|
+
NewRelic::Agent.instance.cross_app_monitor.client_referring_transaction_path_hash(state)
|
474
|
+
end
|
475
|
+
|
476
|
+
APDEX_S = 'S'.freeze
|
477
|
+
APDEX_T = 'T'.freeze
|
478
|
+
APDEX_F = 'F'.freeze
|
479
|
+
|
480
|
+
def append_apdex_perf_zone(duration, payload)
|
481
|
+
return unless recording_web_transaction?
|
482
|
+
|
483
|
+
bucket = apdex_bucket(duration)
|
484
|
+
bucket_str = case bucket
|
485
|
+
when :apdex_s then APDEX_S
|
486
|
+
when :apdex_t then APDEX_T
|
487
|
+
when :apdex_f then APDEX_F
|
488
|
+
else nil
|
489
|
+
end
|
490
|
+
payload[:apdex_perf_zone] = bucket_str if bucket_str
|
491
|
+
end
|
492
|
+
|
493
|
+
def append_cat_info(state, duration, payload)
|
494
|
+
return unless include_guid?(state, duration)
|
495
|
+
payload[:guid] = guid
|
496
|
+
|
497
|
+
return unless state.is_cross_app?
|
498
|
+
trip_id = cat_trip_id(state)
|
499
|
+
path_hash = cat_path_hash(state)
|
500
|
+
referring_path_hash = cat_referring_path_hash(state)
|
501
|
+
|
502
|
+
payload[:cat_trip_id] = trip_id if trip_id
|
503
|
+
payload[:cat_referring_path_hash] = referring_path_hash if referring_path_hash
|
504
|
+
|
505
|
+
if path_hash
|
506
|
+
payload[:cat_path_hash] = path_hash
|
507
|
+
|
508
|
+
alternate_path_hashes = cat_path_hashes - [path_hash]
|
509
|
+
unless alternate_path_hashes.empty?
|
510
|
+
payload[:cat_alternate_path_hashes] = alternate_path_hashes
|
511
|
+
end
|
436
512
|
end
|
437
513
|
end
|
438
514
|
|
@@ -505,16 +581,23 @@ module NewRelic
|
|
505
581
|
|
506
582
|
APDEX_METRIC = 'Apdex'.freeze
|
507
583
|
|
584
|
+
def had_error?
|
585
|
+
!notable_exceptions.empty?
|
586
|
+
end
|
587
|
+
|
588
|
+
def apdex_bucket(duration)
|
589
|
+
self.class.apdex_bucket(duration, had_error?, apdex_t)
|
590
|
+
end
|
591
|
+
|
508
592
|
def record_apdex(state, end_time=Time.now)
|
509
593
|
return unless recording_web_transaction? && state.is_execution_traced?
|
510
594
|
|
511
595
|
freeze_name_and_execute_if_not_ignored do
|
512
596
|
action_duration = end_time - start_time
|
513
597
|
total_duration = end_time - apdex_start
|
514
|
-
is_error = !notable_exceptions.empty?
|
515
598
|
|
516
|
-
apdex_bucket_global =
|
517
|
-
apdex_bucket_txn =
|
599
|
+
apdex_bucket_global = apdex_bucket(total_duration)
|
600
|
+
apdex_bucket_txn = apdex_bucket(action_duration)
|
518
601
|
|
519
602
|
@metrics.record_unscoped(APDEX_METRIC, apdex_bucket_global, apdex_t)
|
520
603
|
txn_apdex_metric = @frozen_name.gsub(/^[^\/]+\//, 'Apdex/')
|
@@ -559,6 +642,11 @@ module NewRelic
|
|
559
642
|
end
|
560
643
|
|
561
644
|
def add_custom_parameters(p)
|
645
|
+
if NewRelic::Agent.config[:high_security]
|
646
|
+
NewRelic::Agent.logger.debug("Unable to add custom attributes #{p.keys.inspect} while in high security mode.")
|
647
|
+
return
|
648
|
+
end
|
649
|
+
|
562
650
|
custom_parameters.merge!(p)
|
563
651
|
end
|
564
652
|
|
@@ -126,10 +126,17 @@ module NewRelic
|
|
126
126
|
last_builder.set_transaction_name(txn.best_name)
|
127
127
|
last_builder.finish_trace(time.to_f, custom_parameters_from_transaction(txn))
|
128
128
|
|
129
|
+
last_sample = last_builder.sample
|
130
|
+
last_sample.guid = txn.guid
|
131
|
+
last_sample.set_custom_param(:gc_time, gc_time) if gc_time
|
132
|
+
|
133
|
+
if state.is_cross_app?
|
134
|
+
last_sample.set_custom_param(:'nr.trip_id', txn.cat_trip_id(state))
|
135
|
+
last_sample.set_custom_param(:'nr.path_hash', txn.cat_path_hash(state))
|
136
|
+
end
|
137
|
+
|
129
138
|
@samples_lock.synchronize do
|
130
|
-
@last_sample =
|
131
|
-
@last_sample.guid = txn.guid
|
132
|
-
@last_sample.set_custom_param(:gc_time, gc_time) if gc_time
|
139
|
+
@last_sample = last_sample
|
133
140
|
store_sample(@last_sample)
|
134
141
|
@last_sample
|
135
142
|
end
|
@@ -84,9 +84,8 @@ module NewRelic
|
|
84
84
|
referring_transaction_info != nil
|
85
85
|
end
|
86
86
|
|
87
|
-
def
|
88
|
-
|
89
|
-
request_guid
|
87
|
+
def is_cross_app?
|
88
|
+
is_cross_app_caller? || is_cross_app_callee?
|
90
89
|
end
|
91
90
|
|
92
91
|
# Request data
|
@@ -98,15 +97,6 @@ module NewRelic
|
|
98
97
|
current_transaction.guid
|
99
98
|
end
|
100
99
|
|
101
|
-
def request_guid_to_include
|
102
|
-
return "" unless include_guid?
|
103
|
-
request_guid
|
104
|
-
end
|
105
|
-
|
106
|
-
def include_guid?
|
107
|
-
request_token && timings.app_time_in_seconds > current_transaction.apdex_t
|
108
|
-
end
|
109
|
-
|
110
100
|
# Current transaction stack and sample building
|
111
101
|
attr_reader :current_transaction
|
112
102
|
attr_accessor :transaction_sample_builder
|
@@ -85,6 +85,11 @@ module NewRelic
|
|
85
85
|
|
86
86
|
config_file_path = @config_file_override || Agent.config[:config_path]
|
87
87
|
Agent.config.replace_or_add_config(Agent::Configuration::YamlSource.new(config_file_path, env))
|
88
|
+
|
89
|
+
if Agent.config[:high_security]
|
90
|
+
Agent.logger.info("Installing high security configuration based on local configuration")
|
91
|
+
Agent.config.replace_or_add_config(Agent::Configuration::HighSecuritySource.new(Agent.config))
|
92
|
+
end
|
88
93
|
end
|
89
94
|
|
90
95
|
# Install the real agent into the Agent module, and issue the start command.
|
@@ -33,6 +33,11 @@ module NewRelic
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def self.normalize_string(s)
|
36
|
+
# Early return if called on 1.8.x. In normal circumstances 1.8.x
|
37
|
+
# shouldn't call this--it does nothing for Ruby-marshalled formats-- but
|
38
|
+
# we use it in multiverse to make comparing data more consistent.
|
39
|
+
return s unless supports_normalization?
|
40
|
+
|
36
41
|
encoding = s.encoding
|
37
42
|
if (encoding == Encoding::UTF_8 || encoding == Encoding::ISO_8859_1) && s.valid_encoding?
|
38
43
|
return s
|
@@ -69,7 +74,8 @@ module NewRelic
|
|
69
74
|
return object if object.empty?
|
70
75
|
hash = {}
|
71
76
|
object.each_pair do |k, v|
|
72
|
-
k = normalize_string(k)
|
77
|
+
k = normalize_string(k) if k.is_a?(String)
|
78
|
+
k = normalize_string(k.to_s) if k.is_a?(Symbol)
|
73
79
|
hash[k] = normalize(v)
|
74
80
|
end
|
75
81
|
hash
|
@@ -15,6 +15,10 @@ module NewRelic::Rack
|
|
15
15
|
# @api public
|
16
16
|
#
|
17
17
|
class BrowserMonitoring < AgentMiddleware
|
18
|
+
# The maximum number of bytes of the response body that we will
|
19
|
+
# examine in order to look for a RUM insertion point.
|
20
|
+
SCAN_LIMIT = 50_000
|
21
|
+
|
18
22
|
def traced_call(env)
|
19
23
|
result = @app.call(env) # [status, headers, response]
|
20
24
|
|
@@ -38,8 +42,23 @@ module NewRelic::Rack
|
|
38
42
|
def should_instrument?(env, status, headers)
|
39
43
|
status == 200 &&
|
40
44
|
!env[ALREADY_INSTRUMENTED_KEY] &&
|
41
|
-
|
42
|
-
!
|
45
|
+
is_html?(headers) &&
|
46
|
+
!is_attachment?(headers) &&
|
47
|
+
!is_streaming?(env)
|
48
|
+
end
|
49
|
+
|
50
|
+
def is_html?(headers)
|
51
|
+
headers["Content-Type"] && headers["Content-Type"].include?("text/html")
|
52
|
+
end
|
53
|
+
|
54
|
+
def is_attachment?(headers)
|
55
|
+
headers['Content-Disposition'].to_s.include?('attachment')
|
56
|
+
end
|
57
|
+
|
58
|
+
def is_streaming?(env)
|
59
|
+
return false unless defined?(ActionController::Live)
|
60
|
+
|
61
|
+
env['action_controller.instance'].class.included_modules.include?(ActionController::Live)
|
43
62
|
end
|
44
63
|
|
45
64
|
CHARSET_RE = /<\s*meta[^>]+charset\s*=[^>]*>/im.freeze
|
@@ -51,7 +70,7 @@ module NewRelic::Rack
|
|
51
70
|
return nil unless source
|
52
71
|
|
53
72
|
# Only scan the first 50k (roughly) then give up.
|
54
|
-
beginning_of_source = source[0..
|
73
|
+
beginning_of_source = source[0..SCAN_LIMIT]
|
55
74
|
|
56
75
|
if body_start = find_body_start(beginning_of_source)
|
57
76
|
meta_tag_positions = [
|
@@ -73,7 +92,9 @@ module NewRelic::Rack
|
|
73
92
|
NewRelic::Agent.logger.debug "Skipping RUM instrumentation. Could not properly determine location to inject script."
|
74
93
|
end
|
75
94
|
else
|
76
|
-
|
95
|
+
msg = "Skipping RUM instrumentation. Unable to find <body> tag in first #{SCAN_LIMIT} bytes of document."
|
96
|
+
NewRelic::Agent.logger.log_once(:warn, :rum_insertion_failure, msg)
|
97
|
+
NewRelic::Agent.logger.debug(msg)
|
77
98
|
end
|
78
99
|
|
79
100
|
if headers['Content-Length']
|
data/lib/new_relic/version.rb
CHANGED
data/newrelic_rpm.gemspec
CHANGED
@@ -39,7 +39,6 @@ EOS
|
|
39
39
|
s.require_paths = ["lib"]
|
40
40
|
s.rubygems_version = Gem::VERSION
|
41
41
|
s.summary = "New Relic Ruby Agent"
|
42
|
-
s.post_install_message = NewRelic::LatestChanges.read
|
43
42
|
|
44
43
|
s.add_development_dependency 'rake', '10.1.0'
|
45
44
|
s.add_development_dependency 'minitest', '~> 4.7.5'
|
data/test/agent_helper.rb
CHANGED
@@ -244,6 +244,10 @@ def in_transaction(*args)
|
|
244
244
|
val
|
245
245
|
end
|
246
246
|
|
247
|
+
def stub_transaction_guid(guid)
|
248
|
+
NewRelic::Agent::Transaction.tl_current.instance_variable_set(:@guid, guid)
|
249
|
+
end
|
250
|
+
|
247
251
|
# Convenience wrapper around in_transaction that sets the category so that it
|
248
252
|
# looks like we are in a web transaction
|
249
253
|
def in_web_transaction(name='dummy')
|
@@ -252,6 +256,32 @@ def in_web_transaction(name='dummy')
|
|
252
256
|
end
|
253
257
|
end
|
254
258
|
|
259
|
+
def in_background_transaction(name='silly')
|
260
|
+
in_transaction(name, :category => :task) do
|
261
|
+
yield
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
def last_traced_error
|
266
|
+
NewRelic::Agent.agent.error_collector.errors.last
|
267
|
+
end
|
268
|
+
|
269
|
+
def last_traced_error_request_params
|
270
|
+
last_traced_error.params[:request_params]
|
271
|
+
end
|
272
|
+
|
273
|
+
def last_transaction_trace
|
274
|
+
NewRelic::Agent.agent.transaction_sampler.last_sample
|
275
|
+
end
|
276
|
+
|
277
|
+
def last_transaction_trace_request_params
|
278
|
+
last_transaction_trace.params[:request_params]
|
279
|
+
end
|
280
|
+
|
281
|
+
def last_sql_trace
|
282
|
+
NewRelic::Agent.agent.sql_sampler.sql_traces.values.last
|
283
|
+
end
|
284
|
+
|
255
285
|
def find_last_transaction_segment(transaction_sample=nil)
|
256
286
|
if transaction_sample
|
257
287
|
root_segment = transaction_sample.root_segment
|
@@ -457,3 +487,49 @@ ensure
|
|
457
487
|
NewRelic::Agent.ignore_error_filter(&original_filter)
|
458
488
|
end
|
459
489
|
end
|
490
|
+
|
491
|
+
def json_dump_and_encode(object)
|
492
|
+
Base64.encode64(NewRelic::JSONWrapper.dump(object))
|
493
|
+
end
|
494
|
+
|
495
|
+
def get_last_analytics_event
|
496
|
+
NewRelic::Agent.agent.instance_variable_get(:@request_sampler).samples.last
|
497
|
+
end
|
498
|
+
|
499
|
+
def cross_agent_tests_dir
|
500
|
+
File.expand_path(File.join(File.dirname(__FILE__), 'fixtures', 'cross_agent_tests'))
|
501
|
+
end
|
502
|
+
|
503
|
+
def load_cross_agent_test(name)
|
504
|
+
test_file_path = File.join(cross_agent_tests_dir, "#{name}.json")
|
505
|
+
data = File.read(test_file_path)
|
506
|
+
NewRelic::JSONWrapper.load(data)
|
507
|
+
end
|
508
|
+
|
509
|
+
def assert_event_attributes(event, test_name, expected_attributes, non_expected_attributes)
|
510
|
+
incorrect_attributes = []
|
511
|
+
|
512
|
+
event_attrs = event[0]
|
513
|
+
|
514
|
+
expected_attributes.each do |name, expected_value|
|
515
|
+
actual_value = event_attrs[name]
|
516
|
+
incorrect_attributes << name unless actual_value == expected_value
|
517
|
+
end
|
518
|
+
|
519
|
+
msg = "Found missing or incorrect attribute values in #{test_name}:\n"
|
520
|
+
|
521
|
+
incorrect_attributes.each do |name|
|
522
|
+
msg << " #{name}: expected = #{expected_attributes[name].inspect}, actual = #{event_attrs[name].inspect}\n"
|
523
|
+
end
|
524
|
+
msg << "\n"
|
525
|
+
|
526
|
+
msg << "All event values:\n"
|
527
|
+
event_attrs.each do |name, actual_value|
|
528
|
+
msg << " #{name}: #{actual_value.inspect}\n"
|
529
|
+
end
|
530
|
+
assert(incorrect_attributes.empty?, msg)
|
531
|
+
|
532
|
+
non_expected_attributes.each do |name|
|
533
|
+
assert_nil(event_attrs[name], "Found value '#{event_attrs[name]}' for attribute '#{name}', but expected nothing in #{test_name}")
|
534
|
+
end
|
535
|
+
end
|