newrelic_rpm 3.13.2.302 → 3.14.0.305
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +20 -0
- data/README.md +1 -13
- data/lib/new_relic/agent/agent.rb +40 -15
- data/lib/new_relic/agent/agent_logger.rb +1 -1
- data/lib/new_relic/agent/configuration/default_source.rb +16 -6
- data/lib/new_relic/agent/configuration/server_source.rb +2 -1
- data/lib/new_relic/agent/error_collector.rb +13 -21
- data/lib/new_relic/agent/error_event_aggregator.rb +124 -0
- data/lib/new_relic/agent/error_trace_aggregator.rb +15 -5
- data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +16 -2
- data/lib/new_relic/agent/new_relic_service.rb +11 -10
- data/lib/new_relic/agent/new_relic_service/json_marshaller.rb +1 -1
- data/lib/new_relic/agent/payload_metric_mapping.rb +58 -0
- data/lib/new_relic/agent/sampled_buffer.rb +15 -1
- data/lib/new_relic/agent/supported_versions.rb +4 -4
- data/lib/new_relic/agent/transaction.rb +52 -44
- data/lib/new_relic/agent/transaction/request_attributes.rb +110 -0
- data/lib/new_relic/agent/transaction_event_aggregator.rb +4 -41
- data/lib/new_relic/noticed_error.rb +25 -9
- data/lib/new_relic/rack/agent_middleware.rb +5 -0
- data/lib/new_relic/version.rb +2 -2
- data/newrelic_rpm.gemspec +6 -0
- data/test/agent_helper.rb +16 -7
- data/test/environments/norails/Gemfile +1 -0
- data/test/multiverse/lib/multiverse/runner.rb +1 -1
- data/test/multiverse/lib/multiverse/suite.rb +6 -3
- data/test/multiverse/suites/agent_only/agent_attributes_test.rb +57 -0
- data/test/multiverse/suites/agent_only/audit_log_test.rb +1 -2
- data/test/multiverse/suites/agent_only/error_events_test.rb +82 -0
- data/test/multiverse/suites/agent_only/harvest_timestamps_test.rb +31 -6
- data/test/multiverse/suites/agent_only/logging_test.rb +2 -2
- data/test/multiverse/suites/agent_only/marshaling_test.rb +6 -0
- data/test/multiverse/suites/agent_only/set_transaction_name_test.rb +2 -2
- data/test/multiverse/suites/agent_only/thread_profiling_test.rb +0 -20
- data/test/multiverse/suites/grape/grape_test.rb +16 -1
- data/test/multiverse/suites/no_json/Envfile +12 -0
- data/test/multiverse/suites/no_json/config/newrelic.yml +27 -0
- data/test/multiverse/suites/no_json/marshal_config_test.rb +22 -0
- data/test/multiverse/suites/rack/example_app.rb +19 -0
- data/test/multiverse/suites/rack/response_content_type_test.rb +50 -0
- data/test/multiverse/suites/rails/error_tracing_test.rb +12 -7
- data/test/multiverse/suites/rails/parameter_capture_test.rb +21 -1
- data/test/multiverse/suites/sinatra/sinatra_error_tracing_test.rb +5 -2
- data/test/multiverse/suites/sinatra/sinatra_parameter_capture_test.rb +16 -1
- data/test/multiverse/suites/sinatra/sinatra_test_cases.rb +4 -2
- data/test/new_relic/agent/agent_logger_test.rb +9 -0
- data/test/new_relic/agent/agent_test.rb +6 -4
- data/test/new_relic/agent/audit_logger_test.rb +0 -7
- data/test/new_relic/agent/error_collector_test.rb +20 -250
- data/test/new_relic/agent/error_event_aggregator_test.rb +294 -0
- data/test/new_relic/agent/error_trace_aggregator_test.rb +273 -5
- data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +2 -2
- data/test/new_relic/agent/new_relic_service_test.rb +8 -32
- data/test/new_relic/agent/payload_metric_mapping_test.rb +74 -0
- data/test/new_relic/agent/pipe_channel_manager_test.rb +6 -5
- data/test/new_relic/agent/sampled_buffer_test.rb +36 -0
- data/test/new_relic/agent/sql_sampler_test.rb +4 -14
- data/test/new_relic/agent/stats_engine/stats_hash_test.rb +5 -4
- data/test/new_relic/agent/threading/thread_profile_test.rb +1 -2
- data/test/new_relic/agent/transaction/request_attributes_test.rb +76 -0
- data/test/new_relic/agent/transaction_event_aggregator_test.rb +12 -1
- data/test/new_relic/agent/transaction_test.rb +60 -11
- data/test/new_relic/data_container_tests.rb +17 -6
- data/test/new_relic/fake_collector.rb +16 -21
- data/test/new_relic/marshalling_test_cases.rb +1 -0
- data/test/new_relic/noticed_error_test.rb +59 -0
- data/test/new_relic/rack/agent_hooks_test.rb +1 -1
- data/test/new_relic/rack/error_collector_test.rb +7 -5
- data/test/performance/suites/error_collector.rb +28 -0
- data/test/performance/suites/marshalling.rb +0 -8
- metadata +14 -3
- data/lib/new_relic/agent/new_relic_service/pruby_marshaller.rb +0 -56
@@ -7,6 +7,7 @@ require 'monitor'
|
|
7
7
|
|
8
8
|
require 'newrelic_rpm' unless defined?( NewRelic )
|
9
9
|
require 'new_relic/agent' unless defined?( NewRelic::Agent )
|
10
|
+
require 'new_relic/agent/payload_metric_mapping'
|
10
11
|
|
11
12
|
class NewRelic::Agent::TransactionEventAggregator
|
12
13
|
include NewRelic::Coerce,
|
@@ -20,6 +21,7 @@ class NewRelic::Agent::TransactionEventAggregator
|
|
20
21
|
TIMESTAMP_KEY = 'timestamp'.freeze
|
21
22
|
NAME_KEY = 'name'.freeze
|
22
23
|
DURATION_KEY = 'duration'.freeze
|
24
|
+
ERROR_KEY = 'error'.freeze
|
23
25
|
GUID_KEY = 'nr.guid'.freeze
|
24
26
|
REFERRING_TRANSACTION_GUID_KEY = 'nr.referringTransactionGuid'.freeze
|
25
27
|
CAT_TRIP_ID_KEY = 'nr.tripId'.freeze
|
@@ -170,54 +172,15 @@ class NewRelic::Agent::TransactionEventAggregator
|
|
170
172
|
end
|
171
173
|
end
|
172
174
|
|
173
|
-
def self.map_metric(metric_name, to_add={})
|
174
|
-
to_add.values.each(&:freeze)
|
175
|
-
|
176
|
-
mappings = OVERVIEW_SPECS.fetch(metric_name, {})
|
177
|
-
mappings.merge!(to_add)
|
178
|
-
|
179
|
-
OVERVIEW_SPECS[metric_name] = mappings
|
180
|
-
end
|
181
|
-
|
182
|
-
OVERVIEW_SPECS = {}
|
183
|
-
|
184
|
-
# All Transactions
|
185
|
-
# Don't need to use the transaction-type specific metrics since this is
|
186
|
-
# scoped to just one transaction, so Datastore/all has what we want.
|
187
|
-
map_metric('Datastore/all', :total_call_time => "databaseDuration")
|
188
|
-
map_metric('Datastore/all', :call_count => "databaseCallCount")
|
189
|
-
map_metric('GC/Transaction/all', :total_call_time => "gcCumulative")
|
190
|
-
|
191
|
-
# Web Metrics
|
192
|
-
map_metric('WebFrontend/QueueTime', :total_call_time => "queueDuration")
|
193
|
-
map_metric('External/allWeb', :total_call_time => "externalDuration")
|
194
|
-
map_metric('External/allWeb', :call_count => "externalCallCount")
|
195
|
-
|
196
|
-
# Background Metrics
|
197
|
-
map_metric('External/allOther', :total_call_time => "externalDuration")
|
198
|
-
map_metric('External/allOther', :call_count => "externalCallCount")
|
199
|
-
|
200
|
-
def append_metrics(txn_metrics, sample)
|
201
|
-
if txn_metrics
|
202
|
-
OVERVIEW_SPECS.each do |(name, extracted_values)|
|
203
|
-
if txn_metrics.has_key?(name)
|
204
|
-
stat = txn_metrics[name]
|
205
|
-
extracted_values.each do |value_name, key_name|
|
206
|
-
sample[key_name] = stat.send(value_name)
|
207
|
-
end
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
175
|
def create_main_event(payload)
|
214
176
|
sample = {
|
215
177
|
TIMESTAMP_KEY => float(payload[:start_timestamp]),
|
216
178
|
NAME_KEY => string(payload[:name]),
|
217
179
|
DURATION_KEY => float(payload[:duration]),
|
218
180
|
TYPE_KEY => SAMPLE_TYPE,
|
181
|
+
ERROR_KEY => payload[:error]
|
219
182
|
}
|
220
|
-
|
183
|
+
NewRelic::Agent::PayloadMetricMapping.append_mapped_metrics(payload[:metrics], sample)
|
221
184
|
optionally_append(GUID_KEY, :guid, sample, payload)
|
222
185
|
optionally_append(REFERRING_TRANSACTION_GUID_KEY, :referring_transaction_guid, sample, payload)
|
223
186
|
optionally_append(CAT_TRIP_ID_KEY, :cat_trip_id, sample, payload)
|
@@ -10,8 +10,8 @@ class NewRelic::NoticedError
|
|
10
10
|
extend NewRelic::CollectionHelper
|
11
11
|
|
12
12
|
attr_accessor :path, :timestamp, :message, :exception_class_name,
|
13
|
-
:request_uri, :
|
14
|
-
:attributes_from_notice_error, :attributes
|
13
|
+
:request_uri, :request_port, :file_name, :line_number,
|
14
|
+
:stack_trace, :attributes_from_notice_error, :attributes
|
15
15
|
|
16
16
|
attr_reader :exception_id, :is_internal
|
17
17
|
|
@@ -86,7 +86,7 @@ class NewRelic::NoticedError
|
|
86
86
|
string(path),
|
87
87
|
string(message),
|
88
88
|
string(exception_class_name),
|
89
|
-
|
89
|
+
processed_attributes ]
|
90
90
|
end
|
91
91
|
|
92
92
|
USER_ATTRIBUTES = "userAttributes".freeze
|
@@ -97,12 +97,17 @@ class NewRelic::NoticedError
|
|
97
97
|
|
98
98
|
DESTINATION = NewRelic::Agent::AttributeFilter::DST_ERROR_COLLECTOR
|
99
99
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
100
|
+
# Note that we process attributes lazily and store the result. This is because
|
101
|
+
# there is a possibility that a noticed error will be discarded and not sent back
|
102
|
+
# as a traced error or TransactionError.
|
103
|
+
def processed_attributes
|
104
|
+
@processed_attributes ||= begin
|
105
|
+
attributes = base_parameters
|
106
|
+
append_attributes(attributes, USER_ATTRIBUTES, merged_custom_attributes)
|
107
|
+
append_attributes(attributes, AGENT_ATTRIBUTES, build_agent_attributes)
|
108
|
+
append_attributes(attributes, INTRINSIC_ATTRIBUTES, build_intrinsic_attributes)
|
109
|
+
attributes
|
110
|
+
end
|
106
111
|
end
|
107
112
|
|
108
113
|
def base_parameters
|
@@ -161,4 +166,15 @@ class NewRelic::NoticedError
|
|
161
166
|
outgoing_params[outgoing_key] = source_attributes || {}
|
162
167
|
end
|
163
168
|
|
169
|
+
def agent_attributes
|
170
|
+
processed_attributes[AGENT_ATTRIBUTES]
|
171
|
+
end
|
172
|
+
|
173
|
+
def custom_attributes
|
174
|
+
processed_attributes[USER_ATTRIBUTES]
|
175
|
+
end
|
176
|
+
|
177
|
+
def intrinsic_attributes
|
178
|
+
processed_attributes[INTRINSIC_ATTRIBUTES]
|
179
|
+
end
|
164
180
|
end
|
@@ -35,6 +35,11 @@ module NewRelic
|
|
35
35
|
return if NewRelic::Agent.config[:disable_middleware_instrumentation]
|
36
36
|
super
|
37
37
|
end
|
38
|
+
|
39
|
+
def capture_response_content_type(state, result)
|
40
|
+
return if NewRelic::Agent.config[:disable_middleware_instrumentation]
|
41
|
+
super
|
42
|
+
end
|
38
43
|
end
|
39
44
|
end
|
40
45
|
end
|
data/lib/new_relic/version.rb
CHANGED
data/newrelic_rpm.gemspec
CHANGED
@@ -56,6 +56,12 @@ EOS
|
|
56
56
|
s.add_development_dependency 'rb-fsevent'
|
57
57
|
end
|
58
58
|
|
59
|
+
# rack-cache ~> 1.2 is specified by actionpack 3.2, but rack-cache 1.3.1 only works on Ruby 1.9.3 & newer. :(
|
60
|
+
# https://github.com/rtomayko/rack-cache/issues/124
|
61
|
+
if RUBY_VERSION < "1.9.3"
|
62
|
+
s.add_development_dependency "rack-cache", "~> 1.2.0"
|
63
|
+
end
|
64
|
+
|
59
65
|
# version lock down for i18n that is compatible with Ruby 1.8.7
|
60
66
|
s.add_development_dependency 'i18n', '0.6.11'
|
61
67
|
|
data/test/agent_helper.rb
CHANGED
@@ -26,12 +26,25 @@ def assert_in_delta(expected, actual, delta)
|
|
26
26
|
assert_between((expected - delta), (expected + delta), actual)
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
29
|
+
def harvest_error_traces!
|
30
|
+
NewRelic::Agent.instance.error_collector.error_trace_aggregator.harvest!
|
31
|
+
end
|
32
|
+
|
33
|
+
def reset_error_traces!
|
34
|
+
NewRelic::Agent.instance.error_collector.error_trace_aggregator.reset!
|
35
|
+
end
|
36
|
+
|
37
|
+
def assert_has_traced_error(error_class)
|
38
|
+
errors = harvest_error_traces!
|
30
39
|
assert \
|
31
|
-
|
40
|
+
errors.find {|e| e.exception_class_name == error_class.name} != nil, \
|
32
41
|
"Didn't find error of class #{error_class}"
|
33
42
|
end
|
34
43
|
|
44
|
+
def last_traced_error
|
45
|
+
harvest_error_traces!.last
|
46
|
+
end
|
47
|
+
|
35
48
|
unless defined?( assert_block )
|
36
49
|
def assert_block(*msgs)
|
37
50
|
assert yield, *msgs
|
@@ -81,7 +94,7 @@ end
|
|
81
94
|
# orderings of the key/value pairs in Hashes that were embedded in the request
|
82
95
|
# body). So, this method traverses an object graph and only makes assertions
|
83
96
|
# about the terminal (non-Array-or-Hash) nodes therein.
|
84
|
-
def assert_audit_log_contains_object(audit_log_contents, o, format)
|
97
|
+
def assert_audit_log_contains_object(audit_log_contents, o, format = :json)
|
85
98
|
case o
|
86
99
|
when Hash
|
87
100
|
o.each do |k,v|
|
@@ -321,10 +334,6 @@ def refute_contains_request_params(attributes)
|
|
321
334
|
end
|
322
335
|
end
|
323
336
|
|
324
|
-
def last_traced_error
|
325
|
-
NewRelic::Agent.agent.error_collector.errors.last
|
326
|
-
end
|
327
|
-
|
328
337
|
def last_transaction_trace
|
329
338
|
NewRelic::Agent.agent.transaction_sampler.last_sample
|
330
339
|
end
|
@@ -83,7 +83,7 @@ module Multiverse
|
|
83
83
|
|
84
84
|
GROUPS = {
|
85
85
|
"agent" => ["agent_only", "bare", "config_file_loading",
|
86
|
-
"deferred_instrumentation", "high_security"],
|
86
|
+
"deferred_instrumentation", "high_security", "no_json"],
|
87
87
|
"api" => ["grape"],
|
88
88
|
"background" => ["delayed_job", "rake", "resque", "sidekiq"],
|
89
89
|
"database" => ["datamapper", "mongo", "redis", "sequel"],
|
@@ -174,18 +174,21 @@ module Multiverse
|
|
174
174
|
f.puts newrelic_gemfile_line unless gemfile_text =~ /^\s*gem .newrelic_rpm./
|
175
175
|
f.puts jruby_openssl_line unless gemfile_text =~ /^\s*gem .jruby-openssl./ || (defined?(JRUBY_VERSION) && JRUBY_VERSION > '1.7')
|
176
176
|
f.puts minitest_line unless gemfile_text =~ /^\s*gem .minitest[^_]./
|
177
|
+
if RUBY_VERSION == "1.8.7"
|
178
|
+
f.puts "gem 'json'" unless gemfile_text =~ /^\s.*gem .json./
|
179
|
+
end
|
177
180
|
|
178
181
|
rbx_gemfile_lines(f, gemfile_text)
|
179
182
|
|
180
183
|
f.puts " gem 'mocha', '0.14.0', :require => false"
|
181
184
|
|
182
185
|
if debug
|
183
|
-
pry_version = RUBY_VERSION
|
186
|
+
pry_version = RUBY_VERSION > '1.8.7' ? '0.10.0' : '0.9.12'
|
184
187
|
|
185
188
|
# Pry 0.10.0 breaks compatibility with Ruby 1.8.7 :(
|
186
189
|
f.puts " gem 'pry', '~> #{pry_version}'"
|
187
|
-
f.puts " gem 'pry-byebug'" if RUBY_VERSION >= "2.0.0" && RUBY_ENGINE == "ruby"
|
188
|
-
f.puts " gem 'pry-stack_explorer'" if RUBY_ENGINE == "ruby"
|
190
|
+
f.puts " gem 'pry-byebug'" if defined?(RUBY_ENGINE) && RUBY_VERSION >= "2.0.0" && RUBY_ENGINE == "ruby"
|
191
|
+
f.puts " gem 'pry-stack_explorer'" if defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby"
|
189
192
|
end
|
190
193
|
end
|
191
194
|
puts yellow("Gemfile.#{env_index} set to:") if verbose?
|
@@ -20,6 +20,18 @@ class AgentAttributesTest < Minitest::Test
|
|
20
20
|
refute_browser_monitoring_has_agent_attribute("httpResponseCode")
|
21
21
|
end
|
22
22
|
|
23
|
+
def test_response_content_type_default_destinations
|
24
|
+
run_transaction do |txn|
|
25
|
+
txn.response_content_type = 'application/json'
|
26
|
+
end
|
27
|
+
|
28
|
+
assert_transaction_trace_has_agent_attribute("response.headers.contentType", "application/json")
|
29
|
+
assert_event_has_agent_attribute("response.headers.contentType", "application/json")
|
30
|
+
assert_error_has_agent_attribute("response.headers.contentType", "application/json")
|
31
|
+
|
32
|
+
refute_browser_monitoring_has_agent_attribute("response.headers.contentType")
|
33
|
+
end
|
34
|
+
|
23
35
|
def test_request_headers_referer_default_destinations
|
24
36
|
txn_options = {:request => stub(:referer => "referrer", :path => "/")}
|
25
37
|
run_transaction({}, txn_options) do |txn|
|
@@ -55,6 +67,51 @@ class AgentAttributesTest < Minitest::Test
|
|
55
67
|
refute_browser_monitoring_has_agent_attribute("request.parameters.duly")
|
56
68
|
end
|
57
69
|
|
70
|
+
def test_agent_attributes_assigned_from_request
|
71
|
+
request = stub(
|
72
|
+
:path => "/",
|
73
|
+
:referer => "http://docs.newrelic.com",
|
74
|
+
:env => {"HTTP_ACCEPT" => "application/json"},
|
75
|
+
:content_length => 103,
|
76
|
+
:host => 'chippy',
|
77
|
+
:user_agent => 'Use This!',
|
78
|
+
:request_method => "GET"
|
79
|
+
)
|
80
|
+
|
81
|
+
run_transaction({}, {:request => request}) do |txn|
|
82
|
+
end
|
83
|
+
|
84
|
+
assert_error_has_agent_attribute "request.headers.referer", "http://docs.newrelic.com"
|
85
|
+
refute_transaction_trace_has_agent_attribute "request.headers.referer"
|
86
|
+
refute_event_has_agent_attribute "request.headers.referer"
|
87
|
+
refute_browser_monitoring_has_agent_attribute "request.headers.referer"
|
88
|
+
|
89
|
+
assert_transaction_trace_has_agent_attribute "request.headers.accept", "application/json"
|
90
|
+
assert_event_has_agent_attribute "request.headers.accept", "application/json"
|
91
|
+
assert_error_has_agent_attribute "request.headers.accept", "application/json"
|
92
|
+
refute_browser_monitoring_has_agent_attribute "request.headers.accept"
|
93
|
+
|
94
|
+
assert_transaction_trace_has_agent_attribute "request.headers.contentLength", 103
|
95
|
+
assert_event_has_agent_attribute "request.headers.contentLength", 103
|
96
|
+
assert_error_has_agent_attribute "request.headers.contentLength", 103
|
97
|
+
refute_browser_monitoring_has_agent_attribute "request.headers.contentLength"
|
98
|
+
|
99
|
+
assert_transaction_trace_has_agent_attribute "request.headers.host", "chippy"
|
100
|
+
assert_event_has_agent_attribute "request.headers.host", "chippy"
|
101
|
+
assert_error_has_agent_attribute "request.headers.host", "chippy"
|
102
|
+
refute_browser_monitoring_has_agent_attribute "request.headers.host"
|
103
|
+
|
104
|
+
assert_transaction_trace_has_agent_attribute "request.headers.userAgent", "Use This!"
|
105
|
+
assert_event_has_agent_attribute "request.headers.userAgent", "Use This!"
|
106
|
+
assert_error_has_agent_attribute "request.headers.userAgent", "Use This!"
|
107
|
+
refute_browser_monitoring_has_agent_attribute "request.headers.userAgent"
|
108
|
+
|
109
|
+
assert_transaction_trace_has_agent_attribute "request.method", "GET"
|
110
|
+
assert_event_has_agent_attribute "request.method", "GET"
|
111
|
+
assert_error_has_agent_attribute "request.method", "GET"
|
112
|
+
refute_browser_monitoring_has_agent_attribute "request.method"
|
113
|
+
end
|
114
|
+
|
58
115
|
def test_custom_attributes_included
|
59
116
|
run_transaction do
|
60
117
|
NewRelic::Agent.add_custom_attributes(:foo => 'bar')
|
@@ -39,9 +39,8 @@ class AuditLogTest < Minitest::Test
|
|
39
39
|
def test_logs_request_bodies_human_readably_ish
|
40
40
|
run_agent(:'audit_log.enabled' => true) do
|
41
41
|
perform_actions
|
42
|
-
format = NewRelic::Agent::NewRelicService::JsonMarshaller.is_supported? ? :json : :pruby
|
43
42
|
$collector.agent_data.each do |req|
|
44
|
-
assert_audit_log_contains_object(audit_log_contents, req.body
|
43
|
+
assert_audit_log_contains_object(audit_log_contents, req.body)
|
45
44
|
end
|
46
45
|
end
|
47
46
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is distributed under New Relic's license terms.
|
3
|
+
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
|
+
|
5
|
+
class ErrorEventsTest < Minitest::Test
|
6
|
+
include MultiverseHelpers
|
7
|
+
|
8
|
+
setup_and_teardown_agent
|
9
|
+
|
10
|
+
def test_error_events_are_submitted
|
11
|
+
txn = generate_errors
|
12
|
+
|
13
|
+
NewRelic::Agent.agent.send(:harvest_and_send_error_event_data)
|
14
|
+
|
15
|
+
intrinsics, _, _ = last_error_event
|
16
|
+
|
17
|
+
assert_equal txn.best_name, intrinsics["transactionName"]
|
18
|
+
assert_equal "RuntimeError", intrinsics["error.class"]
|
19
|
+
assert_equal "Big Controller", intrinsics["error.message"]
|
20
|
+
assert_equal "TransactionError", intrinsics["type"]
|
21
|
+
if RUBY_VERSION == '1.8.7'
|
22
|
+
# 1.8 + JSON is finicky about comparing floats.
|
23
|
+
# If the timestamps are within 0.001 seconds, it's Good Enough.
|
24
|
+
assert_in_delta(txn.payload[:duration], intrinsics["duration"], 0.001)
|
25
|
+
else
|
26
|
+
assert_equal txn.payload[:duration], intrinsics["duration"]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_records_supportability_metrics
|
31
|
+
with_config :'error_collector.max_event_samples_stored' => 10 do
|
32
|
+
generate_errors 15
|
33
|
+
|
34
|
+
NewRelic::Agent.agent.send(:harvest_and_send_error_event_data)
|
35
|
+
|
36
|
+
assert_metrics_recorded({
|
37
|
+
"Supportability/Events/TransactionError/Sent" => {:call_count => 10},
|
38
|
+
"Supportability/Events/TransactionError/Seen" => {:call_count => 15}
|
39
|
+
})
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_does_not_record_error_events_when_disabled
|
44
|
+
with_config :'error_collector.capture_events' => false do
|
45
|
+
generate_errors 5
|
46
|
+
|
47
|
+
NewRelic::Agent.agent.send(:harvest_and_send_error_event_data)
|
48
|
+
assert_equal(0, $collector.calls_for(:error_event_data).size)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_does_not_record_error_events_when_disabled_by_feature_gate
|
53
|
+
connect_response = {
|
54
|
+
'agent_run_id' => 1,
|
55
|
+
'collect_error_events' => false
|
56
|
+
}
|
57
|
+
|
58
|
+
$collector.stub('connect', connect_response)
|
59
|
+
trigger_agent_reconnect
|
60
|
+
|
61
|
+
generate_errors 5
|
62
|
+
|
63
|
+
NewRelic::Agent.agent.send(:harvest_and_send_error_event_data)
|
64
|
+
assert_equal(0, $collector.calls_for(:error_event_data).size)
|
65
|
+
end
|
66
|
+
|
67
|
+
def generate_errors num_errors = 1
|
68
|
+
in_transaction :transaction_name => "Controller/blogs/index" do |t|
|
69
|
+
num_errors.times { t.notice_error RuntimeError.new "Big Controller" }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def last_error_event
|
74
|
+
post = last_error_event_post
|
75
|
+
assert_equal(1, post.error_events.size)
|
76
|
+
post.error_events.last
|
77
|
+
end
|
78
|
+
|
79
|
+
def last_error_event_post
|
80
|
+
$collector.calls_for(:error_event_data).first
|
81
|
+
end
|
82
|
+
end
|
@@ -23,8 +23,15 @@ class HarvestTimestampsTest < Minitest::Test
|
|
23
23
|
metric_data_post = $collector.calls_for('metric_data').first
|
24
24
|
start_ts, end_ts = metric_data_post[1..2]
|
25
25
|
|
26
|
-
|
27
|
-
|
26
|
+
if RUBY_VERSION == '1.8.7'
|
27
|
+
# 1.8 + JSON is finicky about comparing floats.
|
28
|
+
# If the timestamps are within 0.001 seconds, it's Good Enough.
|
29
|
+
assert_in_delta(t1.to_f, start_ts, 0.001)
|
30
|
+
assert_in_delta(t2.to_f, end_ts, 0.001)
|
31
|
+
else
|
32
|
+
assert_equal(t1.to_f, start_ts)
|
33
|
+
assert_equal(t2.to_f, end_ts)
|
34
|
+
end
|
28
35
|
end
|
29
36
|
|
30
37
|
def test_start_timestamp_maintained_on_harvest_failure
|
@@ -43,8 +50,17 @@ class HarvestTimestampsTest < Minitest::Test
|
|
43
50
|
trigger_metric_data_post
|
44
51
|
second_post = last_metric_data_post
|
45
52
|
|
46
|
-
|
47
|
-
|
53
|
+
if RUBY_VERSION == '1.8.7'
|
54
|
+
# 1.8 + JSON is finicky about comparing floats.
|
55
|
+
# If the timestamps are within 0.001 seconds, it's Good Enough.
|
56
|
+
assert_in_delta(t0, first_post[1], 0.001)
|
57
|
+
assert_in_delta(t1, first_post[2], 0.001)
|
58
|
+
assert_in_delta(t0, second_post[1], 0.001)
|
59
|
+
assert_in_delta(t2, second_post[2], 0.001)
|
60
|
+
else
|
61
|
+
assert_equal([t0, t1], first_post[1..2])
|
62
|
+
assert_equal([t0, t2], second_post[1..2])
|
63
|
+
end
|
48
64
|
end
|
49
65
|
|
50
66
|
def test_timestamps_updated_even_if_filling_metric_id_cache_fails
|
@@ -65,8 +81,17 @@ class HarvestTimestampsTest < Minitest::Test
|
|
65
81
|
trigger_metric_data_post
|
66
82
|
second_post = last_metric_data_post
|
67
83
|
|
68
|
-
|
69
|
-
|
84
|
+
if RUBY_VERSION == '1.8.7'
|
85
|
+
# 1.8 + JSON is finicky about comparing floats.
|
86
|
+
# If the timestamps are within 0.001 seconds, it's Good Enough.
|
87
|
+
assert_in_delta(t0, first_post[1], 0.001)
|
88
|
+
assert_in_delta(t1, first_post[2], 0.001)
|
89
|
+
assert_in_delta(t1, second_post[1], 0.001)
|
90
|
+
assert_in_delta(t2, second_post[2], 0.001)
|
91
|
+
else
|
92
|
+
assert_equal([t0, t1], first_post[1..2])
|
93
|
+
assert_equal([t1, t2], second_post[1..2])
|
94
|
+
end
|
70
95
|
end
|
71
96
|
|
72
97
|
def trigger_metric_data_post
|