wd_newrelic_rpm 3.3.4.1 → 3.5.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (290) hide show
  1. data/.gitignore +20 -0
  2. data/.project +23 -0
  3. data/.travis.yml +9 -0
  4. data/CHANGELOG +317 -39
  5. data/GUIDELINES_FOR_CONTRIBUTING.md +76 -0
  6. data/Gemfile +16 -0
  7. data/LICENSE +1 -1
  8. data/{README.rdoc → README.md} +71 -55
  9. data/Rakefile +62 -0
  10. data/bin/mongrel_rpm +1 -1
  11. data/config.dot +290 -0
  12. data/config/database.yml +5 -0
  13. data/init.rb +31 -0
  14. data/lib/new_relic/agent.rb +31 -60
  15. data/lib/new_relic/agent/agent.rb +277 -502
  16. data/lib/new_relic/agent/agent_logger.rb +165 -0
  17. data/lib/new_relic/agent/audit_logger.rb +72 -0
  18. data/lib/new_relic/agent/beacon_configuration.rb +36 -50
  19. data/lib/new_relic/agent/browser_monitoring.rb +114 -61
  20. data/lib/new_relic/agent/busy_calculator.rb +14 -6
  21. data/lib/new_relic/agent/configuration.rb +74 -0
  22. data/lib/new_relic/agent/configuration/defaults.rb +126 -0
  23. data/lib/new_relic/agent/configuration/environment_source.rb +49 -0
  24. data/lib/new_relic/agent/configuration/manager.rb +136 -0
  25. data/lib/new_relic/agent/configuration/mask_defaults.rb +10 -0
  26. data/lib/new_relic/agent/configuration/server_source.rb +27 -0
  27. data/lib/new_relic/agent/configuration/yaml_source.rb +63 -0
  28. data/lib/new_relic/agent/cross_process_monitoring.rb +43 -0
  29. data/lib/new_relic/agent/database.rb +39 -26
  30. data/lib/new_relic/agent/error_collector.rb +48 -49
  31. data/lib/new_relic/agent/instrumentation/active_merchant.rb +1 -1
  32. data/lib/new_relic/agent/instrumentation/active_record.rb +4 -7
  33. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +1 -1
  34. data/lib/new_relic/agent/instrumentation/authlogic.rb +1 -1
  35. data/lib/new_relic/agent/instrumentation/browser_monitoring_timings.rb +41 -0
  36. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +35 -12
  37. data/lib/new_relic/agent/instrumentation/data_mapper.rb +4 -12
  38. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +2 -2
  39. data/lib/new_relic/agent/instrumentation/memcache.rb +6 -6
  40. data/lib/new_relic/agent/instrumentation/merb/controller.rb +1 -1
  41. data/lib/new_relic/agent/instrumentation/merb/errors.rb +1 -1
  42. data/lib/new_relic/agent/instrumentation/metric_frame.rb +4 -14
  43. data/lib/new_relic/agent/instrumentation/metric_frame/pop.rb +1 -1
  44. data/lib/new_relic/agent/instrumentation/net.rb +1 -1
  45. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +6 -20
  46. data/lib/new_relic/agent/instrumentation/queue_time.rb +2 -2
  47. data/lib/new_relic/agent/instrumentation/rack.rb +1 -1
  48. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +7 -7
  49. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +1 -1
  50. data/lib/new_relic/agent/instrumentation/rails/errors.rb +1 -1
  51. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +5 -5
  52. data/lib/new_relic/agent/instrumentation/rails3/errors.rb +6 -2
  53. data/lib/new_relic/agent/instrumentation/resque.rb +81 -0
  54. data/lib/new_relic/agent/instrumentation/sinatra.rb +21 -10
  55. data/lib/new_relic/agent/instrumentation/sunspot.rb +1 -1
  56. data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +5 -4
  57. data/lib/new_relic/agent/method_tracer.rb +11 -9
  58. data/lib/new_relic/agent/new_relic_service.rb +379 -0
  59. data/lib/new_relic/agent/pipe_channel_manager.rb +175 -0
  60. data/lib/new_relic/agent/pipe_service.rb +58 -0
  61. data/lib/new_relic/agent/samplers/delayed_job_sampler.rb +86 -0
  62. data/lib/new_relic/agent/samplers/memory_sampler.rb +6 -8
  63. data/lib/new_relic/agent/sql_sampler.rb +31 -74
  64. data/lib/new_relic/agent/stats_engine.rb +0 -5
  65. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +40 -24
  66. data/lib/new_relic/agent/stats_engine/metric_stats.rb +89 -14
  67. data/lib/new_relic/agent/stats_engine/samplers.rb +9 -7
  68. data/lib/new_relic/agent/stats_engine/transactions.rb +20 -12
  69. data/lib/new_relic/agent/thread.rb +32 -0
  70. data/lib/new_relic/agent/thread_profiler.rb +306 -0
  71. data/lib/new_relic/agent/transaction_info.rb +24 -4
  72. data/lib/new_relic/agent/transaction_sample_builder.rb +12 -13
  73. data/lib/new_relic/agent/transaction_sampler.rb +49 -65
  74. data/lib/new_relic/agent/worker_loop.rb +31 -25
  75. data/lib/new_relic/collection_helper.rb +1 -1
  76. data/lib/new_relic/commands/deployments.rb +19 -10
  77. data/lib/new_relic/control.rb +1 -3
  78. data/lib/new_relic/control/class_methods.rb +10 -5
  79. data/lib/new_relic/control/frameworks/merb.rb +0 -6
  80. data/lib/new_relic/control/frameworks/rails.rb +30 -45
  81. data/lib/new_relic/control/frameworks/rails3.rb +23 -18
  82. data/lib/new_relic/control/frameworks/rails4.rb +23 -0
  83. data/lib/new_relic/control/frameworks/ruby.rb +2 -23
  84. data/lib/new_relic/control/instance_methods.rb +35 -73
  85. data/lib/new_relic/control/instrumentation.rb +7 -12
  86. data/lib/new_relic/control/server_methods.rb +17 -19
  87. data/lib/new_relic/delayed_job_injection.rb +2 -2
  88. data/lib/new_relic/helper.rb +34 -0
  89. data/lib/new_relic/language_support.rb +56 -37
  90. data/lib/new_relic/local_environment.rb +32 -67
  91. data/lib/new_relic/metric_data.rb +10 -2
  92. data/lib/new_relic/metric_spec.rb +7 -3
  93. data/lib/new_relic/noticed_error.rb +32 -9
  94. data/lib/new_relic/rack.rb +4 -0
  95. data/lib/new_relic/rack/browser_monitoring.rb +34 -25
  96. data/lib/new_relic/rack/developer_mode.rb +3 -0
  97. data/lib/new_relic/rack/error_collector.rb +56 -0
  98. data/lib/new_relic/stats.rb +9 -7
  99. data/lib/new_relic/transaction_sample.rb +19 -18
  100. data/lib/new_relic/transaction_sample/segment.rb +13 -15
  101. data/lib/new_relic/version.rb +19 -3
  102. data/lib/newrelic_rpm.rb +1 -1
  103. data/lib/tasks/tests.rake +6 -8
  104. data/newrelic.yml +15 -32
  105. data/newrelic_rpm.gemspec +224 -43
  106. data/newrelic_rpm.gemspec.erb +54 -0
  107. data/test/config/newrelic.yml +4 -3
  108. data/test/config/test_control.rb +18 -18
  109. data/test/fixtures/gemspec_no_build.rb +442 -0
  110. data/test/fixtures/gemspec_with_build.rb +442 -0
  111. data/test/fixtures/gemspec_with_build_and_stage.rb +442 -0
  112. data/test/intentional_fail.rb +10 -0
  113. data/test/multiverse/.gitignore +10 -0
  114. data/test/multiverse/README.md +85 -0
  115. data/test/multiverse/lib/multiverse/color.rb +13 -0
  116. data/test/multiverse/lib/multiverse/envfile.rb +66 -0
  117. data/test/multiverse/lib/multiverse/environment.rb +16 -0
  118. data/test/multiverse/lib/multiverse/output_collector.rb +29 -0
  119. data/test/multiverse/lib/multiverse/runner.rb +44 -0
  120. data/test/multiverse/lib/multiverse/suite.rb +162 -0
  121. data/test/multiverse/script/run_one +3 -0
  122. data/test/multiverse/script/runner +9 -0
  123. data/test/multiverse/suites/active_record/Envfile +13 -0
  124. data/test/multiverse/suites/active_record/ar_method_aliasing.rb +94 -0
  125. data/test/multiverse/suites/active_record/config/newrelic.yml +22 -0
  126. data/test/multiverse/suites/active_record/encoding_test.rb +26 -0
  127. data/test/multiverse/suites/agent_only/Envfile +4 -0
  128. data/test/multiverse/suites/agent_only/audit_log_test.rb +99 -0
  129. data/test/multiverse/suites/agent_only/config/newrelic.yml +22 -0
  130. data/test/multiverse/suites/agent_only/http_response_code_test.rb +53 -0
  131. data/test/multiverse/suites/agent_only/marshaling_test.rb +109 -0
  132. data/test/multiverse/suites/agent_only/method_visibility_test.rb +98 -0
  133. data/test/multiverse/suites/agent_only/pipe_manager_test.rb +33 -0
  134. data/test/multiverse/suites/agent_only/service_timeout_test.rb +29 -0
  135. data/test/multiverse/suites/agent_only/test_trace_method_with_punctuation.rb +30 -0
  136. data/test/multiverse/suites/agent_only/test_trace_transaction_with_punctuation.rb +32 -0
  137. data/test/multiverse/suites/agent_only/thread_profiling_test.rb +80 -0
  138. data/test/multiverse/suites/config_file_loading/Envfile +7 -0
  139. data/test/multiverse/suites/config_file_loading/config_file_loading_test.rb +106 -0
  140. data/test/multiverse/suites/datamapper/Envfile +8 -0
  141. data/test/multiverse/suites/datamapper/config/newrelic.yml +22 -0
  142. data/test/multiverse/suites/datamapper/encoding_test.rb +36 -0
  143. data/test/multiverse/suites/logging/Envfile +4 -0
  144. data/test/multiverse/suites/logging/config/newrelic.yml +22 -0
  145. data/test/multiverse/suites/logging/logging_test.rb +143 -0
  146. data/test/multiverse/suites/monitor_mode_false/Envfile +2 -0
  147. data/test/multiverse/suites/monitor_mode_false/config/newrelic.yml +25 -0
  148. data/test/multiverse/suites/monitor_mode_false/no_dns_resolv.rb +29 -0
  149. data/test/multiverse/suites/no_load/Envfile +2 -0
  150. data/test/multiverse/suites/no_load/config/newrelic.yml +22 -0
  151. data/test/multiverse/suites/no_load/start_up_test.rb +14 -0
  152. data/test/multiverse/suites/rails_3_error_tracing/Envfile +15 -0
  153. data/test/multiverse/suites/rails_3_error_tracing/config/newrelic.yml +165 -0
  154. data/test/multiverse/suites/rails_3_error_tracing/error_tracing_test.rb +236 -0
  155. data/test/multiverse/suites/rails_3_gc/Envfile +8 -0
  156. data/test/multiverse/suites/rails_3_gc/config/newrelic.yml +167 -0
  157. data/test/multiverse/suites/rails_3_gc/instrumentation_test.rb +92 -0
  158. data/test/multiverse/suites/rails_3_queue_time/Envfile +15 -0
  159. data/test/multiverse/suites/rails_3_queue_time/config/newrelic.yml +165 -0
  160. data/test/multiverse/suites/rails_3_queue_time/queue_time_test.rb +75 -0
  161. data/test/multiverse/suites/rails_3_views/.gitignore +3 -0
  162. data/test/multiverse/suites/rails_3_views/Envfile +16 -0
  163. data/test/multiverse/suites/rails_3_views/app/views/foos/_foo.html.haml +1 -0
  164. data/test/multiverse/suites/rails_3_views/app/views/test/_a_partial.html.erb +1 -0
  165. data/test/multiverse/suites/rails_3_views/app/views/test/_mid_partial.html.erb +1 -0
  166. data/test/multiverse/suites/rails_3_views/app/views/test/_top_partial.html.erb +3 -0
  167. data/test/multiverse/suites/rails_3_views/app/views/test/deep_partial.html.erb +3 -0
  168. data/test/multiverse/suites/rails_3_views/app/views/test/haml_view.html.haml +6 -0
  169. data/test/multiverse/suites/rails_3_views/app/views/test/index.html.erb +4 -0
  170. data/test/multiverse/suites/rails_3_views/config/newrelic.yml +164 -0
  171. data/test/multiverse/suites/rails_3_views/view_instrumentation_test.rb +245 -0
  172. data/test/multiverse/suites/resque/Envfile +21 -0
  173. data/test/multiverse/suites/resque/config/newrelic.yml +22 -0
  174. data/test/multiverse/suites/resque/dump.rdb +0 -0
  175. data/test/multiverse/suites/resque/instrumentation_test.rb +73 -0
  176. data/test/multiverse/suites/rum_auto_instrumentation/Envfile +4 -0
  177. data/test/multiverse/suites/rum_auto_instrumentation/config/newrelic.yml +24 -0
  178. data/test/multiverse/suites/rum_auto_instrumentation/responses/worst_case_small.html +5000 -0
  179. data/test/multiverse/suites/rum_auto_instrumentation/sanity_test.rb +102 -0
  180. data/test/multiverse/suites/sinatra/Envfile +13 -0
  181. data/test/multiverse/suites/sinatra/config/newrelic.yml +24 -0
  182. data/test/multiverse/suites/sinatra/sinatra_metric_explosion_test.rb +77 -0
  183. data/test/multiverse/suites/sinatra/sinatra_routes_test.rb +46 -0
  184. data/test/multiverse/suites/sinatra/sinatra_test.rb +55 -0
  185. data/test/multiverse/test/multiverse_test.rb +55 -0
  186. data/test/multiverse/test/suite_examples/one/a/Envfile +3 -0
  187. data/test/multiverse/test/suite_examples/one/a/a_test.rb +11 -0
  188. data/test/multiverse/test/suite_examples/one/a/config/newrelic.yml +24 -0
  189. data/test/multiverse/test/suite_examples/one/b/Envfile +3 -0
  190. data/test/multiverse/test/suite_examples/one/b/b_test.rb +11 -0
  191. data/test/multiverse/test/suite_examples/one/b/config/newrelic.yml +24 -0
  192. data/test/multiverse/test/suite_examples/three/a/Envfile +2 -0
  193. data/test/multiverse/test/suite_examples/three/a/fail_test.rb +6 -0
  194. data/test/multiverse/test/suite_examples/three/b/Envfile +2 -0
  195. data/test/multiverse/test/suite_examples/three/b/win_test.rb +6 -0
  196. data/test/multiverse/test/suite_examples/two/a/Envfile +1 -0
  197. data/test/multiverse/test/suite_examples/two/a/fail_test.rb +6 -0
  198. data/test/new_relic/agent/agent/connect_test.rb +151 -227
  199. data/test/new_relic/agent/agent/start_test.rb +68 -118
  200. data/test/new_relic/agent/agent/start_worker_thread_test.rb +12 -74
  201. data/test/new_relic/agent/agent_logger_test.rb +153 -0
  202. data/test/new_relic/agent/agent_test.rb +116 -30
  203. data/test/new_relic/agent/agent_test_controller.rb +1 -1
  204. data/test/new_relic/agent/agent_test_controller_test.rb +42 -10
  205. data/test/new_relic/agent/audit_logger_test.rb +105 -0
  206. data/test/new_relic/agent/beacon_configuration_test.rb +63 -67
  207. data/test/new_relic/agent/browser_monitoring_test.rb +151 -79
  208. data/test/new_relic/agent/busy_calculator_test.rb +7 -0
  209. data/test/new_relic/agent/configuration/environment_source_test.rb +79 -0
  210. data/test/new_relic/agent/configuration/manager_test.rb +204 -0
  211. data/test/new_relic/agent/configuration/server_source_test.rb +45 -0
  212. data/test/new_relic/agent/configuration/yaml_source_test.rb +75 -0
  213. data/test/new_relic/agent/cross_process_monitoring_test.rb +77 -0
  214. data/test/new_relic/agent/database_test.rb +12 -11
  215. data/test/new_relic/agent/error_collector/notice_error_test.rb +64 -53
  216. data/test/new_relic/agent/error_collector_test.rb +33 -19
  217. data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +60 -30
  218. data/test/new_relic/agent/instrumentation/browser_monitoring_timings_test.rb +39 -0
  219. data/test/new_relic/agent/instrumentation/metric_frame/pop_test.rb +1 -1
  220. data/test/new_relic/agent/instrumentation/metric_frame_test.rb +6 -0
  221. data/test/new_relic/agent/instrumentation/queue_time_test.rb +14 -0
  222. data/test/new_relic/agent/instrumentation/sinatra_test.rb +25 -0
  223. data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +2 -2
  224. data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +4 -10
  225. data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +3 -15
  226. data/test/new_relic/agent/method_tracer_test.rb +7 -6
  227. data/test/new_relic/agent/mock_scope_listener.rb +3 -0
  228. data/test/new_relic/agent/new_relic_service_test.rb +376 -0
  229. data/test/new_relic/agent/pipe_channel_manager_test.rb +131 -0
  230. data/test/new_relic/agent/pipe_service_test.rb +113 -0
  231. data/test/new_relic/agent/rpm_agent_test.rb +27 -50
  232. data/test/new_relic/agent/sql_sampler_test.rb +81 -56
  233. data/test/new_relic/agent/stats_engine/metric_stats/harvest_test.rb +3 -20
  234. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +12 -1
  235. data/test/new_relic/agent/stats_engine_test.rb +17 -8
  236. data/test/new_relic/agent/thread_profiler_test.rb +537 -0
  237. data/test/new_relic/agent/thread_test.rb +89 -0
  238. data/test/new_relic/agent/threaded_test.rb +65 -0
  239. data/test/new_relic/agent/transaction_info_test.rb +45 -4
  240. data/test/new_relic/agent/transaction_sample_builder_test.rb +8 -7
  241. data/test/new_relic/agent/transaction_sampler_test.rb +193 -204
  242. data/test/new_relic/agent/worker_loop_test.rb +26 -11
  243. data/test/new_relic/agent_test.rb +113 -33
  244. data/test/new_relic/collection_helper_test.rb +7 -8
  245. data/test/new_relic/command/deployments_test.rb +18 -2
  246. data/test/new_relic/control/class_methods_test.rb +0 -18
  247. data/test/new_relic/control/frameworks/rails_test.rb +26 -0
  248. data/test/new_relic/control_test.rb +96 -137
  249. data/test/new_relic/delayed_job_injection_test.rb +6 -1
  250. data/test/new_relic/dispatcher_test.rb +54 -0
  251. data/test/new_relic/fake_collector.rb +283 -0
  252. data/test/new_relic/fake_service.rb +53 -0
  253. data/test/new_relic/fakes_sending_data.rb +30 -0
  254. data/test/new_relic/framework_test.rb +53 -0
  255. data/test/new_relic/load_test.rb +13 -0
  256. data/test/new_relic/local_environment_test.rb +11 -11
  257. data/test/new_relic/metric_data_test.rb +45 -16
  258. data/test/new_relic/noticed_error_test.rb +24 -0
  259. data/test/new_relic/rack/browser_monitoring_test.rb +20 -10
  260. data/test/new_relic/rack/developer_mode_test.rb +13 -7
  261. data/test/new_relic/rack/error_collector_test.rb +74 -0
  262. data/test/new_relic/stats_test.rb +10 -0
  263. data/test/new_relic/transaction_sample/segment_test.rb +23 -4
  264. data/test/new_relic/transaction_sample_test.rb +47 -2
  265. data/test/new_relic/version_number_test.rb +32 -0
  266. data/test/script/build_test_gem.sh +9 -3
  267. data/test/script/ci.sh +108 -35
  268. data/test/script/ci_agent-tests_runner.sh +82 -0
  269. data/test/script/ci_multiverse_runner.sh +63 -0
  270. data/test/test_contexts.rb +1 -0
  271. data/test/test_helper.rb +68 -18
  272. data/ui/helpers/developer_mode_helper.rb +21 -11
  273. data/ui/views/layouts/newrelic_default.rhtml +1 -0
  274. data/ui/views/newrelic/file/images/arrow-close.png +0 -0
  275. data/ui/views/newrelic/file/images/arrow-open.png +0 -0
  276. data/ui/views/newrelic/file/images/blue_bar.gif +0 -0
  277. data/ui/views/newrelic/file/images/file_icon.png +0 -0
  278. data/ui/views/newrelic/file/images/gray_bar.gif +0 -0
  279. data/ui/views/newrelic/show_sample.rhtml +1 -1
  280. data/ui/views/newrelic/threads.rhtml +2 -10
  281. data/vendor/gems/metric_parser-0.1.0.pre1/.specification +116 -0
  282. data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/servlet_init.rb +7 -0
  283. metadata +191 -65
  284. data/lib/new_relic/agent/samplers/delayed_job_lock_sampler.rb +0 -40
  285. data/lib/new_relic/control/configuration.rb +0 -206
  286. data/lib/new_relic/control/logging_methods.rb +0 -143
  287. data/lib/new_relic/data_serialization.rb +0 -151
  288. data/test/new_relic/control/configuration_test.rb +0 -84
  289. data/test/new_relic/control/logging_methods_test.rb +0 -185
  290. data/test/new_relic/data_serialization_test.rb +0 -208
@@ -0,0 +1,10 @@
1
+ module NewRelic
2
+ module Agent
3
+ module Configuration
4
+ MASK_DEFAULTS = {
5
+ :'thread_profiler' => Proc.new { !NewRelic::Agent::ThreadProfiler.is_supported? },
6
+ :'thread_profiler.enabled' => Proc.new { !NewRelic::Agent::ThreadProfiler.is_supported? },
7
+ }
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,27 @@
1
+ module NewRelic
2
+ module Agent
3
+ module Configuration
4
+ class ServerSource < DottedHash
5
+ def initialize(hash)
6
+ if hash['agent_config']
7
+ if hash['agent_config']['transaction_tracer.transaction_threshold'] =~ /apdex_f/i
8
+ # when value is "apdex_f" remove the config and defer to default
9
+ hash['agent_config'].delete('transaction_tracer.transaction_threshold')
10
+ end
11
+ super(hash.delete('agent_config'))
12
+ end
13
+
14
+ string_map = [
15
+ ['collect_traces', 'transaction_tracer.enabled'],
16
+ ['collect_traces', 'slow_sql.enabled'],
17
+ ['collect_errors', 'error_collector.enabled']
18
+ ].each do |pair|
19
+ hash[pair[1]] = hash[pair[0]] if hash[pair[0]] != nil
20
+ end
21
+
22
+ super
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,63 @@
1
+ require 'new_relic/agent/configuration'
2
+
3
+ module NewRelic
4
+ module Agent
5
+ module Configuration
6
+ class YamlSource < DottedHash
7
+ attr_accessor :file_path
8
+
9
+ def initialize(path, env)
10
+ ::NewRelic::Agent.logger.debug("Reading configuration from #{path}")
11
+
12
+ config = {}
13
+ begin
14
+ @file_path = File.expand_path(path)
15
+ if !File.exists?(@file_path)
16
+ ::NewRelic::Agent.logger.error("Unable to load configuration from #{path}")
17
+ return
18
+ end
19
+
20
+ file = File.read(@file_path)
21
+
22
+ # Next two are for populating the newrelic.yml via erb binding, necessary
23
+ # when using the default newrelic.yml file
24
+ generated_for_user = ''
25
+ license_key = ''
26
+
27
+ erb = ERB.new(file).result(binding)
28
+ config = merge!(YAML.load(erb)[env] || {})
29
+ rescue ScriptError, StandardError => e
30
+ ::NewRelic::Agent.logger.error("Unable to read configuration file #{path}: #{e}")
31
+ end
32
+
33
+ if config['transaction_tracer'] &&
34
+ config['transaction_tracer']['transaction_threshold'] =~ /apdex_f/i
35
+ # when value is "apdex_f" remove the config and defer to default
36
+ config['transaction_tracer'].delete('transaction_threshold')
37
+ end
38
+
39
+ booleanify_values(config, 'agent_enabled', 'enabled', 'monitor_daemons')
40
+
41
+ super(config)
42
+ end
43
+
44
+ protected
45
+
46
+ def booleanify_values(config, *keys)
47
+ # auto means defer ro default
48
+ keys.each do |option|
49
+ if config[option] == 'auto'
50
+ config.delete(option)
51
+ elsif !config[option].nil? && !is_boolean?(config[option])
52
+ config[option] = !!(config[option] =~ /yes|on|true/i)
53
+ end
54
+ end
55
+ end
56
+
57
+ def is_boolean?(value)
58
+ value == !!value
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,43 @@
1
+ module NewRelic
2
+ module Agent
3
+ module CrossProcessMonitoring
4
+
5
+ module_function
6
+
7
+ def insert_response_header(request, response)
8
+ if Agent.config[:'cross_process.enabled'] &&
9
+ NewRelic::Agent.instance.cross_process_id && (id = id_from_request(request))
10
+
11
+ content_length = -1
12
+ timings = NewRelic::Agent::BrowserMonitoring.timings
13
+
14
+ # FIXME the transaction name might not be properly encoded. use a json generator
15
+ payload = %[["#{NewRelic::Agent.instance.cross_process_id}","#{timings.transaction_name}",#{timings.queue_time_in_millis},#{timings.app_time_in_millis},#{content_length}] ]
16
+ payload = obfuscate_with_key(payload, NewRelic::Agent.instance.cross_process_encoding_bytes)
17
+
18
+ response['X-NewRelic-App-Data'] = payload
19
+ #FIXME generate ClientApplication metric. id must be decoded first
20
+ # String metricName = MessageFormat.format("ClientApplication/{0}/all", id);
21
+ end
22
+ end
23
+
24
+ def obfuscate_with_key(text, key_bytes)
25
+ obfuscated = ""
26
+ index = 0
27
+ text.each_byte{|byte|
28
+ obfuscated.concat((byte ^ key_bytes[index % key_bytes.length].to_i))
29
+ index+=1
30
+ }
31
+
32
+ [obfuscated].pack("m0").gsub("\n", '')
33
+ end
34
+
35
+ def id_from_request(request)
36
+ %w{X-NewRelic-ID HTTP_X_NEWRELIC_ID X_NEWRELIC_ID}.each do |header|
37
+ return request.env[header] if request.env.has_key?(header)
38
+ end
39
+ nil
40
+ end
41
+ end
42
+ end
43
+ end
@@ -14,27 +14,42 @@ module NewRelic
14
14
  "Rows",
15
15
  "Extra"
16
16
  ].freeze
17
-
17
+
18
18
  module Agent
19
19
  module Database
20
20
  extend self
21
-
21
+
22
22
  def obfuscate_sql(sql)
23
23
  Obfuscator.instance.obfuscator.call(sql)
24
24
  end
25
-
25
+
26
26
  def set_sql_obfuscator(type, &block)
27
27
  Obfuscator.instance.set_sql_obfuscator(type, &block)
28
28
  end
29
-
29
+
30
+ def record_sql_method
31
+ case Agent.config[:'transaction_tracer.record_sql'].to_s
32
+ when 'off'
33
+ :off
34
+ when 'none'
35
+ :off
36
+ when 'false'
37
+ :off
38
+ when 'raw'
39
+ :raw
40
+ else
41
+ :obfuscated
42
+ end
43
+ end
44
+
30
45
  def get_connection(config)
31
46
  ConnectionManager.instance.get_connection(config)
32
47
  end
33
-
48
+
34
49
  def close_connections
35
50
  ConnectionManager.instance.close_connections
36
51
  end
37
-
52
+
38
53
  # Perform this in the runtime environment of a managed
39
54
  # application, to explain the sql statement executed within a
40
55
  # segment of a transaction sample. Returns an array of
@@ -50,7 +65,7 @@ module NewRelic
50
65
  explain_sql = explain_statement(statement, connection_config)
51
66
  return explain_sql || []
52
67
  end
53
-
68
+
54
69
  def explain_statement(statement, config)
55
70
  if is_select?(statement)
56
71
  handle_exception_in_explain do
@@ -63,12 +78,12 @@ module NewRelic
63
78
  end
64
79
  end
65
80
  end
66
-
81
+
67
82
  def process_resultset(items)
68
83
  # The resultset type varies for different drivers. Only thing you can count on is
69
84
  # that it implements each. Also: can't use select_rows because the native postgres
70
85
  # driver doesn't know that method.
71
-
86
+
72
87
  headers = []
73
88
  values = []
74
89
  if items.respond_to?(:each_hash)
@@ -88,7 +103,7 @@ module NewRelic
88
103
  else
89
104
  values = [items]
90
105
  end
91
-
106
+
92
107
  headers = nil if headers.empty?
93
108
  [headers, values]
94
109
  end
@@ -98,20 +113,19 @@ module NewRelic
98
113
  rescue => e
99
114
  begin
100
115
  # guarantees no throw from explain_sql
101
- NewRelic::Control.instance.log.error("Error getting query plan: #{e.message}")
102
- NewRelic::Control.instance.log.debug(e.backtrace.join("\n"))
116
+ ::NewRelic::Agent.logger.error("Error getting query plan:", e)
103
117
  rescue
104
118
  # double exception. throw up your hands
105
119
  end
106
120
  end
107
-
121
+
108
122
  def is_select?(statement)
109
123
  # split the string into at most two segments on the
110
124
  # system-defined field separator character
111
125
  first_word, rest_of_statement = statement.split($;, 2)
112
126
  (first_word.upcase == 'SELECT')
113
127
  end
114
-
128
+
115
129
  class ConnectionManager
116
130
  include Singleton
117
131
 
@@ -121,21 +135,20 @@ module NewRelic
121
135
  # the sql
122
136
  def get_connection(config)
123
137
  @connections ||= {}
124
-
138
+
125
139
  connection = @connections[config]
126
-
140
+
127
141
  return connection if connection
128
-
142
+
129
143
  begin
130
144
  connection = ActiveRecord::Base.send("#{config[:adapter]}_connection", config)
131
145
  @connections[config] = connection
132
146
  rescue => e
133
- NewRelic::Agent.agent.log.error("Caught exception #{e} trying to get connection to DB for explain. Control: #{config}")
134
- NewRelic::Agent.agent.log.error(e.backtrace.join("\n"))
147
+ ::NewRelic::Agent.logger.error("Caught exception trying to get connection to DB for explain. Control: #{config}", e)
135
148
  nil
136
149
  end
137
150
  end
138
-
151
+
139
152
  # Closes all the connections in the internal connection cache
140
153
  def close_connections
141
154
  @connections ||= {}
@@ -145,16 +158,16 @@ module NewRelic
145
158
  rescue
146
159
  end
147
160
  end
148
-
161
+
149
162
  @connections = {}
150
163
  end
151
164
  end
152
165
 
153
166
  class Obfuscator
154
167
  include Singleton
155
-
168
+
156
169
  attr_reader :obfuscator
157
-
170
+
158
171
  def initialize
159
172
  reset
160
173
  end
@@ -162,7 +175,7 @@ module NewRelic
162
175
  def reset
163
176
  @obfuscator = method(:default_sql_obfuscator)
164
177
  end
165
-
178
+
166
179
  # Sets the sql obfuscator used to clean up sql when sending it
167
180
  # to the server. Possible types are:
168
181
  #
@@ -185,7 +198,7 @@ module NewRelic
185
198
  fail "unknown sql_obfuscator type #{type}"
186
199
  end
187
200
  end
188
-
201
+
189
202
  def default_sql_obfuscator(sql)
190
203
  stmt = sql.kind_of?(Statement) ? sql : Statement.new(sql)
191
204
  adapter = stmt.adapter
@@ -215,7 +228,7 @@ module NewRelic
215
228
  end
216
229
  end
217
230
 
218
- class Statement < String
231
+ class Statement < String
219
232
  attr_accessor :adapter
220
233
  end
221
234
  end
@@ -10,38 +10,43 @@ module NewRelic
10
10
  module Shim #:nodoc:
11
11
  def notice_error(*args); end
12
12
  end
13
-
13
+
14
14
  # Maximum possible length of the queue - defaults to 20, may be
15
15
  # made configurable in the future. This is a tradeoff between
16
16
  # memory and data retention
17
17
  MAX_ERROR_QUEUE_LENGTH = 20 unless defined? MAX_ERROR_QUEUE_LENGTH
18
18
 
19
- attr_accessor :enabled
20
- attr_reader :config_enabled
21
-
19
+ attr_accessor :errors
20
+
22
21
  # Returns a new error collector
23
22
  def initialize
24
23
  @errors = []
25
24
  # lookup of exception class names to ignore. Hash for fast access
26
25
  @ignore = {}
26
+ @capture_source = Agent.config[:'error_collector.capture_source']
27
27
 
28
- config = NewRelic::Control.instance.fetch('error_collector', {})
29
-
30
- @enabled = @config_enabled = config.fetch('enabled', true)
31
- @capture_source = config.fetch('capture_source', true)
28
+ initialize_ignored_errors(Agent.config[:'error_collector.ignore_errors'])
29
+ @lock = Mutex.new
32
30
 
33
- ignore_errors = config.fetch('ignore_errors', "")
31
+ Agent.config.register_callback(:'error_collector.enabled') do |config_enabled|
32
+ ::NewRelic::Agent.logger.debug "Errors will #{config_enabled ? '' : 'not '}be sent to the New Relic service."
33
+ end
34
+ Agent.config.register_callback(:'error_collector.ignore_errors') do |ignore_errors|
35
+ initialize_ignored_errors(ignore_errors)
36
+ end
37
+ end
38
+
39
+ def initialize_ignored_errors(ignore_errors)
40
+ @ignore.clear
34
41
  ignore_errors = ignore_errors.split(",") if ignore_errors.is_a? String
35
42
  ignore_errors.each { |error| error.strip! }
36
43
  ignore(ignore_errors)
37
- @lock = Mutex.new
38
44
  end
39
-
40
- # Helper method to get the NewRelic::Control.instance
41
- def control
42
- NewRelic::Control.instance
45
+
46
+ def enabled?
47
+ Agent.config[:'error_collector.enabled']
43
48
  end
44
-
49
+
45
50
  # Returns the error filter proc that is used to check if an
46
51
  # error should be reported. When given a block, resets the
47
52
  # filter to the provided block. The define_method() is used to
@@ -59,45 +64,43 @@ module NewRelic
59
64
  # errors is an array of Exception Class Names
60
65
  #
61
66
  def ignore(errors)
62
- errors.each { |error| @ignore[error] = true; log.debug("Ignoring errors of type '#{error}'") }
67
+ errors.each do |error|
68
+ @ignore[error] = true
69
+ ::NewRelic::Agent.logger.debug("Ignoring errors of type '#{error}'")
70
+ end
63
71
  end
64
-
72
+
65
73
  # This module was extracted from the notice_error method - it is
66
74
  # internally tested and can be refactored without major issues.
67
75
  module NoticeError
68
- # Whether the error collector is disabled or not
69
- def disabled?
70
- !@enabled
71
- end
72
-
73
76
  # Checks the provided error against the error filter, if there
74
77
  # is an error filter
75
78
  def filtered_by_error_filter?(error)
76
79
  return unless @ignore_filter
77
80
  !@ignore_filter.call(error)
78
81
  end
79
-
82
+
80
83
  # Checks the array of error names and the error filter against
81
84
  # the provided error
82
85
  def filtered_error?(error)
83
86
  @ignore[error.class.name] || filtered_by_error_filter?(error)
84
87
  end
85
-
88
+
86
89
  # an error is ignored if it is nil or if it is filtered
87
90
  def error_is_ignored?(error)
88
91
  error && filtered_error?(error)
89
92
  end
90
-
93
+
91
94
  # Increments a statistic that tracks total error rate
92
95
  def increment_error_count!
93
96
  NewRelic::Agent.get_stats("Errors/all").increment_count
94
97
  end
95
-
98
+
96
99
  # whether we should return early from the notice_error process
97
100
  # - based on whether the error is ignored or the error
98
101
  # collector is disabled
99
102
  def should_exit_notice_error?(exception)
100
- if @enabled
103
+ if enabled?
101
104
  if !error_is_ignored?(exception)
102
105
  increment_error_count!
103
106
  return exception.nil? # exit early if the exception is nil
@@ -106,40 +109,40 @@ module NewRelic
106
109
  # disabled or an ignored error, per above
107
110
  true
108
111
  end
109
-
112
+
110
113
  # acts just like Hash#fetch, but deletes the key from the hash
111
114
  def fetch_from_options(options, key, default=nil)
112
115
  options.delete(key) || default
113
116
  end
114
-
117
+
115
118
  # returns some basic option defaults pulled from the provided
116
119
  # options hash
117
120
  def uri_ref_and_root(options)
118
121
  {
119
122
  :request_uri => fetch_from_options(options, :uri, ''),
120
123
  :request_referer => fetch_from_options(options, :referer, ''),
121
- :rails_root => control.root
124
+ :rails_root => NewRelic::Control.instance.root
122
125
  }
123
126
  end
124
-
127
+
125
128
  # If anything else is left over, we treat it like a custom param
126
129
  def custom_params_from_opts(options)
127
130
  # If anything else is left over, treat it like a custom param:
128
131
  fetch_from_options(options, :custom_params, {}).merge(options)
129
132
  end
130
-
133
+
131
134
  # takes the request parameters out of the options hash, and
132
135
  # returns them if we are capturing parameters, otherwise
133
136
  # returns nil
134
137
  def request_params_from_opts(options)
135
138
  value = options.delete(:request_params)
136
- if control.capture_params
139
+ if Agent.config[:capture_params]
137
140
  value
138
141
  else
139
142
  nil
140
143
  end
141
144
  end
142
-
145
+
143
146
  # normalizes the request and custom parameters before attaching
144
147
  # them to the error. See NewRelic::CollectionHelper#normalize_params
145
148
  def normalized_request_and_custom_params(options)
@@ -148,32 +151,32 @@ module NewRelic
148
151
  :custom_params => normalize_params(custom_params_from_opts(options))
149
152
  }
150
153
  end
151
-
154
+
152
155
  # Merges together many of the options into something that can
153
156
  # actually be attached to the error
154
157
  def error_params_from_options(options)
155
158
  uri_ref_and_root(options).merge(normalized_request_and_custom_params(options))
156
159
  end
157
-
160
+
158
161
  # calls a method on an object, if it responds to it - used for
159
162
  # detection and soft fail-safe. Returns nil if the method does
160
163
  # not exist
161
164
  def sense_method(object, method)
162
165
  object.send(method) if object.respond_to?(method)
163
166
  end
164
-
167
+
165
168
  # extracts source from the exception, if the exception supports
166
169
  # that method
167
170
  def extract_source(exception)
168
171
  sense_method(exception, 'source_extract') if @capture_source
169
172
  end
170
-
173
+
171
174
  # extracts a stack trace from the exception for debugging purposes
172
175
  def extract_stack_trace(exception)
173
176
  actual_exception = sense_method(exception, 'original_exception') || exception
174
177
  sense_method(actual_exception, 'backtrace') || '<no stack trace>'
175
178
  end
176
-
179
+
177
180
  # extracts a bunch of information from the exception to include
178
181
  # in the noticed error - some may or may not be available, but
179
182
  # we try to include all of it
@@ -185,22 +188,23 @@ module NewRelic
185
188
  :stack_trace => extract_stack_trace(exception)
186
189
  }
187
190
  end
188
-
191
+
189
192
  # checks the size of the error queue to make sure we are under
190
193
  # the maximum limit, and logs a warning if we are over the limit.
191
194
  def over_queue_limit?(message)
192
195
  over_limit = (@errors.length >= MAX_ERROR_QUEUE_LENGTH)
193
- log.warn("The error reporting queue has reached #{MAX_ERROR_QUEUE_LENGTH}. The error detail for this and subsequent errors will not be transmitted to New Relic until the queued errors have been sent: #{message}") if over_limit
196
+ ::NewRelic::Agent.logger.warn("The error reporting queue has reached #{MAX_ERROR_QUEUE_LENGTH}. The error detail for this and subsequent errors will not be transmitted to New Relic until the queued errors have been sent: #{message}") if over_limit
194
197
  over_limit
195
198
  end
196
199
 
197
-
198
200
  # Synchronizes adding an error to the error queue, and checks if
199
201
  # the error queue is too long - if so, we drop the error on the
200
202
  # floor after logging a warning.
201
203
  def add_to_error_queue(noticed_error)
202
204
  @lock.synchronize do
203
- @errors << noticed_error unless over_queue_limit?(noticed_error.message)
205
+ if !over_queue_limit?(noticed_error.message) && !@errors.include?(noticed_error)
206
+ @errors << noticed_error
207
+ end
204
208
  end
205
209
  end
206
210
  end
@@ -224,7 +228,7 @@ module NewRelic
224
228
  add_to_error_queue(NewRelic::NoticedError.new(action_path, exception_options, exception))
225
229
  exception
226
230
  rescue => e
227
- log.error("Error capturing an error, yodawg. #{e}")
231
+ ::NewRelic::Agent.logger.warn("Failure when capturing error '#{exception}':", e)
228
232
  end
229
233
 
230
234
  # Get the errors currently queued up. Unsent errors are left
@@ -241,11 +245,6 @@ module NewRelic
241
245
  errors
242
246
  end
243
247
  end
244
-
245
- private
246
- def log
247
- NewRelic::Agent.logger
248
- end
249
248
  end
250
249
  end
251
250
  end