newrelic_rpm 2.8.11 → 2.9.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of newrelic_rpm might be problematic. Click here for more details.
- data/CHANGELOG +267 -0
- data/LICENSE +1 -1
- data/Manifest +142 -0
- data/README.md +138 -0
- data/Rakefile +10 -28
- data/bin/mongrel_rpm +33 -0
- data/cert/cacert.pem +34 -0
- data/init.rb +38 -0
- data/lib/new_relic/agent/agent.rb +160 -347
- data/lib/new_relic/agent/collection_helper.rb +13 -24
- data/lib/new_relic/agent/error_collector.rb +29 -15
- data/lib/new_relic/agent/instrumentation/active_record_instrumentation.rb +63 -76
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +90 -48
- data/lib/new_relic/agent/instrumentation/dispatcher_instrumentation.rb +72 -47
- data/lib/new_relic/agent/instrumentation/error_instrumentation.rb +14 -0
- data/lib/new_relic/agent/instrumentation/merb/controller.rb +10 -1
- data/lib/new_relic/agent/instrumentation/merb/dispatcher.rb +5 -7
- data/lib/new_relic/agent/instrumentation/merb/errors.rb +3 -1
- data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +7 -0
- data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +34 -7
- data/lib/new_relic/agent/instrumentation/rails/dispatcher.rb +20 -12
- data/lib/new_relic/agent/instrumentation/rails/errors.rb +5 -4
- data/lib/new_relic/agent/method_tracer.rb +159 -135
- data/lib/new_relic/agent/patch_const_missing.rb +46 -26
- data/lib/new_relic/agent/sampler.rb +12 -0
- data/lib/new_relic/agent/samplers/cpu_sampler.rb +44 -0
- data/lib/new_relic/agent/samplers/memory_sampler.rb +126 -0
- data/lib/new_relic/agent/samplers/mongrel_sampler.rb +22 -0
- data/lib/new_relic/agent/shim_agent.rb +11 -0
- data/lib/new_relic/agent/stats_engine.rb +85 -46
- data/lib/new_relic/agent/transaction_sampler.rb +63 -38
- data/lib/new_relic/agent/worker_loop.rb +8 -18
- data/lib/new_relic/agent.rb +200 -25
- data/lib/new_relic/commands/deployments.rb +9 -9
- data/lib/new_relic/control/merb.rb +22 -0
- data/lib/new_relic/control/rails.rb +141 -0
- data/lib/new_relic/{config → control}/ruby.rb +13 -2
- data/lib/new_relic/control.rb +424 -0
- data/lib/new_relic/local_environment.rb +201 -79
- data/lib/new_relic/metric_data.rb +7 -0
- data/lib/new_relic/metric_parser/action_mailer.rb +9 -0
- data/lib/new_relic/metric_parser/active_merchant.rb +26 -0
- data/lib/new_relic/metric_parser/active_record.rb +11 -0
- data/lib/new_relic/metric_parser/controller.rb +51 -0
- data/lib/new_relic/metric_parser/controller_cpu.rb +38 -0
- data/lib/new_relic/metric_parser/database.rb +23 -0
- data/lib/new_relic/metric_parser/errors.rb +6 -0
- data/lib/new_relic/metric_parser/mem_cache.rb +12 -0
- data/lib/new_relic/metric_parser/view.rb +61 -0
- data/lib/new_relic/metric_parser/web_service.rb +9 -0
- data/lib/new_relic/metric_parser.rb +107 -0
- data/lib/new_relic/metric_spec.rb +5 -0
- data/lib/new_relic/noticed_error.rb +5 -1
- data/lib/new_relic/rack/metric_app.rb +57 -0
- data/lib/new_relic/rack/newrelic.ru +25 -0
- data/lib/new_relic/rack/newrelic.yml +25 -0
- data/lib/new_relic/rack.rb +5 -0
- data/lib/new_relic/recipes.rb +10 -3
- data/lib/new_relic/stats.rb +130 -144
- data/lib/new_relic/transaction_analysis.rb +7 -8
- data/lib/new_relic/transaction_sample.rb +86 -10
- data/lib/new_relic/version.rb +41 -160
- data/lib/new_relic_api.rb +7 -6
- data/lib/newrelic_rpm.rb +30 -17
- data/lib/tasks/{agent_tests.rake → tests.rake} +1 -1
- data/newrelic.yml +115 -62
- data/newrelic_rpm.gemspec +36 -0
- data/test/active_record_fixtures.rb +55 -0
- data/test/config/newrelic.yml +21 -3
- data/test/config/{test_config.rb → test_control.rb} +14 -10
- data/test/new_relic/agent/active_record_instrumentation_test.rb +189 -0
- data/test/new_relic/agent/agent_test.rb +104 -0
- data/test/new_relic/agent/agent_test_controller.rb +18 -1
- data/test/new_relic/agent/classloader_patch_test.rb +56 -0
- data/test/new_relic/agent/{tc_collection_helper.rb → collection_helper_test.rb} +28 -23
- data/test/new_relic/agent/controller_test.rb +107 -0
- data/test/new_relic/agent/dispatcher_instrumentation_test.rb +70 -0
- data/test/new_relic/agent/error_collector_test.rb +155 -0
- data/test/new_relic/agent/{tc_method_tracer.rb → method_tracer_test.rb} +6 -12
- data/test/new_relic/agent/metric_data_test.rb +56 -0
- data/test/new_relic/agent/stats_engine_test.rb +266 -0
- data/test/new_relic/agent/{tc_transaction_sample_builder.rb → transaction_sample_builder_test.rb} +6 -5
- data/test/new_relic/agent/{tc_transaction_sample.rb → transaction_sample_test.rb} +9 -13
- data/test/new_relic/agent/transaction_sampler_test.rb +317 -0
- data/test/new_relic/agent/{tc_worker_loop.rb → worker_loop_test.rb} +1 -1
- data/test/new_relic/control_test.rb +97 -0
- data/test/new_relic/{tc_deployments_api.rb → deployments_api_test.rb} +8 -4
- data/test/new_relic/environment_test.rb +75 -0
- data/test/new_relic/metric_parser_test.rb +142 -0
- data/test/new_relic/{tc_metric_spec.rb → metric_spec_test.rb} +28 -1
- data/test/new_relic/samplers_test.rb +71 -0
- data/test/new_relic/{tc_shim_agent.rb → shim_agent_test.rb} +1 -1
- data/test/new_relic/stats_test.rb +291 -0
- data/test/new_relic/version_number_test.rb +46 -0
- data/test/test_helper.rb +7 -30
- data/test/ui/newrelic_controller_test.rb +14 -0
- data/test/ui/{tc_newrelic_helper.rb → newrelic_helper_test.rb} +16 -7
- data/ui/controllers/newrelic_controller.rb +17 -3
- data/ui/helpers/newrelic_helper.rb +44 -15
- data/ui/views/layouts/newrelic_default.rhtml +7 -8
- data/ui/views/newrelic/_sample.rhtml +5 -2
- data/ui/views/newrelic/_segment.rhtml +1 -1
- data/ui/views/newrelic/_segment_limit_message.rhtml +1 -0
- data/ui/views/newrelic/_segment_row.rhtml +4 -4
- data/ui/views/newrelic/_show_sample_detail.rhtml +3 -1
- data/ui/views/newrelic/_show_sample_sql.rhtml +2 -1
- data/ui/views/newrelic/explain_sql.rhtml +2 -5
- data/ui/views/newrelic/images/file_icon.png +0 -0
- data/ui/views/newrelic/images/new_relic_rpm_desktop.gif +0 -0
- data/ui/views/newrelic/index.rhtml +21 -13
- data/ui/views/newrelic/javascript/prototype-scriptaculous.js +7288 -0
- data/ui/views/newrelic/show_sample.rhtml +18 -3
- data/ui/views/newrelic/stylesheets/style.css +39 -0
- data/ui/views/newrelic/threads.rhtml +52 -0
- metadata +192 -70
- data/README +0 -136
- data/lib/new_relic/agent/instrumentation/rails/rails.rb +0 -6
- data/lib/new_relic/agent/samplers/cpu.rb +0 -29
- data/lib/new_relic/agent/samplers/memory.rb +0 -53
- data/lib/new_relic/agent/samplers/mongrel.rb +0 -26
- data/lib/new_relic/agent/synchronize.rb +0 -40
- data/lib/new_relic/config/merb.rb +0 -35
- data/lib/new_relic/config/rails.rb +0 -114
- data/lib/new_relic/config.rb +0 -279
- data/lib/new_relic/shim_agent.rb +0 -96
- data/test/new_relic/agent/model_fixture.rb +0 -15
- data/test/new_relic/agent/tc_active_record.rb +0 -90
- data/test/new_relic/agent/tc_agent.rb +0 -148
- data/test/new_relic/agent/tc_controller.rb +0 -77
- data/test/new_relic/agent/tc_dispatcher_instrumentation.rb +0 -52
- data/test/new_relic/agent/tc_error_collector.rb +0 -127
- data/test/new_relic/agent/tc_stats_engine.rb +0 -218
- data/test/new_relic/agent/tc_synchronize.rb +0 -37
- data/test/new_relic/agent/tc_transaction_sampler.rb +0 -302
- data/test/new_relic/tc_config.rb +0 -36
- data/test/new_relic/tc_environment.rb +0 -94
- data/test/new_relic/tc_stats.rb +0 -141
@@ -1,148 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
|
2
|
-
##require 'new_relic/agent/agent'
|
3
|
-
##require 'new_relic/local_environment'
|
4
|
-
require 'net/http'
|
5
|
-
|
6
|
-
class AgentTests < ActiveSupport::TestCase
|
7
|
-
|
8
|
-
attr_reader :agent
|
9
|
-
|
10
|
-
# Fake out the agent to think mongrel is running
|
11
|
-
def setup
|
12
|
-
@agent = NewRelic::Agent.instance
|
13
|
-
@agent.start :test, :test
|
14
|
-
end
|
15
|
-
|
16
|
-
# Remove the port method so it won't think mongrel
|
17
|
-
# is available
|
18
|
-
def teardown
|
19
|
-
@agent.shutdown
|
20
|
-
super
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_public_apis
|
24
|
-
begin
|
25
|
-
NewRelic::Agent.set_sql_obfuscator(:unknown) do |sql|
|
26
|
-
puts sql
|
27
|
-
end
|
28
|
-
fail
|
29
|
-
rescue
|
30
|
-
# ok
|
31
|
-
end
|
32
|
-
|
33
|
-
|
34
|
-
ignore_called = false
|
35
|
-
NewRelic::Agent.ignore_error_filter do |e|
|
36
|
-
ignore_called = true
|
37
|
-
nil
|
38
|
-
end
|
39
|
-
|
40
|
-
NewRelic::Agent.agent.error_collector.notice_error('path', nil, {:x => 'y'}, ActionController::RoutingError.new("message"))
|
41
|
-
|
42
|
-
assert ignore_called
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_startup_shutdown
|
46
|
-
@agent.shutdown
|
47
|
-
assert (not @agent.started?)
|
48
|
-
@agent.start "ruby", "test1"
|
49
|
-
assert @agent.started?
|
50
|
-
@agent.shutdown
|
51
|
-
@agent.start "ruby", "test2"
|
52
|
-
end
|
53
|
-
def test_setup_log_default
|
54
|
-
assert @agent.log.instance_of?(Logger), @agent.log
|
55
|
-
logfile = @agent.log.instance_eval { @logdev.filename }
|
56
|
-
assert_match /\/log\/newrelic_agent\..*\.log$/,logfile
|
57
|
-
@agent.shutdown
|
58
|
-
end
|
59
|
-
|
60
|
-
def test_classloading_patch
|
61
|
-
require 'new_relic/agent/patch_const_missing'
|
62
|
-
ClassLoadingWatcher.set_background_thread(Thread.current)
|
63
|
-
|
64
|
-
NewRelic::Config.instance.log.expects(:error).at_least_once.with{|args| args =~ /Agent background thread.*:FooBar/}
|
65
|
-
NewRelic::Config.instance.log.expects(:error).with{|args| args =~ /Agent background thread.*:FooBaz/}.never
|
66
|
-
|
67
|
-
ClassLoadingWatcher.enable_warning
|
68
|
-
assert_raise NameError do
|
69
|
-
FooBar::Bat
|
70
|
-
end
|
71
|
-
ClassLoadingWatcher.disable_warning
|
72
|
-
assert_raise NameError do
|
73
|
-
FooBaz::Bat
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def test_require
|
78
|
-
require 'new_relic/agent/patch_const_missing'
|
79
|
-
ClassLoadingWatcher.set_background_thread(Thread.current)
|
80
|
-
|
81
|
-
# try loading some non-existent class
|
82
|
-
NewRelic::Config.instance.log.expects(:error).at_least_once.with{|args| args =~ /Agent background thread.*net/}
|
83
|
-
NewRelic::Config.instance.log.expects(:error).with{|args| args =~ /Agent background thread.*net/}.never
|
84
|
-
|
85
|
-
ClassLoadingWatcher.enable_warning
|
86
|
-
|
87
|
-
require 'net/http'
|
88
|
-
|
89
|
-
ClassLoadingWatcher.disable_warning
|
90
|
-
|
91
|
-
require 'net/http'
|
92
|
-
end
|
93
|
-
|
94
|
-
def test_load
|
95
|
-
require 'new_relic/agent/patch_const_missing'
|
96
|
-
ClassLoadingWatcher.set_background_thread(Thread.current)
|
97
|
-
|
98
|
-
# try loading some non-existent class
|
99
|
-
NewRelic::Config.instance.log.expects(:error).at_least_once.with{|args| args =~ /Agent background thread.*/}
|
100
|
-
NewRelic::Config.instance.log.expects(:error).with{|args| args =~ /Agent background thread.*/}.never
|
101
|
-
|
102
|
-
ClassLoadingWatcher.enable_warning
|
103
|
-
|
104
|
-
load 'net/http.rb'
|
105
|
-
|
106
|
-
ClassLoadingWatcher.disable_warning
|
107
|
-
|
108
|
-
load 'net/http.rb'
|
109
|
-
end
|
110
|
-
|
111
|
-
def test_info
|
112
|
-
props = NewRelic::Config.instance.app_config_info
|
113
|
-
list = props.assoc('Plugin List').last.sort
|
114
|
-
assert_not_nil list # can't really guess what might be in here.
|
115
|
-
assert_match /jdbc|postgres|mysql|sqlite/, props.assoc('Database adapter').last
|
116
|
-
end
|
117
|
-
def test_version
|
118
|
-
assert_match /\d\.\d\.\d+/, NewRelic::VERSION::STRING
|
119
|
-
end
|
120
|
-
|
121
|
-
def test_invoke_remote__ignore_non_200_results
|
122
|
-
NewRelic::Agent::Agent.class_eval do
|
123
|
-
public :invoke_remote
|
124
|
-
end
|
125
|
-
response_mock = mock()
|
126
|
-
Net::HTTP.any_instance.stubs(:request).returns(response_mock)
|
127
|
-
response_mock.stubs(:message).returns("bogus error")
|
128
|
-
|
129
|
-
for code in %w[500 504 400 302 503] do
|
130
|
-
assert_raise NewRelic::Agent::IgnoreSilentlyException, "Ignore #{code}" do
|
131
|
-
response_mock.stubs(:code).returns(code)
|
132
|
-
NewRelic::Agent.agent.invoke_remote :get_data_report_period, 0
|
133
|
-
end
|
134
|
-
end
|
135
|
-
end
|
136
|
-
def test_invoke_remote__throw_other_errors
|
137
|
-
NewRelic::Agent::Agent.class_eval do
|
138
|
-
public :invoke_remote
|
139
|
-
end
|
140
|
-
response_mock = Net::HTTPSuccess.new nil, nil, nil
|
141
|
-
response_mock.stubs(:body).returns("")
|
142
|
-
Marshal.stubs(:load).raises(RuntimeError, "marshal issue")
|
143
|
-
Net::HTTP.any_instance.stubs(:request).returns(response_mock)
|
144
|
-
assert_raise RuntimeError do
|
145
|
-
NewRelic::Agent.agent.invoke_remote :get_data_report_period, 0xFEFE
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
@@ -1,77 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
|
2
|
-
require 'action_controller/base'
|
3
|
-
#require 'new_relic/agent/agent_test_controller'
|
4
|
-
|
5
|
-
class AgentControllerTests < ActionController::TestCase
|
6
|
-
|
7
|
-
self.controller_class = NewRelic::Agent::AgentTestController
|
8
|
-
|
9
|
-
attr_accessor :agent
|
10
|
-
|
11
|
-
def setup
|
12
|
-
super
|
13
|
-
Thread.current[:controller_ignored] = nil
|
14
|
-
@agent = NewRelic::Agent.instance
|
15
|
-
# @agent.instrument_app
|
16
|
-
agent.start :test, :test
|
17
|
-
agent.transaction_sampler.harvest_slowest_sample
|
18
|
-
NewRelic::Agent::AgentTestController.class_eval do
|
19
|
-
newrelic_ignore :only => [:action_to_ignore, :entry_action]
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
def teardown
|
24
|
-
NewRelic::Agent.instance.shutdown
|
25
|
-
Thread.current[:controller_ignored] = nil
|
26
|
-
super
|
27
|
-
end
|
28
|
-
def test_metric__ignore
|
29
|
-
engine = @agent.stats_engine
|
30
|
-
get :action_to_ignore
|
31
|
-
assert_equal true, Thread.current[:controller_ignored]
|
32
|
-
end
|
33
|
-
def test_metric__no_ignore
|
34
|
-
engine = @agent.stats_engine
|
35
|
-
index_stats = engine.get_stats_no_scope('Controller/new_relic/agent/agent_test/index')
|
36
|
-
assert_difference 'index_stats.call_count' do
|
37
|
-
get :index
|
38
|
-
end
|
39
|
-
assert_equal false, Thread.current[:controller_ignored]
|
40
|
-
end
|
41
|
-
def test_metric__dispatched
|
42
|
-
engine = @agent.stats_engine
|
43
|
-
get :entry_action
|
44
|
-
assert_equal false, Thread.current[:controller_ignored]
|
45
|
-
assert_nil engine.lookup_stat('Controller/agent_test/entry_action')
|
46
|
-
assert_equal 1, engine.lookup_stat('Controller/new_relic/agent/agent_test/internal_action').call_count
|
47
|
-
end
|
48
|
-
def test_action_instrumentation
|
49
|
-
begin
|
50
|
-
get :index, :foo => 'bar'
|
51
|
-
assert_match /bar/, @response.body
|
52
|
-
#rescue ActionController::RoutingError
|
53
|
-
# you might get here if you don't have the default route installed.
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def test_controller_params
|
58
|
-
|
59
|
-
assert agent.transaction_sampler
|
60
|
-
|
61
|
-
num_samples = NewRelic::Agent.instance.transaction_sampler.get_samples.length
|
62
|
-
|
63
|
-
assert_equal "[FILTERED]", @controller._filter_parameters({'social_security_number' => 'test'})['social_security_number']
|
64
|
-
|
65
|
-
get :index, 'social_security_number' => "001-555-1212"
|
66
|
-
|
67
|
-
samples = agent.transaction_sampler.get_samples
|
68
|
-
|
69
|
-
agent.transaction_sampler.expects(:notice_transaction).never
|
70
|
-
|
71
|
-
assert_equal num_samples + 1, samples.length
|
72
|
-
|
73
|
-
assert_equal "[FILTERED]", samples.last.params[:request_params]["social_security_number"]
|
74
|
-
|
75
|
-
end
|
76
|
-
|
77
|
-
end
|
@@ -1,52 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
|
2
|
-
|
3
|
-
class NewRelic::Agent::DispatcherInstrumentationTests < Test::Unit::TestCase
|
4
|
-
|
5
|
-
class FunnyDispatcher
|
6
|
-
include NewRelic::Agent::Instrumentation::DispatcherInstrumentation
|
7
|
-
end
|
8
|
-
def setup
|
9
|
-
@instance_busy = NewRelic::Agent.agent.stats_engine.get_stats('Instance/Busy')
|
10
|
-
@dispatch_stat = NewRelic::Agent.agent.stats_engine.get_stats 'Rails/HTTP Dispatch'
|
11
|
-
@mongrel_queue_stat = NewRelic::Agent.agent.stats_engine.get_stats 'WebFrontend/Mongrel/Average Queue Time'
|
12
|
-
|
13
|
-
NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.harvest_busy
|
14
|
-
@instance_busy.reset
|
15
|
-
@dispatch_stat.reset
|
16
|
-
@mongrel_queue_stat.reset
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_normal_call
|
21
|
-
d = FunnyDispatcher.new
|
22
|
-
assert !NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.is_busy?
|
23
|
-
d.newrelic_dispatcher_start
|
24
|
-
sleep 1.0
|
25
|
-
assert NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.is_busy?
|
26
|
-
d.newrelic_dispatcher_finish
|
27
|
-
assert !NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.is_busy?
|
28
|
-
assert_nil Thread.current[:newrelic_t0]
|
29
|
-
NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.harvest_busy
|
30
|
-
|
31
|
-
assert_equal 1, @instance_busy.call_count
|
32
|
-
assert_equal 1, @dispatch_stat.call_count
|
33
|
-
assert_equal 0, @mongrel_queue_stat.call_count
|
34
|
-
assert @dispatch_stat.total_call_time >= 1.0, "Total call time must be at least one second"
|
35
|
-
assert @instance_busy.total_call_time > 0.9 && @instance_busy.total_call_time <= 1.0, "instance busy = #{@instance_busy.inspect}"
|
36
|
-
end
|
37
|
-
def test_recursive_call
|
38
|
-
d = FunnyDispatcher.new
|
39
|
-
assert !NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.is_busy?
|
40
|
-
d.newrelic_dispatcher_start
|
41
|
-
assert NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.is_busy?
|
42
|
-
d.newrelic_dispatcher_start
|
43
|
-
assert NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.is_busy?
|
44
|
-
d.newrelic_dispatcher_finish
|
45
|
-
assert !NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.is_busy?
|
46
|
-
d.newrelic_dispatcher_finish
|
47
|
-
assert !NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.is_busy?
|
48
|
-
assert_nil Thread.current[:newrelic_t0]
|
49
|
-
NewRelic::Agent::Instrumentation::DispatcherInstrumentation::BusyCalculator.harvest_busy
|
50
|
-
assert_equal 1, @instance_busy.call_count
|
51
|
-
end
|
52
|
-
end
|
@@ -1,127 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
|
2
|
-
##require 'new_relic/agent/error_collector'
|
3
|
-
require 'test/unit'
|
4
|
-
|
5
|
-
class NewRelic::Agent::ErrorCollectorTests < Test::Unit::TestCase
|
6
|
-
|
7
|
-
def setup
|
8
|
-
@error_collector = NewRelic::Agent::ErrorCollector.new(nil)
|
9
|
-
end
|
10
|
-
|
11
|
-
def test_simple
|
12
|
-
@error_collector.notice_error('path', '/myurl/', {:x => 'y'}, Exception.new("message"))
|
13
|
-
|
14
|
-
old_errors = []
|
15
|
-
errors = @error_collector.harvest_errors(old_errors)
|
16
|
-
|
17
|
-
assert_equal errors.length, 1
|
18
|
-
|
19
|
-
err = errors.first
|
20
|
-
assert_equal 'message', err.message
|
21
|
-
assert_equal 'y', err.params[:request_params][:x]
|
22
|
-
assert err.params[:request_uri] == '/myurl/'
|
23
|
-
assert err.path == 'path'
|
24
|
-
assert err.exception_class == 'Exception'
|
25
|
-
|
26
|
-
# the collector should now return an empty array since nothing
|
27
|
-
# has been added since its last harvest
|
28
|
-
errors = @error_collector.harvest_errors(nil)
|
29
|
-
assert errors.length == 0
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_collect_failover
|
33
|
-
@error_collector.notice_error('first', nil, {:x => 'y'}, Exception.new("message"))
|
34
|
-
|
35
|
-
errors = @error_collector.harvest_errors([])
|
36
|
-
|
37
|
-
@error_collector.notice_error('second', nil, {:x => 'y'}, Exception.new("message"))
|
38
|
-
@error_collector.notice_error('path', nil, {:x => 'y'}, Exception.new("message"))
|
39
|
-
@error_collector.notice_error('path', nil, {:x => 'y'}, Exception.new("message"))
|
40
|
-
|
41
|
-
errors = @error_collector.harvest_errors(errors)
|
42
|
-
|
43
|
-
assert_equal 1, errors.length
|
44
|
-
assert_equal 'first', errors.first.path
|
45
|
-
|
46
|
-
# add two more
|
47
|
-
@error_collector.notice_error('path', nil, {:x => 'y'}, Exception.new("message"))
|
48
|
-
@error_collector.notice_error('last', nil, {:x => 'y'}, Exception.new("message"))
|
49
|
-
|
50
|
-
errors = @error_collector.harvest_errors(nil)
|
51
|
-
assert_equal 5, errors.length
|
52
|
-
assert_equal 'second', errors.first.path
|
53
|
-
assert_equal 'last', errors.last.path
|
54
|
-
|
55
|
-
end
|
56
|
-
|
57
|
-
def test_queue_overflow
|
58
|
-
|
59
|
-
max_q_length = 20 # for some reason I can't read the constant in ErrorCollector
|
60
|
-
|
61
|
-
silence_stream(::STDERR) do
|
62
|
-
(max_q_length + 5).times do |n|
|
63
|
-
@error_collector.notice_error("path", nil, {:x => n}, Exception.new("exception #{n}"))
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
errors = @error_collector.harvest_errors([])
|
68
|
-
assert errors.length == max_q_length
|
69
|
-
errors.each_index do |i|
|
70
|
-
err = errors.shift
|
71
|
-
assert_equal i.to_s, err.params[:request_params][:x], err.params.inspect
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
# Why would anyone undef these methods?
|
76
|
-
class TestClass
|
77
|
-
undef to_s
|
78
|
-
undef inspect
|
79
|
-
end
|
80
|
-
|
81
|
-
|
82
|
-
def test_supported_param_types
|
83
|
-
|
84
|
-
types = [[1, '1'],
|
85
|
-
[1.1, '1.1'],
|
86
|
-
['hi', 'hi'],
|
87
|
-
[:hi, :hi],
|
88
|
-
[Exception.new("test"), "#<Exception: test>"],
|
89
|
-
[TestClass.new, "#<NewRelic::Agent::ErrorCollectorTests::TestClass>"]
|
90
|
-
]
|
91
|
-
|
92
|
-
|
93
|
-
types.each do |test|
|
94
|
-
@error_collector.notice_error('path', nil, {:x => test[0]}, Exception.new("message"))
|
95
|
-
|
96
|
-
assert_equal test[1], @error_collector.harvest_errors([])[0].params[:request_params][:x]
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
|
101
|
-
def test_exclude
|
102
|
-
@error_collector.ignore(["ActionController::RoutingError"])
|
103
|
-
|
104
|
-
@error_collector.notice_error('path', nil, {:x => 'y'}, ActionController::RoutingError.new("message"))
|
105
|
-
|
106
|
-
errors = @error_collector.harvest_errors([])
|
107
|
-
|
108
|
-
assert_equal 0, errors.length
|
109
|
-
end
|
110
|
-
|
111
|
-
def test_exclude_block
|
112
|
-
@error_collector.ignore_error_filter do |e|
|
113
|
-
if e.is_a? ActionController::RoutingError
|
114
|
-
nil
|
115
|
-
else
|
116
|
-
e
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
@error_collector.notice_error('path', nil, {:x => 'y'}, ActionController::RoutingError.new("message"))
|
121
|
-
|
122
|
-
errors = @error_collector.harvest_errors([])
|
123
|
-
|
124
|
-
assert_equal 0, errors.length
|
125
|
-
end
|
126
|
-
|
127
|
-
end
|
@@ -1,218 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__),'..','..','test_helper'))
|
2
|
-
require 'test/unit'
|
3
|
-
##require 'new_relic/agent/stats_engine'
|
4
|
-
|
5
|
-
|
6
|
-
module NewRelic::Agent
|
7
|
-
class StatsEngineTests < Test::Unit::TestCase
|
8
|
-
def setup
|
9
|
-
@engine = StatsEngine.new
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_get_no_scope
|
13
|
-
s1 = @engine.get_stats "a"
|
14
|
-
s2 = @engine.get_stats "a"
|
15
|
-
s3 = @engine.get_stats "b"
|
16
|
-
|
17
|
-
assert_not_nil s1
|
18
|
-
assert_not_nil s2
|
19
|
-
assert_not_nil s3
|
20
|
-
|
21
|
-
assert s1 == s2
|
22
|
-
assert s1 != s3
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_harvest
|
26
|
-
s1 = @engine.get_stats "a"
|
27
|
-
s2 = @engine.get_stats "c"
|
28
|
-
|
29
|
-
s1.trace_call 10
|
30
|
-
s2.trace_call 1
|
31
|
-
s2.trace_call 3
|
32
|
-
|
33
|
-
assert @engine.get_stats("a").call_count == 1
|
34
|
-
assert @engine.get_stats("a").total_call_time == 10
|
35
|
-
|
36
|
-
assert @engine.get_stats("c").call_count == 2
|
37
|
-
assert @engine.get_stats("c").total_call_time == 4
|
38
|
-
|
39
|
-
metric_data = @engine.harvest_timeslice_data({}, {}).values
|
40
|
-
|
41
|
-
# after harvest, all the metrics should be reset
|
42
|
-
assert @engine.get_stats("a").call_count == 0
|
43
|
-
assert @engine.get_stats("a").total_call_time == 0
|
44
|
-
|
45
|
-
assert @engine.get_stats("c").call_count == 0
|
46
|
-
assert @engine.get_stats("c").total_call_time == 0
|
47
|
-
|
48
|
-
metric_data = metric_data.reverse if metric_data[0].metric_spec.name != "a"
|
49
|
-
|
50
|
-
assert metric_data[0].metric_spec.name == "a"
|
51
|
-
|
52
|
-
assert metric_data[0].stats.call_count == 1
|
53
|
-
assert metric_data[0].stats.total_call_time == 10
|
54
|
-
end
|
55
|
-
|
56
|
-
def test_harvest_with_merge
|
57
|
-
s = @engine.get_stats "a"
|
58
|
-
s.trace_call 1
|
59
|
-
|
60
|
-
assert @engine.get_stats("a").call_count == 1
|
61
|
-
|
62
|
-
harvest = @engine.harvest_timeslice_data({}, {})
|
63
|
-
assert s.call_count == 0
|
64
|
-
s.trace_call 2
|
65
|
-
assert s.call_count == 1
|
66
|
-
|
67
|
-
# this calk should merge the contents of the previous harvest,
|
68
|
-
# so the stats for metric "a" should have 2 data points
|
69
|
-
harvest = @engine.harvest_timeslice_data(harvest, {})
|
70
|
-
stats = harvest.fetch(NewRelic::MetricSpec.new("a")).stats
|
71
|
-
assert stats.call_count == 2
|
72
|
-
assert stats.total_call_time == 3
|
73
|
-
end
|
74
|
-
|
75
|
-
def test_scope
|
76
|
-
@engine.push_scope "scope1"
|
77
|
-
assert @engine.peek_scope.name == "scope1"
|
78
|
-
|
79
|
-
expected = @engine.push_scope "scope2"
|
80
|
-
@engine.pop_scope expected, 0
|
81
|
-
|
82
|
-
scoped = @engine.get_stats "a"
|
83
|
-
scoped.trace_call 3
|
84
|
-
|
85
|
-
assert scoped.total_call_time == 3
|
86
|
-
unscoped = @engine.get_stats "a"
|
87
|
-
|
88
|
-
assert scoped == @engine.get_stats("a")
|
89
|
-
assert unscoped.total_call_time == 3
|
90
|
-
end
|
91
|
-
|
92
|
-
|
93
|
-
def test_simplethrowcase(depth=0)
|
94
|
-
|
95
|
-
fail "doh" if depth == 10
|
96
|
-
|
97
|
-
scope = @engine.push_scope "scope#{depth}"
|
98
|
-
|
99
|
-
begin
|
100
|
-
test_simplethrowcase(depth+1)
|
101
|
-
rescue StandardError => e
|
102
|
-
if (depth != 0)
|
103
|
-
raise e
|
104
|
-
end
|
105
|
-
ensure
|
106
|
-
@engine.pop_scope scope, 0
|
107
|
-
end
|
108
|
-
|
109
|
-
if depth == 0
|
110
|
-
assert @engine.peek_scope.nil?
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
|
115
|
-
def test_scope_failure
|
116
|
-
scope1 = @engine.push_scope "scope1"
|
117
|
-
@engine.push_scope "scope2"
|
118
|
-
|
119
|
-
begin
|
120
|
-
@engine.pop_scope scope1
|
121
|
-
fail "Didn't throw when scope push/pop mismatched"
|
122
|
-
rescue
|
123
|
-
# success
|
124
|
-
end
|
125
|
-
end
|
126
|
-
|
127
|
-
def test_children_time
|
128
|
-
t1 = Time.now
|
129
|
-
|
130
|
-
expected1 = @engine.push_scope "a"
|
131
|
-
sleep 0.1
|
132
|
-
t2 = Time.now
|
133
|
-
|
134
|
-
expected2 = @engine.push_scope "b"
|
135
|
-
sleep 0.2
|
136
|
-
t3 = Time.now
|
137
|
-
|
138
|
-
expected = @engine.push_scope "c"
|
139
|
-
sleep 0.3
|
140
|
-
scope = @engine.pop_scope expected, Time.now - t3
|
141
|
-
|
142
|
-
t4 = Time.now
|
143
|
-
|
144
|
-
check_time_approximate 0, scope.children_time
|
145
|
-
check_time_approximate 0.3, @engine.peek_scope.children_time
|
146
|
-
|
147
|
-
sleep 0.1
|
148
|
-
t5 = Time.now
|
149
|
-
|
150
|
-
expected = @engine.push_scope "d"
|
151
|
-
sleep 0.2
|
152
|
-
scope = @engine.pop_scope expected, Time.now - t5
|
153
|
-
|
154
|
-
t6 = Time.now
|
155
|
-
|
156
|
-
check_time_approximate 0, scope.children_time
|
157
|
-
|
158
|
-
scope = @engine.pop_scope expected2, Time.now - t2
|
159
|
-
assert_equal scope.name, 'b'
|
160
|
-
|
161
|
-
check_time_approximate (t4 - t3) + (t6 - t5), scope.children_time
|
162
|
-
|
163
|
-
scope = @engine.pop_scope expected1, Time.now - t1
|
164
|
-
assert_equal scope.name, 'a'
|
165
|
-
|
166
|
-
check_time_approximate (t6 - t2), scope.children_time
|
167
|
-
end
|
168
|
-
|
169
|
-
def test_simple_start_transaction
|
170
|
-
@engine.push_scope "scope"
|
171
|
-
@engine.start_transaction
|
172
|
-
assert @engine.peek_scope.nil?
|
173
|
-
end
|
174
|
-
|
175
|
-
|
176
|
-
# test for when the scope stack contains an element only used for tts and not metrics
|
177
|
-
def test_simple_tt_only_scope
|
178
|
-
scope1 = @engine.push_scope "a", 0, true
|
179
|
-
scope2 = @engine.push_scope "b", 10, false
|
180
|
-
scope3 = @engine.push_scope "c", 20, true
|
181
|
-
|
182
|
-
@engine.pop_scope scope3, 10
|
183
|
-
@engine.pop_scope scope2, 10
|
184
|
-
@engine.pop_scope scope1, 10
|
185
|
-
|
186
|
-
assert_equal 0, scope3.children_time
|
187
|
-
assert_equal 10, scope2.children_time
|
188
|
-
assert_equal 10, scope1.children_time
|
189
|
-
end
|
190
|
-
|
191
|
-
def test_double_tt_only_scope
|
192
|
-
scope1 = @engine.push_scope "a", 0, true
|
193
|
-
scope2 = @engine.push_scope "b", 10, false
|
194
|
-
scope3 = @engine.push_scope "c", 20, false
|
195
|
-
scope4 = @engine.push_scope "d", 30, true
|
196
|
-
|
197
|
-
@engine.pop_scope scope4, 10
|
198
|
-
@engine.pop_scope scope3, 10
|
199
|
-
@engine.pop_scope scope2, 10
|
200
|
-
@engine.pop_scope scope1, 10
|
201
|
-
|
202
|
-
assert_equal 0, scope4.children_time
|
203
|
-
assert_equal 10, scope3.children_time
|
204
|
-
assert_equal 10, scope2.children_time
|
205
|
-
assert_equal 10, scope1.children_time
|
206
|
-
end
|
207
|
-
|
208
|
-
|
209
|
-
private
|
210
|
-
def check_time_approximate(expected, actual)
|
211
|
-
assert((expected - actual).abs < 0.01, "Expected #{expected}, got #{actual}")
|
212
|
-
end
|
213
|
-
|
214
|
-
end
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
end
|