newrelic_rpm 3.5.2.17 → 3.5.3.24

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.

Files changed (134) hide show
  1. data/.travis.yml +3 -1
  2. data/CHANGELOG +39 -23
  3. data/GUIDELINES_FOR_CONTRIBUTING.md +23 -2
  4. data/Rakefile +32 -0
  5. data/lib/new_relic/agent.rb +1 -0
  6. data/lib/new_relic/agent/agent.rb +45 -6
  7. data/lib/new_relic/agent/browser_monitoring.rb +36 -20
  8. data/lib/new_relic/agent/busy_calculator.rb +12 -4
  9. data/lib/new_relic/agent/configuration/defaults.rb +6 -1
  10. data/lib/new_relic/agent/configuration/environment_source.rb +14 -0
  11. data/lib/new_relic/agent/instrumentation/sinatra.rb +14 -10
  12. data/lib/new_relic/agent/new_relic_service.rb +192 -34
  13. data/lib/new_relic/agent/pipe_channel_manager.rb +1 -2
  14. data/lib/new_relic/agent/pipe_service.rb +5 -1
  15. data/lib/new_relic/agent/samplers/memory_sampler.rb +1 -1
  16. data/lib/new_relic/agent/sql_sampler.rb +29 -10
  17. data/lib/new_relic/agent/stats_engine/metric_stats.rb +40 -0
  18. data/lib/new_relic/agent/stats_engine/samplers.rb +1 -2
  19. data/lib/new_relic/agent/thread.rb +27 -0
  20. data/lib/new_relic/agent/thread_profiler.rb +295 -0
  21. data/lib/new_relic/agent/worker_loop.rb +29 -15
  22. data/lib/new_relic/control/frameworks/rails.rb +4 -4
  23. data/lib/new_relic/control/frameworks/rails3.rb +1 -1
  24. data/lib/new_relic/helper.rb +3 -0
  25. data/lib/new_relic/metric_data.rb +10 -2
  26. data/lib/new_relic/noticed_error.rb +5 -0
  27. data/lib/new_relic/transaction_sample.rb +23 -13
  28. data/lib/new_relic/transaction_sample/segment.rb +13 -15
  29. data/lib/new_relic/version.rb +1 -1
  30. data/lib/tasks/tests.rake +5 -11
  31. data/test/multiverse/.gitignore +10 -0
  32. data/test/multiverse/README.md +90 -0
  33. data/test/multiverse/Rakefile +17 -0
  34. data/test/multiverse/lib/multiverse/color.rb +13 -0
  35. data/test/multiverse/lib/multiverse/envfile.rb +66 -0
  36. data/test/multiverse/lib/multiverse/environment.rb +16 -0
  37. data/test/multiverse/lib/multiverse/output_collector.rb +29 -0
  38. data/test/multiverse/lib/multiverse/runner.rb +44 -0
  39. data/test/multiverse/lib/multiverse/suite.rb +162 -0
  40. data/test/multiverse/script/run_one +3 -0
  41. data/test/multiverse/script/runner +9 -0
  42. data/test/multiverse/suites/active_record/Envfile +13 -0
  43. data/test/multiverse/suites/active_record/ar_method_aliasing.rb +94 -0
  44. data/test/multiverse/suites/active_record/config/newrelic.yml +22 -0
  45. data/test/multiverse/suites/active_record/encoding_test.rb +26 -0
  46. data/test/multiverse/suites/agent_only/Envfile +3 -0
  47. data/test/multiverse/suites/agent_only/config/newrelic.yml +22 -0
  48. data/test/multiverse/suites/agent_only/http_response_code_test.rb +53 -0
  49. data/test/multiverse/suites/agent_only/marshaling_test.rb +109 -0
  50. data/test/multiverse/suites/agent_only/method_visibility_test.rb +98 -0
  51. data/test/multiverse/suites/agent_only/pipe_manager_test.rb +33 -0
  52. data/test/multiverse/suites/agent_only/service_timeout_test.rb +29 -0
  53. data/test/multiverse/suites/agent_only/test_trace_method_with_punctuation.rb +30 -0
  54. data/test/multiverse/suites/agent_only/test_trace_transaction_with_punctuation.rb +32 -0
  55. data/test/multiverse/suites/agent_only/thread_profiling_test.rb +80 -0
  56. data/test/multiverse/suites/datamapper/Envfile +8 -0
  57. data/test/multiverse/suites/datamapper/config/newrelic.yml +22 -0
  58. data/test/multiverse/suites/datamapper/encoding_test.rb +36 -0
  59. data/test/multiverse/suites/monitor_mode_false/Envfile +2 -0
  60. data/test/multiverse/suites/monitor_mode_false/config/newrelic.yml +25 -0
  61. data/test/multiverse/suites/monitor_mode_false/no_dns_resolv.rb +29 -0
  62. data/test/multiverse/suites/no_load/Envfile +2 -0
  63. data/test/multiverse/suites/no_load/config/newrelic.yml +23 -0
  64. data/test/multiverse/suites/no_load/start_up_test.rb +14 -0
  65. data/test/multiverse/suites/rails_3_error_tracing/Envfile +15 -0
  66. data/test/multiverse/suites/rails_3_error_tracing/config/newrelic.yml +165 -0
  67. data/test/multiverse/suites/rails_3_error_tracing/error_tracing_test.rb +236 -0
  68. data/test/multiverse/suites/rails_3_gc/Envfile +8 -0
  69. data/test/multiverse/suites/rails_3_gc/config/newrelic.yml +167 -0
  70. data/test/multiverse/suites/rails_3_gc/instrumentation_test.rb +92 -0
  71. data/test/multiverse/suites/rails_3_queue_time/Envfile +15 -0
  72. data/test/multiverse/suites/rails_3_queue_time/config/newrelic.yml +165 -0
  73. data/test/multiverse/suites/rails_3_queue_time/queue_time_test.rb +75 -0
  74. data/test/multiverse/suites/rails_3_views/.gitignore +3 -0
  75. data/test/multiverse/suites/rails_3_views/Envfile +16 -0
  76. data/test/multiverse/suites/rails_3_views/app/views/foos/_foo.html.haml +1 -0
  77. data/test/multiverse/suites/rails_3_views/app/views/test/_a_partial.html.erb +1 -0
  78. data/test/multiverse/suites/rails_3_views/app/views/test/_mid_partial.html.erb +1 -0
  79. data/test/multiverse/suites/rails_3_views/app/views/test/_top_partial.html.erb +3 -0
  80. data/test/multiverse/suites/rails_3_views/app/views/test/deep_partial.html.erb +3 -0
  81. data/test/multiverse/suites/rails_3_views/app/views/test/haml_view.html.haml +6 -0
  82. data/test/multiverse/suites/rails_3_views/app/views/test/index.html.erb +4 -0
  83. data/test/multiverse/suites/rails_3_views/config/newrelic.yml +164 -0
  84. data/test/multiverse/suites/rails_3_views/view_instrumentation_test.rb +245 -0
  85. data/test/multiverse/suites/resque/Envfile +21 -0
  86. data/test/multiverse/suites/resque/config/newrelic.yml +22 -0
  87. data/test/multiverse/suites/resque/dump.rdb +0 -0
  88. data/test/multiverse/suites/resque/instrumentation_test.rb +73 -0
  89. data/test/multiverse/suites/rum_auto_instrumentation/Envfile +4 -0
  90. data/test/multiverse/suites/rum_auto_instrumentation/config/newrelic.yml +24 -0
  91. data/test/multiverse/suites/rum_auto_instrumentation/problem_response.html +422 -0
  92. data/test/multiverse/suites/rum_auto_instrumentation/responses/worst_case_small.html +5000 -0
  93. data/test/multiverse/suites/rum_auto_instrumentation/sanity_test.rb +115 -0
  94. data/test/multiverse/suites/sinatra/Envfile +13 -0
  95. data/test/multiverse/suites/sinatra/config/newrelic.yml +24 -0
  96. data/test/multiverse/suites/sinatra/sinatra_metric_explosion_test.rb +76 -0
  97. data/test/multiverse/suites/sinatra/sinatra_routes_test.rb +46 -0
  98. data/test/multiverse/test/multiverse_test.rb +55 -0
  99. data/test/multiverse/test/suite_examples/one/a/Envfile +3 -0
  100. data/test/multiverse/test/suite_examples/one/a/a_test.rb +11 -0
  101. data/test/multiverse/test/suite_examples/one/a/config/newrelic.yml +24 -0
  102. data/test/multiverse/test/suite_examples/one/b/Envfile +3 -0
  103. data/test/multiverse/test/suite_examples/one/b/b_test.rb +11 -0
  104. data/test/multiverse/test/suite_examples/one/b/config/newrelic.yml +24 -0
  105. data/test/multiverse/test/suite_examples/three/a/Envfile +2 -0
  106. data/test/multiverse/test/suite_examples/three/a/fail_test.rb +6 -0
  107. data/test/multiverse/test/suite_examples/three/b/Envfile +2 -0
  108. data/test/multiverse/test/suite_examples/three/b/win_test.rb +6 -0
  109. data/test/multiverse/test/suite_examples/two/a/Envfile +1 -0
  110. data/test/multiverse/test/suite_examples/two/a/fail_test.rb +6 -0
  111. data/test/new_relic/agent/agent_test.rb +54 -2
  112. data/test/new_relic/agent/agent_test_controller.rb +1 -1
  113. data/test/new_relic/agent/agent_test_controller_test.rb +35 -5
  114. data/test/new_relic/agent/browser_monitoring_test.rb +8 -8
  115. data/test/new_relic/agent/configuration/environment_source_test.rb +16 -0
  116. data/test/new_relic/agent/method_tracer_test.rb +6 -6
  117. data/test/new_relic/agent/new_relic_service_test.rb +137 -20
  118. data/test/new_relic/agent/sql_sampler_test.rb +26 -0
  119. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +1 -1
  120. data/test/new_relic/agent/stats_engine_test.rb +1 -0
  121. data/test/new_relic/agent/thread_profiler_test.rb +536 -0
  122. data/test/new_relic/agent/thread_test.rb +76 -0
  123. data/test/new_relic/agent/threaded_test.rb +65 -0
  124. data/test/new_relic/agent/transaction_sampler_test.rb +16 -13
  125. data/test/new_relic/agent/worker_loop_test.rb +20 -0
  126. data/test/new_relic/fake_collector.rb +103 -31
  127. data/test/new_relic/fake_service.rb +7 -1
  128. data/test/new_relic/metric_data_test.rb +45 -16
  129. data/test/new_relic/noticed_error_test.rb +14 -0
  130. data/test/new_relic/transaction_sample/segment_test.rb +23 -4
  131. data/test/new_relic/transaction_sample_test.rb +39 -0
  132. data/ui/views/layouts/newrelic_default.rhtml +1 -0
  133. data/ui/views/newrelic/threads.rhtml +2 -10
  134. metadata +88 -2
@@ -4,4 +4,6 @@ rvm:
4
4
  - ree
5
5
  - 1.9.2
6
6
  - 1.9.3
7
- - jruby
7
+ - jruby-19mode
8
+ - jruby-18mode
9
+
data/CHANGELOG CHANGED
@@ -1,6 +1,22 @@
1
1
 
2
2
  # New Relic Ruby Agent Release Notes #
3
3
 
4
+ ## v3.5.3 ##
5
+
6
+ * Update the collector protocol to use JSON and Ruby primitives
7
+
8
+ The communication between the agent and the NewRelic will not longer be
9
+ marshalled Ruby objects, but rather JSON in the case of Ruby 1.9 and marshalled
10
+ Ruby primitives in the case of 1.8. This results in greater harvest efficiency
11
+ as well as feature parity with other New Relic agents.
12
+
13
+ * Fix incorrect application of conditions in sinatra instrumentation
14
+
15
+ The agent's sinatra instrumentation was causing sinatra's condidtions to
16
+ be incorrectly applied in some obscure cases. The bug was triggered
17
+ when a condition was present on a lower priority route that would match
18
+ the current request, except for the precense of a higher priority route.
19
+
4
20
  ## v3.5.2 ##
5
21
 
6
22
  * Simplified process of running agent test suite and documented code
@@ -19,13 +35,13 @@
19
35
 
20
36
  * Server-side configuration for ignoring errors was not being heeded by agent.
21
37
 
22
- * Better handling of a thread safety issue.
38
+ * Better handling of a thread safety issue.
23
39
 
24
- Some issues may remain, which we are working to address, but they should be gracefully handled
40
+ Some issues may remain, which we are working to address, but they should be gracefully handled
25
41
  now, rather than crashing the running app.
26
42
 
27
43
  * Use "java_import" rather than "include_class" when require Java Jars into a JRuby app.
28
-
44
+
29
45
  Thanks to Jan Habermann for the pull request
30
46
 
31
47
  * Replaced alias_method mechanism with super call in DataMapper instrumentation.
@@ -46,7 +62,7 @@
46
62
 
47
63
  ## v3.5.0.1 ##
48
64
 
49
- * (Fix) Due to a serious resource leak we have ended support for versions of Phusion Passenger
65
+ * (Fix) Due to a serious resource leak we have ended support for versions of Phusion Passenger
50
66
  older than 2.1.1. Users of older versions are encouraged upgrade to a more recent version.
51
67
 
52
68
  ## v3.5.0 ##
@@ -59,19 +75,19 @@
59
75
  * When the Ruby Agent detects Unicorn as the dispatcher it creates an INFO level log message
60
76
  with additional information
61
77
 
62
- To help customers using Unicorn, if the agent detects it (Unicorn) is being used as the
78
+ To help customers using Unicorn, if the agent detects it (Unicorn) is being used as the
63
79
  dispatcher an INFO level log message it created that includes a link to New Relic
64
80
  online doc that has additional steps that may be required to get performance data reporting.
65
81
 
66
82
  * (Fix) In version 3.4.2 of the Ruby Agent the server side value for Apdex T was disgregarded
67
83
 
68
- With version 3.4.2 of the agent, the value set in the newrelic.yml file took precedence over the
84
+ With version 3.4.2 of the agent, the value set in the newrelic.yml file took precedence over the
69
85
  value set in the New Relic UI. As of version 3.5.0 only the value for Apdex T set in the
70
86
  New Relic UI will be used. Any setting in the yaml file will be ignored.
71
87
 
72
88
  * Improved Error Detection/Reporting capabilities for Rails 3 apps
73
89
 
74
- Some errors are missed by the agent's exception reporting handlers because they are
90
+ Some errors are missed by the agent's exception reporting handlers because they are
75
91
  generated in the rails stack, outside of the instrumented controller action. A Rack
76
92
  middleware is now included that can detect these errors as they bubble out of the middleware stack.
77
93
  Note that this does not include Routing Errors.
@@ -87,11 +103,11 @@
87
103
 
88
104
  * Know issue with Ruby 1.8.7-p334, sqlite3-ruby 1.3.0 or older, and resque 1.23.0
89
105
 
90
- The Ruby Agent will not work in conjunction with Ruby 1.8.7-p334, sqlite3-ruby 1.3.3
106
+ The Ruby Agent will not work in conjunction with Ruby 1.8.7-p334, sqlite3-ruby 1.3.3
91
107
  or earlier, and resque 1.23.0. Your app will likely stop functioning. This is a known problem
92
- with Ruby versions up to 1.8.7-p334. Upgrading to the last release of Ruby 1.8.7
93
- is recommended. This issue has been present in every version of the agent we've tested
94
- going back for a year.
108
+ with Ruby versions up to 1.8.7-p334. Upgrading to the last release of Ruby 1.8.7
109
+ is recommended. This issue has been present in every version of the agent we've tested
110
+ going back for a year.
95
111
 
96
112
 
97
113
  ### previous versions ###
@@ -109,7 +125,7 @@
109
125
  * The RUM NRAGENT tk value gets more robustly sanitized to prevent potential XSS vulnerabilities
110
126
 
111
127
  The code that scrubes the token used in Real User Monitoring has been enhanced to be
112
- more robust.
128
+ more robust.
113
129
 
114
130
  * Support for Apdex T in server side configuration
115
131
 
@@ -123,26 +139,26 @@
123
139
 
124
140
  ## v3.4.1 ##
125
141
  #### Bug Fixes ####
126
- * Fix edge case in RUM auto instrumentation where X-UA-Compatible meta tag is
142
+ * Fix edge case in RUM auto instrumentation where X-UA-Compatible meta tag is
127
143
  present but </head> tag is missing.
128
144
 
129
- There is a somewhat obscure edge case where RUM auto instrumentation will
130
- crash a request. The issue seems to be triggered when the X-UA-Compatible
145
+ There is a somewhat obscure edge case where RUM auto instrumentation will
146
+ crash a request. The issue seems to be triggered when the X-UA-Compatible
131
147
  meta tag is present and the </head> tag is missing.
132
148
 
133
- * Fixed reference to @service.request_timeout to @request_timeout in
149
+ * Fixed reference to @service.request_timeout to @request_timeout in
134
150
  new_relic_service.rb. (Thanks to Matthew Savage)
135
151
 
136
- When a timeout occurred during connection to the collector an "undefined
152
+ When a timeout occurred during connection to the collector an "undefined
137
153
  method `request_timeout' for nil:NilClass'" would get raised.
138
154
 
139
- * preserve visibility on traced methods.
155
+ * preserve visibility on traced methods.
140
156
 
141
- Aliased methods now have the same visibility as the original traced method.
142
- A couple of the esoteric methods created in the process weren't getting the
143
- visibility set properly.
157
+ Aliased methods now have the same visibility as the original traced method.
158
+ A couple of the esoteric methods created in the process weren't getting the
159
+ visibility set properly.
144
160
 
145
- * Agent service does not connect to directed shard collector after connecting
161
+ * Agent service does not connect to directed shard collector after connecting
146
162
  to proxy
147
163
 
148
164
  After connecting to collector proxy name of real collector was updated, but
@@ -157,7 +173,7 @@
157
173
  * should reset RubyBench GC counter between polls
158
174
 
159
175
  On Ruby REE, the GC profiler does not reset the counter between polls. This
160
- is only a problem if GC could happen *between* transactions, as in, for
176
+ is only a problem if GC could happen *between* transactions, as in, for
161
177
  example, out-of-band GC in Unicorn. fixed.
162
178
 
163
179
  v3.4.0.1
@@ -16,8 +16,12 @@ specific libraries such as `ActiveSupport`.
16
16
 
17
17
  ## Testing
18
18
 
19
- The agent includes a suite of unit tests which should be used to verify your
20
- changes don't break existing functionality.
19
+ The agent includes a suite of unit and functional tests which should be used to
20
+ verify your changes don't break existing functionality.
21
+
22
+ Unit tests are stored in the `test/new_relic` directory.
23
+
24
+ Functional tests are stored in the `test/multiverse` directory.
21
25
 
22
26
  ### Running Tests
23
27
 
@@ -50,3 +54,20 @@ functionality (e.g. a performance optimization) and new tests are not required.
50
54
  In general, including tests with your pull request dramatically increases the
51
55
  chances it will be accepted.
52
56
 
57
+ ### Functional Testing
58
+
59
+ For cases where the unit test environment is not sufficient for testing a
60
+ change (e.g. instrumentation for a non-rails framework, not available in the
61
+ unit test environment), we have a functional testing suite called multiverse.
62
+ These tests can be run by invoking:
63
+
64
+ bundle
65
+ bundle exec rake test:multiverse
66
+
67
+ ### And Finally...
68
+
69
+ You are welcome to send pull requests to us - however, by doing so you agree
70
+ that you are granting New Relic a non-exclusive, non-revokable, no-cost license
71
+ to use the code, algorithms, patents, and ideas in that code in our products if
72
+ we so choose. You also agree the code is provided as-is and you provide no
73
+ warranties as to its fitness or correctness for any purpose.
data/Rakefile CHANGED
@@ -1,7 +1,39 @@
1
1
  require 'rubygems'
2
+ require 'rake/testtask'
2
3
  require "#{File.dirname(__FILE__)}/lib/new_relic/version.rb"
3
4
  require "#{File.dirname(__FILE__)}/lib/tasks/all.rb"
4
5
 
6
+ task :default => :test
7
+
8
+ task :test => 'test:newrelic'
9
+
10
+ namespace :test do
11
+ desc "Run all tests"
12
+ task :all => %w{newrelic multiverse}
13
+
14
+ agent_home = File.expand_path(File.dirname(__FILE__))
15
+
16
+ desc "Run functional test suite for newrelic"
17
+ task :multiverse, [:suite, :mode] => [:gemspec] do |t, args|
18
+ args.with_defaults(:suite => "", :mode => "")
19
+ if args.mode == "run_one"
20
+ puts `#{agent_home}/test/multiverse/script/run_one #{args.suite}`
21
+ else
22
+ ruby "#{agent_home}/test/multiverse/script/runner #{args.suite}"
23
+ end
24
+ end
25
+
26
+ Rake::TestTask.new(:intentional_fail) do |t|
27
+ t.libs << "#{agent_home}/test"
28
+ t.libs << "#{agent_home}/lib"
29
+ t.pattern = "#{agent_home}/test/intentional_fail.rb"
30
+ t.verbose = true
31
+ end
32
+
33
+ # Note unit testing task is defined in lib/tasks/tests.rake to facilitate
34
+ # running them in a rails application environment.
35
+
36
+ end
5
37
 
6
38
  desc 'Generate gemspec [ build_number, stage ]'
7
39
  task :gemspec, [ :build_number, :stage ] do |t, args|
@@ -84,6 +84,7 @@ module NewRelic
84
84
  require 'new_relic/agent/stats_engine'
85
85
  require 'new_relic/agent/transaction_sampler'
86
86
  require 'new_relic/agent/sql_sampler'
87
+ require 'new_relic/agent/thread_profiler'
87
88
  require 'new_relic/agent/error_collector'
88
89
  require 'new_relic/agent/busy_calculator'
89
90
  require 'new_relic/agent/sampler'
@@ -8,6 +8,7 @@ require 'new_relic/agent/new_relic_service'
8
8
  require 'new_relic/agent/pipe_service'
9
9
  require 'new_relic/agent/configuration/manager'
10
10
  require 'new_relic/agent/database'
11
+ require 'new_relic/agent/thread_profiler'
11
12
 
12
13
  module NewRelic
13
14
  module Agent
@@ -26,6 +27,7 @@ module NewRelic
26
27
  @stats_engine = NewRelic::Agent::StatsEngine.new
27
28
  @transaction_sampler = NewRelic::Agent::TransactionSampler.new
28
29
  @sql_sampler = NewRelic::Agent::SqlSampler.new
30
+ @thread_profiler = NewRelic::Agent::ThreadProfiler.new
29
31
  @error_collector = NewRelic::Agent::ErrorCollector.new
30
32
  @connect_attempts = 0
31
33
 
@@ -70,6 +72,8 @@ module NewRelic
70
72
  # the transaction sampler that handles recording transactions
71
73
  attr_reader :transaction_sampler
72
74
  attr_reader :sql_sampler
75
+ # begins a thread profile session when instructed by agent commands
76
+ attr_reader :thread_profiler
73
77
  # error collector is a simple collection of recorded errors
74
78
  attr_reader :error_collector
75
79
  # whether we should record raw, obfuscated, or no sql
@@ -592,10 +596,9 @@ module NewRelic
592
596
  # See #connect for a description of connection_options.
593
597
  def start_worker_thread(connection_options = {})
594
598
  log.debug "Creating Ruby Agent worker thread."
595
- @worker_thread = Thread.new do
599
+ @worker_thread = NewRelic::Agent::Thread.new('Worker Loop') do
596
600
  deferred_work!(connection_options)
597
- end # thread new
598
- @worker_thread['newrelic_label'] = 'Worker Loop'
601
+ end
599
602
  end
600
603
 
601
604
  # A shorthand for NewRelic::Control.instance
@@ -980,7 +983,7 @@ module NewRelic
980
983
  if Agent.config[:'transaction_tracer.explain_enabled']
981
984
  options[:explain_sql] = Agent.config[:'transaction_tracer.explain_threshold']
982
985
  end
983
- traces = @traces.collect {|trace| trace.prepare_to_send(options)}
986
+ traces = @traces.map {|trace| trace.prepare_to_send(options) }
984
987
  @service.transaction_sample_data(traces)
985
988
  log.debug "Sent slowest sample (#{@service.agent_id}) in #{Time.now - now} seconds"
986
989
  rescue UnrecoverableServerException => e
@@ -994,6 +997,17 @@ module NewRelic
994
997
  @traces = nil
995
998
  end
996
999
 
1000
+ def harvest_and_send_thread_profile(disconnecting=false)
1001
+ @thread_profiler.stop(true) if disconnecting
1002
+
1003
+ if @thread_profiler.finished?
1004
+ profile = @thread_profiler.harvest
1005
+
1006
+ log.debug "Sending thread profile #{profile.profile_id}"
1007
+ @service.profile_data(profile)
1008
+ end
1009
+ end
1010
+
997
1011
  # Gets the collection of unsent errors from the error
998
1012
  # collector. We pass back in an existing array of errors that
999
1013
  # may be left over from a previous send
@@ -1023,13 +1037,37 @@ module NewRelic
1023
1037
  end
1024
1038
  end
1025
1039
 
1026
- def transmit_data
1040
+ # Only JSON marshalling appears to work with collector on
1041
+ # get_agent_commands and agent_command_results. We only support
1042
+ # these features on Ruby versions that can hack JSON out of the box
1043
+ def agent_commands_supported?
1044
+ RUBY_VERSION >= "1.9.2"
1045
+ end
1046
+
1047
+ def check_for_agent_commands
1048
+ if !agent_commands_supported?
1049
+ log.debug("Skipping agent commands, as they aren't supported on this environment")
1050
+ return
1051
+ end
1052
+
1053
+ commands = @service.get_agent_commands
1054
+ log.debug "Received get_agent_commands = #{commands}"
1055
+
1056
+ @thread_profiler.respond_to_commands(commands) do |command_id, error|
1057
+ @service.agent_command_results(command_id, error)
1058
+ end
1059
+ end
1060
+
1061
+ def transmit_data(disconnecting=false)
1027
1062
  now = Time.now
1028
1063
  log.debug "Sending data to New Relic Service"
1029
1064
  harvest_and_send_errors
1030
1065
  harvest_and_send_slowest_sample
1031
1066
  harvest_and_send_slowest_sql
1032
1067
  harvest_and_send_timeslice_data
1068
+ harvest_and_send_thread_profile(disconnecting)
1069
+
1070
+ check_for_agent_commands
1033
1071
  rescue => e
1034
1072
  retry_count ||= 0
1035
1073
  retry_count += 1
@@ -1055,7 +1093,8 @@ module NewRelic
1055
1093
  if @connected
1056
1094
  begin
1057
1095
  @service.request_timeout = 10
1058
- transmit_data
1096
+ transmit_data(true)
1097
+
1059
1098
  if @connected_pid == $$ && !@service.kind_of?(NewRelic::Agent::NewRelicService)
1060
1099
  log.debug "Sending New Relic service agent run shutdown message"
1061
1100
  @service.shutdown(Time.now.to_f)
@@ -31,14 +31,11 @@ module NewRelic
31
31
  # page as is reasonably possible - that is, before any style or
32
32
  # javascript inclusions, but after any header-related meta tags
33
33
  def browser_timing_header
34
- if NewRelic::Agent.instance.beacon_configuration.nil? ||
35
- !NewRelic::Agent.is_transaction_traced? ||
36
- !NewRelic::Agent.is_execution_traced? ||
37
- NewRelic::Agent::TransactionInfo.get.ignore_end_user?
38
- return ""
34
+ if insert_js?
35
+ NewRelic::Agent.instance.beacon_configuration.browser_timing_header
36
+ else
37
+ ""
39
38
  end
40
-
41
- NewRelic::Agent.instance.beacon_configuration.browser_timing_header
42
39
  end
43
40
 
44
41
  # This method returns a string suitable for inclusion in a page
@@ -50,19 +47,11 @@ module NewRelic
50
47
  # This is the footer string - it should be placed as low in the
51
48
  # page as is reasonably possible.
52
49
  def browser_timing_footer
53
- config = NewRelic::Agent.instance.beacon_configuration
54
-
55
- if config.nil? ||
56
- !config.enabled? ||
57
- Agent.config[:browser_key].nil? ||
58
- Agent.config[:browser_key].empty? ||
59
- !NewRelic::Agent.is_transaction_traced? ||
60
- !NewRelic::Agent.is_execution_traced? ||
61
- NewRelic::Agent::TransactionInfo.get.ignore_end_user?
62
- return ""
63
- end
64
-
65
- generate_footer_js(config)
50
+ if insert_js?
51
+ generate_footer_js(NewRelic::Agent.instance.beacon_configuration)
52
+ else
53
+ ""
54
+ end
66
55
  end
67
56
 
68
57
  module_function
@@ -129,6 +118,33 @@ module NewRelic
129
118
 
130
119
  private
131
120
 
121
+ # Check whether RUM header and footer should be generated. Log the
122
+ # reason if they shouldn't.
123
+ def insert_js?
124
+ if NewRelic::Agent.instance.beacon_configuration.nil?
125
+ NewRelic::Agent.logger.debug "Beacon configuration is nil. Skipping browser instrumentation."
126
+ false
127
+ elsif ! NewRelic::Agent.instance.beacon_configuration.enabled?
128
+ NewRelic::Agent.logger.debug "Beacon configuration is disabled. Skipping browser instrumentation."
129
+ NewRelic::Agent.logger.debug NewRelic::Agent.instance.beacon_configuration.inspect
130
+ false
131
+ elsif Agent.config[:browser_key].nil? || Agent.config[:browser_key].empty?
132
+ NewRelic::Agent.logger.debug "Browser key is not set. Skipping browser instrumentation."
133
+ false
134
+ elsif ! NewRelic::Agent.is_transaction_traced?
135
+ NewRelic::Agent.logger.debug "Transaction is not traced. Skipping browser instrumentation."
136
+ false
137
+ elsif ! NewRelic::Agent.is_execution_traced?
138
+ NewRelic::Agent.logger.debug "Execution is not traced. Skipping browser instrumentation."
139
+ false
140
+ elsif NewRelic::Agent::TransactionInfo.get.ignore_end_user?
141
+ NewRelic::Agent.logger.debug "Ignore end user for this transaction is set. Skipping browser instrumentation."
142
+ false
143
+ else
144
+ true
145
+ end
146
+ end
147
+
132
148
  def generate_footer_js(config)
133
149
  if browser_monitoring_start_time
134
150
  footer_js_string(config)
@@ -30,7 +30,8 @@ module NewRelic
30
30
  # called when a transaction finishes, to add time to the
31
31
  # instance variable accumulator. this is harvested when we send
32
32
  # data to the server
33
- def dispatcher_finish(end_time = Time.now)
33
+ def dispatcher_finish(end_time = nil)
34
+ end_time ||= time_now
34
35
  callers = Thread.current[:busy_entries] -= 1
35
36
  # Ignore nested calls
36
37
  return if callers > 0
@@ -56,15 +57,14 @@ module NewRelic
56
57
  Thread.current[:busy_entries] = 0
57
58
  @lock ||= Mutex.new
58
59
  @accumulator = 0
59
- @harvest_start = Time.now
60
+ @harvest_start = time_now
60
61
  end
61
62
 
62
- self.reset
63
63
 
64
64
  # Called before uploading to to the server to collect current busy stats.
65
65
  def harvest_busy
66
66
  busy = 0
67
- t0 = Time.now
67
+ t0 = time_now
68
68
  @lock.synchronize do
69
69
  busy = accumulator
70
70
  @accumulator = 0
@@ -88,12 +88,20 @@ module NewRelic
88
88
  instance_busy_stats.record_data_point busy
89
89
  @harvest_start = t0
90
90
  end
91
+
91
92
  private
93
+
94
+ # so we can stub Time.now only for the BusyCalculator in tests
95
+ def time_now
96
+ Time.now
97
+ end
98
+
92
99
  def instance_busy_stats
93
100
  # Late binding on the Instance/busy stats
94
101
  NewRelic::Agent.agent.stats_engine.get_stats_no_scope 'Instance/Busy'
95
102
  end
96
103
 
104
+ self.reset
97
105
  end
98
106
  end
99
107
  end