newrelic_rpm 3.6.7.159 → 3.6.8.164
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +14 -0
- data/lib/new_relic/agent/agent.rb +38 -35
- data/lib/new_relic/agent/agent_logger.rb +6 -47
- data/lib/new_relic/agent/beacon_configuration.rb +10 -4
- data/lib/new_relic/agent/browser_monitoring.rb +39 -33
- data/lib/new_relic/agent/commands/agent_command.rb +4 -4
- data/lib/new_relic/agent/commands/agent_command_router.rb +72 -10
- data/lib/new_relic/agent/commands/thread_profiler_session.rb +110 -0
- data/lib/new_relic/agent/commands/xray_session.rb +55 -0
- data/lib/new_relic/agent/commands/xray_session_collection.rb +158 -0
- data/lib/new_relic/agent/configuration/default_source.rb +61 -24
- data/lib/new_relic/agent/configuration/mask_defaults.rb +2 -2
- data/lib/new_relic/agent/configuration/server_source.rb +1 -1
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +2 -0
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +4 -10
- data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +10 -11
- data/lib/new_relic/agent/memory_logger.rb +52 -0
- data/lib/new_relic/agent/new_relic_service.rb +4 -0
- data/lib/new_relic/agent/request_sampler.rb +32 -13
- data/lib/new_relic/agent/samplers/cpu_sampler.rb +6 -3
- data/lib/new_relic/agent/threading/agent_thread.rb +2 -1
- data/lib/new_relic/agent/threading/backtrace_node.rb +80 -27
- data/lib/new_relic/agent/threading/backtrace_service.rb +264 -0
- data/lib/new_relic/agent/threading/thread_profile.rb +79 -118
- data/lib/new_relic/agent/transaction/developer_mode_sample_buffer.rb +56 -0
- data/lib/new_relic/agent/transaction/force_persist_sample_buffer.rb +25 -0
- data/lib/new_relic/agent/transaction/slowest_sample_buffer.rb +25 -0
- data/lib/new_relic/agent/transaction/transaction_sample_buffer.rb +86 -0
- data/lib/new_relic/agent/transaction/xray_sample_buffer.rb +64 -0
- data/lib/new_relic/agent/transaction.rb +25 -4
- data/lib/new_relic/agent/transaction_sample_builder.rb +6 -10
- data/lib/new_relic/agent/transaction_sampler.rb +47 -202
- data/lib/new_relic/agent/worker_loop.rb +47 -39
- data/lib/new_relic/agent.rb +1 -1
- data/lib/new_relic/build.rb +2 -2
- data/lib/new_relic/coerce.rb +8 -0
- data/lib/new_relic/control/instance_methods.rb +1 -0
- data/lib/new_relic/rack/browser_monitoring.rb +15 -1
- data/lib/new_relic/rack/developer_mode.rb +1 -1
- data/lib/new_relic/transaction_sample.rb +20 -5
- data/lib/new_relic/version.rb +1 -1
- data/newrelic.yml +4 -6
- data/newrelic_rpm.gemspec +1 -1
- data/test/agent_helper.rb +11 -0
- data/test/environments/lib/environments/runner.rb +5 -1
- data/test/environments/rails21/Gemfile +2 -2
- data/test/environments/rails22/Gemfile +2 -2
- data/test/environments/rails23/Gemfile +2 -2
- data/test/environments/rails31/Gemfile +2 -2
- data/test/environments/rails32/Gemfile +2 -2
- data/test/multiverse/suites/agent_only/marshaling_test.rb +1 -1
- data/test/multiverse/suites/agent_only/testing_app.rb +6 -0
- data/test/multiverse/suites/agent_only/thread_profiling_test.rb +5 -5
- data/test/multiverse/suites/agent_only/xray_sessions_test.rb +163 -0
- data/test/multiverse/suites/rails/request_statistics_test.rb +2 -2
- data/test/multiverse/suites/rails/view_instrumentation_test.rb +20 -21
- data/test/new_relic/agent/agent/connect_test.rb +0 -10
- data/test/new_relic/agent/agent_test.rb +27 -44
- data/test/new_relic/agent/browser_monitoring_test.rb +0 -52
- data/test/new_relic/agent/commands/agent_command_router_test.rb +150 -12
- data/test/new_relic/agent/commands/{thread_profiler_test.rb → thread_profiler_session_test.rb} +58 -19
- data/test/new_relic/agent/commands/xray_session_collection_test.rb +332 -0
- data/test/new_relic/agent/commands/xray_session_test.rb +42 -0
- data/test/new_relic/agent/configuration/manager_test.rb +2 -1
- data/test/new_relic/agent/configuration/server_source_test.rb +10 -10
- data/test/new_relic/agent/cpu_sampler_test.rb +50 -0
- data/test/new_relic/agent/instrumentation/action_controller_subscriber_test.rb +31 -0
- data/test/new_relic/agent/instrumentation/queue_time_test.rb +0 -1
- data/test/new_relic/agent/instrumentation/sequel_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +0 -1
- data/test/new_relic/agent/memory_logger_test.rb +53 -0
- data/test/new_relic/agent/new_relic_service_test.rb +1 -1
- data/test/new_relic/agent/pipe_channel_manager_test.rb +4 -5
- data/test/new_relic/agent/request_sampler_test.rb +70 -20
- data/test/new_relic/agent/rules_engine_test.rb +6 -0
- data/test/new_relic/agent/threading/agent_thread_test.rb +2 -2
- data/test/new_relic/agent/threading/backtrace_node_test.rb +110 -17
- data/test/new_relic/agent/threading/backtrace_service_test.rb +567 -0
- data/test/new_relic/agent/threading/fake_thread.rb +4 -0
- data/test/new_relic/agent/threading/thread_profile_test.rb +141 -217
- data/test/new_relic/agent/threading/threaded_test_case.rb +3 -8
- data/test/new_relic/agent/transaction/developer_mode_sample_buffer_test.rb +69 -0
- data/test/new_relic/agent/transaction/force_persist_sample_buffer_test.rb +52 -0
- data/test/new_relic/agent/transaction/slowest_sample_buffer_test.rb +67 -0
- data/test/new_relic/agent/transaction/xray_sample_buffer_test.rb +71 -0
- data/test/new_relic/agent/transaction_sampler_test.rb +171 -307
- data/test/new_relic/agent/transaction_test.rb +33 -5
- data/test/new_relic/agent/worker_loop_test.rb +33 -11
- data/test/new_relic/coerce_test.rb +13 -0
- data/test/new_relic/fake_collector.rb +26 -3
- data/test/new_relic/multiverse_helpers.rb +2 -0
- data/test/new_relic/rack/browser_monitoring_test.rb +12 -0
- data/test/new_relic/rack/developer_mode_test.rb +2 -2
- data/test/new_relic/transaction_sample_test.rb +19 -2
- data/test/performance/lib/performance/console_reporter.rb +1 -1
- data/test/performance/lib/performance/test_case.rb +7 -3
- data/test/performance/script/runner +3 -0
- data/test/performance/suites/thread_profiling.rb +83 -0
- data/test/test_helper.rb +2 -2
- data.tar.gz.sig +0 -0
- metadata +32 -32
- metadata.gz.sig +1 -1
- data/lib/new_relic/agent/commands/thread_profiler.rb +0 -80
data/lib/new_relic/agent.rb
CHANGED
@@ -89,7 +89,7 @@ module NewRelic
|
|
89
89
|
require 'new_relic/agent/stats_engine'
|
90
90
|
require 'new_relic/agent/transaction_sampler'
|
91
91
|
require 'new_relic/agent/sql_sampler'
|
92
|
-
require 'new_relic/agent/commands/
|
92
|
+
require 'new_relic/agent/commands/thread_profiler_session'
|
93
93
|
require 'new_relic/agent/error_collector'
|
94
94
|
require 'new_relic/agent/busy_calculator'
|
95
95
|
require 'new_relic/agent/sampler'
|
data/lib/new_relic/build.rb
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
# GITSHA:
|
2
|
-
module NewRelic; module VERSION; BUILD='
|
1
|
+
# GITSHA: 2af3914786d2a12b3cda44aa4f5f453ea1f845f8
|
2
|
+
module NewRelic; module VERSION; BUILD='164'; end; end
|
data/lib/new_relic/coerce.rb
CHANGED
@@ -17,6 +17,14 @@ module NewRelic
|
|
17
17
|
0
|
18
18
|
end
|
19
19
|
|
20
|
+
def int_or_nil(value, context=nil)
|
21
|
+
return nil if value.nil?
|
22
|
+
Integer(value)
|
23
|
+
rescue => error
|
24
|
+
log_failure(value, Integer, context, error)
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
|
20
28
|
def float(value, context=nil)
|
21
29
|
result = Float(value)
|
22
30
|
raise "Value #{result.inspect} is not finite." unless result.finite?
|
@@ -89,9 +89,23 @@ module NewRelic::Rack
|
|
89
89
|
end
|
90
90
|
end
|
91
91
|
end
|
92
|
-
|
92
|
+
|
93
|
+
if headers['Content-Length']
|
94
|
+
headers['Content-Length'] = calculate_content_length(source).to_s
|
95
|
+
end
|
96
|
+
|
93
97
|
source
|
94
98
|
end
|
99
|
+
|
100
|
+
# String does not respond to 'bytesize' in 1.8.6. Fortunately String#length
|
101
|
+
# returns bytes rather than characters in 1.8.6 so we can use that instead.
|
102
|
+
def calculate_content_length(source)
|
103
|
+
if source.respond_to?(:bytesize)
|
104
|
+
source.bytesize
|
105
|
+
else
|
106
|
+
source.length
|
107
|
+
end
|
108
|
+
end
|
95
109
|
end
|
96
110
|
|
97
111
|
end
|
@@ -241,7 +241,7 @@ module NewRelic
|
|
241
241
|
end
|
242
242
|
|
243
243
|
def get_samples
|
244
|
-
@samples = NewRelic::Agent.instance.transaction_sampler.samples.select do |sample|
|
244
|
+
@samples = NewRelic::Agent.instance.transaction_sampler.dev_mode_sample_buffer.samples.select do |sample|
|
245
245
|
sample.params[:path] != nil
|
246
246
|
end
|
247
247
|
|
@@ -15,8 +15,8 @@ module NewRelic
|
|
15
15
|
|
16
16
|
class TransactionSample
|
17
17
|
|
18
|
-
attr_accessor
|
19
|
-
:threshold
|
18
|
+
attr_accessor :params, :root_segment, :profile, :force_persist, :guid,
|
19
|
+
:threshold, :finished, :xray_session_id
|
20
20
|
attr_reader :root_segment, :params, :sample_id
|
21
21
|
|
22
22
|
@@start_time = Time.now
|
@@ -71,12 +71,14 @@ module NewRelic
|
|
71
71
|
trace_tree = encoder.encode(self.to_array)
|
72
72
|
[ Helper.time_to_millis(@start_time),
|
73
73
|
Helper.time_to_millis(duration),
|
74
|
-
string(
|
74
|
+
string(transaction_name),
|
75
75
|
string(@params[:uri]),
|
76
76
|
trace_tree,
|
77
77
|
string(@guid),
|
78
78
|
nil,
|
79
|
-
|
79
|
+
forced?,
|
80
|
+
int_or_nil(xray_session_id)
|
81
|
+
]
|
80
82
|
end
|
81
83
|
|
82
84
|
def start_time
|
@@ -87,9 +89,21 @@ module NewRelic
|
|
87
89
|
@root_segment.path_string
|
88
90
|
end
|
89
91
|
|
92
|
+
def transaction_name
|
93
|
+
@params[:path]
|
94
|
+
end
|
95
|
+
|
96
|
+
def transaction_name=(new_name)
|
97
|
+
@params[:path] = new_name
|
98
|
+
end
|
99
|
+
|
100
|
+
def forced?
|
101
|
+
!!@force_persist || !int_or_nil(xray_session_id).nil?
|
102
|
+
end
|
103
|
+
|
90
104
|
# relative_timestamp is seconds since the start of the transaction
|
91
105
|
def create_segment(relative_timestamp, metric_name=nil, segment_id = nil)
|
92
|
-
raise TypeError.new("Frozen Transaction Sample") if
|
106
|
+
raise TypeError.new("Frozen Transaction Sample") if finished
|
93
107
|
@params[:segment_count] += 1
|
94
108
|
@segment_count += 1
|
95
109
|
NewRelic::TransactionSample::Segment.new(relative_timestamp, metric_name, segment_id)
|
@@ -176,6 +190,7 @@ module NewRelic
|
|
176
190
|
sample.params.merge! self.params
|
177
191
|
sample.guid = self.guid
|
178
192
|
sample.force_persist = self.force_persist if self.force_persist
|
193
|
+
sample.xray_session_id = self.xray_session_id
|
179
194
|
|
180
195
|
build_segment_for_transfer(sample, @root_segment, sample.root_segment, options)
|
181
196
|
|
data/lib/new_relic/version.rb
CHANGED
data/newrelic.yml
CHANGED
@@ -188,18 +188,16 @@ common: &default_settings
|
|
188
188
|
|
189
189
|
development:
|
190
190
|
<<: *default_settings
|
191
|
-
# Turn
|
192
|
-
|
193
|
-
|
194
|
-
# turn the agent on in development mode.
|
195
|
-
monitor_mode: false
|
191
|
+
# Turn on communication to New Relic service in development mode
|
192
|
+
monitor_mode: true
|
193
|
+
app_name: <%= @app_name %> (Development)
|
196
194
|
|
197
195
|
# Rails Only - when running in Developer Mode, the New Relic Agent will
|
198
196
|
# present performance information on the last 100 transactions you have
|
199
197
|
# executed since starting the mongrel.
|
200
198
|
# NOTE: There is substantial overhead when running in developer mode.
|
201
199
|
# Do not use for production or load testing.
|
202
|
-
developer_mode:
|
200
|
+
developer_mode: false
|
203
201
|
|
204
202
|
# Enable textmate links
|
205
203
|
# textmate: true
|
data/newrelic_rpm.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.name = "newrelic_rpm"
|
10
10
|
s.version = NewRelic::VERSION::STRING
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
12
|
-
s.authors = [ "Jason Clark", "Sam Goldstein", "
|
12
|
+
s.authors = [ "Jason Clark", "Sam Goldstein", "Jonan Scheffler", "Ben Weintraub" ]
|
13
13
|
s.date = Time.now.strftime('%Y-%m-%d')
|
14
14
|
s.description = <<-EOS
|
15
15
|
New Relic is a performance management system, developed by New Relic,
|
data/test/agent_helper.rb
CHANGED
@@ -97,6 +97,11 @@ unless defined?( assert_not_includes )
|
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
100
|
+
def assert_equal_unordered(left, right)
|
101
|
+
assert_equal(left.length, right.length, "Lengths don't match. #{left.length} != #{right.length}")
|
102
|
+
left.each { |element| assert_includes(right, element) }
|
103
|
+
end
|
104
|
+
|
100
105
|
def compare_metrics(expected, actual)
|
101
106
|
actual.delete_if {|a| a.include?('GC/cumulative') } # in case we are in REE
|
102
107
|
assert_equal(expected.to_a.sort, actual.to_a.sort, "extra: #{(actual - expected).to_a.inspect}; missing: #{(expected - actual).to_a.inspect}")
|
@@ -184,6 +189,12 @@ def assert_falsy(expected, msg = nil)
|
|
184
189
|
assert_block( msg ) { !expected }
|
185
190
|
end
|
186
191
|
|
192
|
+
unless defined?( assert_false )
|
193
|
+
def assert_false(expected)
|
194
|
+
assert_equal false, expected
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
187
198
|
# Mock up a transaction for testing purposes, optionally specifying a name and
|
188
199
|
# transaction type. The given block will be executed within the context of the
|
189
200
|
# dummy transaction.
|
@@ -87,7 +87,11 @@ module Environments
|
|
87
87
|
|
88
88
|
def bundle(dir)
|
89
89
|
puts "Bundling..."
|
90
|
-
bundling = `cd #{dir} && bundle install`
|
90
|
+
bundling = `cd #{dir} && bundle install --local`
|
91
|
+
unless $?.success?
|
92
|
+
puts "Failed local bundle, trying again with full bundle..."
|
93
|
+
bundling = `cd #{dir} && bundle install`
|
94
|
+
end
|
91
95
|
puts red(bundling) unless $?.success?
|
92
96
|
end
|
93
97
|
|
@@ -13,8 +13,8 @@ gem 'rack-test'
|
|
13
13
|
gem 'newrelic_rpm', :path => "../../.."
|
14
14
|
|
15
15
|
if (RUBY_PLATFORM == 'java')
|
16
|
-
gem "activerecord-jdbcmysql-adapter"
|
17
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
16
|
+
gem "activerecord-jdbcmysql-adapter", "~>1.2.9"
|
17
|
+
gem "activerecord-jdbcsqlite3-adapter", "~>1.2.9"
|
18
18
|
gem "jruby-openssl"
|
19
19
|
else
|
20
20
|
gem "mysql", RUBY_VERSION == '1.8.6' ? '2.7' : '2.8.1'
|
@@ -12,8 +12,8 @@ gem 'rack-test'
|
|
12
12
|
gem 'newrelic_rpm', :path => '../../..'
|
13
13
|
|
14
14
|
if (RUBY_PLATFORM == 'java')
|
15
|
-
gem "activerecord-jdbcmysql-adapter"
|
16
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
15
|
+
gem "activerecord-jdbcmysql-adapter", "~>1.2.9"
|
16
|
+
gem "activerecord-jdbcsqlite3-adapter", "~>1.2.9"
|
17
17
|
gem "jruby-openssl"
|
18
18
|
else
|
19
19
|
gem "sqlite3-ruby", "1.2.5"
|
@@ -11,8 +11,8 @@ gem 'rack-test'
|
|
11
11
|
gem "newrelic_rpm", :path => '../../..'
|
12
12
|
|
13
13
|
if(RUBY_PLATFORM == 'java')
|
14
|
-
gem "activerecord-jdbcmysql-adapter"
|
15
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
14
|
+
gem "activerecord-jdbcmysql-adapter", "~>1.2.9"
|
15
|
+
gem "activerecord-jdbcsqlite3-adapter", "~>1.2.9"
|
16
16
|
gem "jruby-openssl"
|
17
17
|
else
|
18
18
|
gem "mysql", RUBY_VERSION == '1.8.6' ? '2.7' : '2.8.1'
|
@@ -8,8 +8,8 @@ gem 'rack'
|
|
8
8
|
gem 'rack-test'
|
9
9
|
|
10
10
|
if (RUBY_PLATFORM == 'java')
|
11
|
-
gem "activerecord-jdbcmysql-adapter"
|
12
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
11
|
+
gem "activerecord-jdbcmysql-adapter", "~>1.2.9"
|
12
|
+
gem "activerecord-jdbcsqlite3-adapter", "~>1.2.9"
|
13
13
|
gem "jruby-openssl"
|
14
14
|
else
|
15
15
|
gem "mysql"
|
@@ -9,8 +9,8 @@ gem 'rack'
|
|
9
9
|
gem 'rack-test'
|
10
10
|
|
11
11
|
platforms :jruby do
|
12
|
-
gem "activerecord-jdbcmysql-adapter"
|
13
|
-
gem "activerecord-jdbcsqlite3-adapter"
|
12
|
+
gem "activerecord-jdbcmysql-adapter", "~>1.2.9"
|
13
|
+
gem "activerecord-jdbcsqlite3-adapter", "~>1.2.9"
|
14
14
|
gem "jruby-openssl"
|
15
15
|
end
|
16
16
|
|
@@ -28,7 +28,7 @@ class MarshalingTest < MiniTest::Unit::TestCase
|
|
28
28
|
sampler.notice_scope_empty(OpenStruct.new(:name => 'path',
|
29
29
|
:custom_parameters => {}))
|
30
30
|
|
31
|
-
expected_sample = sampler.
|
31
|
+
expected_sample = sampler.last_sample
|
32
32
|
|
33
33
|
agent.service.connect
|
34
34
|
agent.send(:harvest_and_send_slowest_sample)
|
@@ -17,6 +17,12 @@ class TestingApp
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def call(env)
|
20
|
+
request = Rack::Request.new(env)
|
21
|
+
params = request.params
|
22
|
+
if params['transaction_name']
|
23
|
+
NewRelic::Agent.set_transaction_name(params['transaction_name'])
|
24
|
+
end
|
25
|
+
sleep(params['sleep'].to_f) if params['sleep']
|
20
26
|
[200, headers, [response]]
|
21
27
|
end
|
22
28
|
|
@@ -23,7 +23,7 @@ class ThreadProfilingTest < MiniTest::Unit::TestCase
|
|
23
23
|
agent.service.request_timeout = 0.5
|
24
24
|
agent.service.agent_id = 666
|
25
25
|
|
26
|
-
@
|
26
|
+
@thread_profiler_session = agent.agent_command_router.thread_profiler_session
|
27
27
|
@threads = []
|
28
28
|
end
|
29
29
|
|
@@ -69,7 +69,7 @@ class ThreadProfilingTest < MiniTest::Unit::TestCase
|
|
69
69
|
|
70
70
|
profile_data = $collector.calls_for('profile_data')[0]
|
71
71
|
assert_equal('666', profile_data.run_id, "Missing run_id, profile_data was #{profile_data.inspect}")
|
72
|
-
assert(profile_data.
|
72
|
+
assert(profile_data.sample_count > 10, "Expected sample_count > 10, but was #{profile_data.sample_count}")
|
73
73
|
|
74
74
|
assert_saw_traces(profile_data, "OTHER")
|
75
75
|
assert_saw_traces(profile_data, "AGENT")
|
@@ -85,12 +85,12 @@ class ThreadProfilingTest < MiniTest::Unit::TestCase
|
|
85
85
|
|
86
86
|
profile_data = $collector.calls_for('profile_data')[0]
|
87
87
|
assert_equal('666', profile_data.run_id, "Missing run_id, profile_data was #{profile_data.inspect}")
|
88
|
-
assert(profile_data.
|
88
|
+
assert(profile_data.sample_count < 50, "Expected sample_count < 50, but was #{profile_data.sample_count}")
|
89
89
|
end
|
90
90
|
|
91
91
|
def issue_command(cmd)
|
92
92
|
$collector.stub('get_agent_commands', cmd)
|
93
|
-
agent.send(:
|
93
|
+
agent.send(:check_for_and_handle_agent_commands)
|
94
94
|
end
|
95
95
|
|
96
96
|
# Runs a thread we expect to span entire test and be killed at the end
|
@@ -103,7 +103,7 @@ class ThreadProfilingTest < MiniTest::Unit::TestCase
|
|
103
103
|
|
104
104
|
def let_it_finish
|
105
105
|
Timeout.timeout(5) do
|
106
|
-
until @
|
106
|
+
until @thread_profiler_session.ready_to_harvest?
|
107
107
|
sleep(0.1)
|
108
108
|
end
|
109
109
|
end
|
@@ -0,0 +1,163 @@
|
|
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
|
+
# https://newrelic.atlassian.net/wiki/display/eng/Agent+Thread+Profiling
|
6
|
+
# https://newrelic.atlassian.net/browse/RUBY-917
|
7
|
+
|
8
|
+
if RUBY_VERSION >= '1.9'
|
9
|
+
|
10
|
+
require 'rack/test'
|
11
|
+
require 'multiverse_helpers'
|
12
|
+
require './testing_app'
|
13
|
+
|
14
|
+
class XraySessionsTest < MiniTest::Unit::TestCase
|
15
|
+
|
16
|
+
AGENT_RUN_ID = 123
|
17
|
+
|
18
|
+
include MultiverseHelpers
|
19
|
+
include Rack::Test::Methods
|
20
|
+
|
21
|
+
setup_and_teardown_agent() do |collector|
|
22
|
+
collector.stub('connect', {"agent_run_id" => AGENT_RUN_ID })
|
23
|
+
end
|
24
|
+
|
25
|
+
def after_setup
|
26
|
+
agent.service.request_timeout = 0.5
|
27
|
+
agent.service.agent_id = AGENT_RUN_ID
|
28
|
+
end
|
29
|
+
|
30
|
+
def app
|
31
|
+
@app ||= TestingApp.new
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_tags_transaction_traces_with_xray_id
|
35
|
+
session = build_xray_session('key_transaction_name' => 'Controller/Rack/A')
|
36
|
+
with_xray_sessions(session) do
|
37
|
+
5.times { get '/?transaction_name=A' }
|
38
|
+
trigger_harvest
|
39
|
+
end
|
40
|
+
|
41
|
+
posts = $collector.calls_for('transaction_sample_data')
|
42
|
+
assert_equal(1, posts.size, "Expected exactly one transaction_sample_data post")
|
43
|
+
|
44
|
+
traces = posts.first.samples
|
45
|
+
assert_equal(5, traces.size)
|
46
|
+
assert traces.all? { |t| t.metric_name == 'Controller/Rack/A' }
|
47
|
+
assert traces.all? { |t| t.xray_id == session['x_ray_id'] }
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_does_not_collect_traces_for_non_xrayed_transactions
|
51
|
+
session = build_xray_session('key_transaction_name' => 'Controller/Rack/A')
|
52
|
+
with_xray_sessions(session) do
|
53
|
+
get '/?transaction_name=OtherThing'
|
54
|
+
get '/?transaction_name=A'
|
55
|
+
trigger_harvest
|
56
|
+
end
|
57
|
+
|
58
|
+
posts = $collector.calls_for('transaction_sample_data')
|
59
|
+
assert_equal(1, posts.size, "Expected exactly one transaction_sample_data post")
|
60
|
+
|
61
|
+
# We expect exactly one transaction trace, for A only
|
62
|
+
assert_equal(1, posts.first.samples.size)
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_gathers_transaction_traces_from_multiple_concurrent_xray_sessions
|
66
|
+
sessionA = build_xray_session('x_ray_id' => 12, 'key_transaction_name' => 'Controller/Rack/A')
|
67
|
+
sessionB = build_xray_session('x_ray_id' => 13, 'key_transaction_name' => 'Controller/Rack/B')
|
68
|
+
|
69
|
+
with_xray_sessions(sessionA, sessionB) do
|
70
|
+
2.times do
|
71
|
+
get '/?transaction_name=A'
|
72
|
+
get '/?transaction_name=B'
|
73
|
+
end
|
74
|
+
trigger_harvest
|
75
|
+
end
|
76
|
+
|
77
|
+
posts = $collector.calls_for('transaction_sample_data')
|
78
|
+
assert_equal(1, posts.size, "Expected exactly one transaction_sample_data post")
|
79
|
+
|
80
|
+
traces = posts.first.samples
|
81
|
+
assert_equal(4, traces.size)
|
82
|
+
|
83
|
+
tracesA = traces.select { |t| t.metric_name == 'Controller/Rack/A' }
|
84
|
+
tracesB = traces.select { |t| t.metric_name == 'Controller/Rack/B' }
|
85
|
+
assert_equal(2, tracesA.size, "Expected 2 traces for transaction A")
|
86
|
+
assert_equal(2, tracesB.size, "Expected 2 traces for transaction B")
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_gathers_thread_profiles
|
90
|
+
session = build_xray_session('key_transaction_name' => 'Controller/Rack/A')
|
91
|
+
with_xray_sessions(session) do
|
92
|
+
get '/?transaction_name=A&sleep=1'
|
93
|
+
trigger_harvest
|
94
|
+
end
|
95
|
+
|
96
|
+
# assert that a thread profile was submitted
|
97
|
+
posts = $collector.calls_for('profile_data')
|
98
|
+
assert_equal(1, posts.size, "Expected exactly one profile_data post")
|
99
|
+
|
100
|
+
profile_data_post = posts.first
|
101
|
+
assert(profile_data_post.sample_count > 1, "Expected at least one sample")
|
102
|
+
assert_saw_traces(profile_data_post, 'REQUEST')
|
103
|
+
end
|
104
|
+
|
105
|
+
## Helpers
|
106
|
+
|
107
|
+
def next_xray_session_id
|
108
|
+
@xray_session_id ||= 0
|
109
|
+
@xray_session_id += 1
|
110
|
+
@xray_session_id
|
111
|
+
end
|
112
|
+
|
113
|
+
def build_xray_session(overrides={})
|
114
|
+
defaults = {
|
115
|
+
"x_ray_id" => next_xray_session_id,
|
116
|
+
"xray_session_name" => "Test XRay Session",
|
117
|
+
"key_transaction_name" => "Controller/Rack/Transaction",
|
118
|
+
"requested_trace_count" => 10,
|
119
|
+
"duration" => 100,
|
120
|
+
"sample_period" => 0.1,
|
121
|
+
"run_profiler" => true
|
122
|
+
}
|
123
|
+
defaults.merge(overrides)
|
124
|
+
end
|
125
|
+
|
126
|
+
def build_active_xrays_command(active_xray_ids)
|
127
|
+
[[
|
128
|
+
AGENT_RUN_ID,
|
129
|
+
{
|
130
|
+
'name' => 'active_xray_sessions',
|
131
|
+
'arguments' => { 'xray_ids' => active_xray_ids }
|
132
|
+
}
|
133
|
+
]]
|
134
|
+
end
|
135
|
+
|
136
|
+
def with_xray_sessions(*xray_metadatas)
|
137
|
+
xray_session_ids = xray_metadatas.map { |m| m['x_ray_id'] }
|
138
|
+
activate_cmd = build_active_xrays_command(xray_session_ids)
|
139
|
+
|
140
|
+
$collector.stub('get_xray_metadata', xray_metadatas)
|
141
|
+
issue_command(activate_cmd)
|
142
|
+
|
143
|
+
yield
|
144
|
+
|
145
|
+
deactivate_cmd = build_active_xrays_command([])
|
146
|
+
issue_command(deactivate_cmd)
|
147
|
+
end
|
148
|
+
|
149
|
+
def issue_command(cmd)
|
150
|
+
$collector.stub('get_agent_commands', cmd)
|
151
|
+
agent.send(:check_for_and_handle_agent_commands)
|
152
|
+
end
|
153
|
+
|
154
|
+
def trigger_harvest
|
155
|
+
agent.send(:transmit_data)
|
156
|
+
end
|
157
|
+
|
158
|
+
def assert_saw_traces(profile_data, type)
|
159
|
+
assert !profile_data.traces[type].empty?, "Missing #{type} traces"
|
160
|
+
end
|
161
|
+
|
162
|
+
end
|
163
|
+
end
|