Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Revert "Get New Relic working again"

This reverts commit ec05e3d.
  • Loading branch information...
commit 4ce22dce3bc6107d2bd58e77c6cbc2ae819b4640 1 parent b8bfee2
Jose Fernandez authored
Showing with 22,293 additions and 59 deletions.
  1. +1 −2  .gitignore
  2. +0 −1  Gemfile
  3. +0 −2  Gemfile.lock
  4. +11 −9 config.ru
  5. +7 −0 vendor/plugins/newrelic_rpm/.gitignore
  6. +17 −0 vendor/plugins/newrelic_rpm/.project
  7. +411 −0 vendor/plugins/newrelic_rpm/CHANGELOG
  8. +37 −0 vendor/plugins/newrelic_rpm/LICENSE
  9. +138 −0 vendor/plugins/newrelic_rpm/README.md
  10. +87 −0 vendor/plugins/newrelic_rpm/Rakefile
  11. +33 −0 vendor/plugins/newrelic_rpm/bin/mongrel_rpm
  12. +4 −0 vendor/plugins/newrelic_rpm/bin/newrelic_cmd
  13. +34 −0 vendor/plugins/newrelic_rpm/cert/cacert.pem
  14. +35 −0 vendor/plugins/newrelic_rpm/init.rb
  15. +46 −0 vendor/plugins/newrelic_rpm/install.rb
  16. +364 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent.rb
  17. +649 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/agent.rb
  18. +91 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/busy_calculator.rb
  19. +13 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/chained_call.rb
  20. +128 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/error_collector.rb
  21. +18 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/active_merchant.rb
  22. +92 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/active_record_instrumentation.rb
  23. +8 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/authlogic.rb
  24. +402 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/controller_instrumentation.rb
  25. +90 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/data_mapper.rb
  26. +22 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb
  27. +29 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/memcache.rb
  28. +26 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/merb/controller.rb
  29. +9 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/merb/errors.rb
  30. +296 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/metric_frame.rb
  31. +17 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/net.rb
  32. +20 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb
  33. +112 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/rack.rb
  34. +59 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/rails/action_controller.rb
  35. +27 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/rails/action_web_service.rb
  36. +24 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/rails/errors.rb
  37. +45 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/rails3/action_controller.rb
  38. +21 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/rails3/errors.rb
  39. +46 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/sinatra.rb
  40. +10 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb
  41. +350 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/method_tracer.rb
  42. +46 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/sampler.rb
  43. +54 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/samplers/cpu_sampler.rb
  44. +37 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/samplers/delayed_job_lock_sampler.rb
  45. +142 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/samplers/memory_sampler.rb
  46. +24 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/samplers/object_sampler.rb
  47. +21 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/shim_agent.rb
  48. +24 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/stats_engine.rb
  49. +118 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/stats_engine/metric_stats.rb
  50. +80 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/stats_engine/samplers.rb
  51. +149 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/stats_engine/transactions.rb
  52. +315 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/transaction_sampler.rb
  53. +80 −0 vendor/plugins/newrelic_rpm/lib/new_relic/agent/worker_loop.rb
  54. +68 −0 vendor/plugins/newrelic_rpm/lib/new_relic/collection_helper.rb
  55. +145 −0 vendor/plugins/newrelic_rpm/lib/new_relic/commands/deployments.rb
  56. +30 −0 vendor/plugins/newrelic_rpm/lib/new_relic/commands/new_relic_commands.rb
  57. +517 −0 vendor/plugins/newrelic_rpm/lib/new_relic/control.rb
  58. +13 −0 vendor/plugins/newrelic_rpm/lib/new_relic/control/external.rb
  59. +24 −0 vendor/plugins/newrelic_rpm/lib/new_relic/control/merb.rb
  60. +151 −0 vendor/plugins/newrelic_rpm/lib/new_relic/control/rails.rb
  61. +75 −0 vendor/plugins/newrelic_rpm/lib/new_relic/control/rails3.rb
  62. +36 −0 vendor/plugins/newrelic_rpm/lib/new_relic/control/ruby.rb
  63. +18 −0 vendor/plugins/newrelic_rpm/lib/new_relic/control/sinatra.rb
  64. +25 −0 vendor/plugins/newrelic_rpm/lib/new_relic/delayed_job_injection.rb
  65. +89 −0 vendor/plugins/newrelic_rpm/lib/new_relic/histogram.rb
  66. +332 −0 vendor/plugins/newrelic_rpm/lib/new_relic/local_environment.rb
  67. +6 −0 vendor/plugins/newrelic_rpm/lib/new_relic/merbtasks.rb
  68. +42 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metric_data.rb
  69. +125 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metric_parser.rb
  70. +9 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metric_parser/action_mailer.rb
  71. +26 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metric_parser/active_merchant.rb
  72. +25 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metric_parser/active_record.rb
  73. +54 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metric_parser/controller.rb
  74. +38 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metric_parser/controller_cpu.rb
  75. +6 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metric_parser/errors.rb
  76. +50 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metric_parser/external.rb
  77. +50 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metric_parser/mem_cache.rb
  78. +15 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metric_parser/other_transaction.rb
  79. +61 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metric_parser/view.rb
  80. +14 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metric_parser/web_frontend.rb
  81. +9 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metric_parser/web_service.rb
  82. +67 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metric_spec.rb
  83. +9 −0 vendor/plugins/newrelic_rpm/lib/new_relic/metrics.rb
  84. +24 −0 vendor/plugins/newrelic_rpm/lib/new_relic/noticed_error.rb
  85. +58 −0 vendor/plugins/newrelic_rpm/lib/new_relic/rack/metric_app.rb
  86. +25 −0 vendor/plugins/newrelic_rpm/lib/new_relic/rack/mongrel_rpm.ru
  87. +26 −0 vendor/plugins/newrelic_rpm/lib/new_relic/rack/newrelic.yml
  88. +5 −0 vendor/plugins/newrelic_rpm/lib/new_relic/rack_app.rb
  89. +82 −0 vendor/plugins/newrelic_rpm/lib/new_relic/recipes.rb
  90. +376 −0 vendor/plugins/newrelic_rpm/lib/new_relic/stats.rb
  91. +124 −0 vendor/plugins/newrelic_rpm/lib/new_relic/transaction_analysis.rb
  92. +654 −0 vendor/plugins/newrelic_rpm/lib/new_relic/transaction_sample.rb
  93. +55 −0 vendor/plugins/newrelic_rpm/lib/new_relic/version.rb
  94. +276 −0 vendor/plugins/newrelic_rpm/lib/new_relic_api.rb
  95. +40 −0 vendor/plugins/newrelic_rpm/lib/newrelic_rpm.rb
  96. +4 −0 vendor/plugins/newrelic_rpm/lib/tasks/all.rb
  97. +7 −0 vendor/plugins/newrelic_rpm/lib/tasks/install.rake
  98. +15 −0 vendor/plugins/newrelic_rpm/lib/tasks/tests.rake
  99. +46 −45 {config → vendor/plugins/newrelic_rpm}/newrelic.yml
  100. +6 −0 vendor/plugins/newrelic_rpm/recipes/newrelic.rb
  101. +55 −0 vendor/plugins/newrelic_rpm/test/active_record_fixtures.rb
  102. +43 −0 vendor/plugins/newrelic_rpm/test/config/newrelic.yml
  103. +38 −0 vendor/plugins/newrelic_rpm/test/config/test_control.rb
  104. +287 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/active_record_instrumentation_test.rb
  105. +274 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/agent_controller_test.rb
  106. +78 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/agent_test_controller.rb
  107. +79 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/busy_calculator_test.rb
  108. +125 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/collection_helper_test.rb
  109. +171 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/error_collector_test.rb
  110. +103 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/memcache_instrumentation_test.rb
  111. +340 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/method_tracer_test.rb
  112. +56 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/metric_data_test.rb
  113. +51 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/metric_frame_test.rb
  114. +40 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/mock_ar_connection.rb
  115. +23 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/mock_scope_listener.rb
  116. +77 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/net_instrumentation_test.rb
  117. +138 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/rpm_agent_test.rb
  118. +79 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/stats_engine/metric_stats_test.rb
  119. +72 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/stats_engine/samplers_test.rb
  120. +184 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/stats_engine/stats_engine_test.rb
  121. +193 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/task_instrumentation_test.rb
  122. +13 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/testable_agent.rb
  123. +195 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/transaction_sample_builder_test.rb
  124. +186 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/transaction_sample_test.rb
  125. +385 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/transaction_sampler_test.rb
  126. +60 −0 vendor/plugins/newrelic_rpm/test/new_relic/agent/worker_loop_test.rb
  127. +117 −0 vendor/plugins/newrelic_rpm/test/new_relic/control_test.rb
  128. +68 −0 vendor/plugins/newrelic_rpm/test/new_relic/deployments_api_test.rb
  129. +75 −0 vendor/plugins/newrelic_rpm/test/new_relic/environment_test.rb
  130. +172 −0 vendor/plugins/newrelic_rpm/test/new_relic/metric_parser_test.rb
  131. +177 −0 vendor/plugins/newrelic_rpm/test/new_relic/metric_spec_test.rb
  132. +9 −0 vendor/plugins/newrelic_rpm/test/new_relic/shim_agent_test.rb
  133. +311 −0 vendor/plugins/newrelic_rpm/test/new_relic/stats_test.rb
  134. +89 −0 vendor/plugins/newrelic_rpm/test/new_relic/version_number_test.rb
  135. +53 −0 vendor/plugins/newrelic_rpm/test/test_helper.rb
  136. +14 −0 vendor/plugins/newrelic_rpm/test/ui/newrelic_controller_test.rb
  137. +53 −0 vendor/plugins/newrelic_rpm/test/ui/newrelic_helper_test.rb
  138. +220 −0 vendor/plugins/newrelic_rpm/ui/controllers/newrelic_controller.rb
  139. +49 −0 vendor/plugins/newrelic_rpm/ui/helpers/google_pie_chart.rb
  140. +319 −0 vendor/plugins/newrelic_rpm/ui/helpers/newrelic_helper.rb
  141. +47 −0 vendor/plugins/newrelic_rpm/ui/views/layouts/newrelic_default.rhtml
  142. +27 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/_explain_plans.rhtml
  143. +19 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/_sample.rhtml
  144. +28 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/_segment.rhtml
  145. +1 −0  vendor/plugins/newrelic_rpm/ui/views/newrelic/_segment_limit_message.rhtml
  146. +14 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/_segment_row.rhtml
  147. +24 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/_show_sample_detail.rhtml
  148. +20 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/_show_sample_sql.rhtml
  149. +3 −0  vendor/plugins/newrelic_rpm/ui/views/newrelic/_show_sample_summary.rhtml
  150. +11 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/_sql_row.rhtml
  151. +30 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/_stack_trace.rhtml
  152. +12 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/_table.rhtml
  153. +42 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/explain_sql.rhtml
  154. BIN  vendor/plugins/newrelic_rpm/ui/views/newrelic/images/arrow-close.png
  155. BIN  vendor/plugins/newrelic_rpm/ui/views/newrelic/images/arrow-open.png
  156. BIN  vendor/plugins/newrelic_rpm/ui/views/newrelic/images/blue_bar.gif
  157. BIN  vendor/plugins/newrelic_rpm/ui/views/newrelic/images/file_icon.png
  158. BIN  vendor/plugins/newrelic_rpm/ui/views/newrelic/images/gray_bar.gif
  159. BIN  vendor/plugins/newrelic_rpm/ui/views/newrelic/images/new-relic-rpm-desktop.gif
  160. BIN  vendor/plugins/newrelic_rpm/ui/views/newrelic/images/new_relic_rpm_desktop.gif
  161. BIN  vendor/plugins/newrelic_rpm/ui/views/newrelic/images/textmate.png
  162. +57 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/index.rhtml
  163. +7,288 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/javascript/prototype-scriptaculous.js
  164. +107 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/javascript/transaction_sample.js
  165. +2 −0  vendor/plugins/newrelic_rpm/ui/views/newrelic/sample_not_found.rhtml
  166. +80 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/show_sample.rhtml
  167. +3 −0  vendor/plugins/newrelic_rpm/ui/views/newrelic/show_source.rhtml
  168. +484 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/stylesheets/style.css
  169. +52 −0 vendor/plugins/newrelic_rpm/ui/views/newrelic/threads.rhtml
View
3  .gitignore
@@ -1,2 +1 @@
-.DS_Store
-log
+.DS_Store
View
1  Gemfile
@@ -5,4 +5,3 @@ gem 'builder'
gem 'rack-rewrite'
gem 'rdiscount'
gem 'toto', :git => "git://github.com/cloudhead/toto.git"
-gem 'newrelic_rpm'
View
2  Gemfile.lock
@@ -11,7 +11,6 @@ GEM
remote: https://rubygems.org/
specs:
builder (3.0.0)
- newrelic_rpm (3.3.4.1)
rack (1.4.1)
rack-rewrite (1.2.1)
rdiscount (1.6.8)
@@ -21,7 +20,6 @@ PLATFORMS
DEPENDENCIES
builder
- newrelic_rpm
rack-rewrite
rdiscount
toto!
View
20 config.ru
@@ -11,17 +11,19 @@ end
use Rack::Static, :urls => ['/css', '/js', '/images', '/favicon.ico', '/robots.txt'], :root => 'public'
use Rack::CommonLogger
-NewRelic::Agent.manual_start :app_name => 'Production Hacks', :agent_enabled => true
-
-require 'new_relic/agent/instrumentation/rack'
-module Toto
- class Server
- include NewRelic::Agent::Instrumentation::Rack
- end
-end
-
if ENV['RACK_ENV'] == "development"
use Rack::ShowExceptions
+else
+ #ENV['APP_ROOT'] ||= File.dirname(__FILE__)
+ #$:.unshift "#{ENV['APP_ROOT']}/vendor/plugins/newrelic_rpm/lib"
+ #require 'newrelic_rpm'
+ #require 'new_relic/agent/instrumentation/rack'
+
+ #module Toto
+ #class Server
+ #include NewRelic::Agent::Instrumentation::Rack
+ #end
+ #end
end
use Rack::Rewrite do
View
7 vendor/plugins/newrelic_rpm/.gitignore
@@ -0,0 +1,7 @@
+.DS\_Store
+.svn/
+*~
+pkg/
+*.gem
+!rails
+Manifest*
View
17 vendor/plugins/newrelic_rpm/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>New Relic Agent</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.rubypeople.rdt.core.rubybuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.rubypeople.rdt.core.rubynature</nature>
+ </natures>
+</projectDescription>
View
411 vendor/plugins/newrelic_rpm/CHANGELOG
@@ -0,0 +1,411 @@
+v2.11.1
+ * republished gem without generated rdocs
+
+v2.11.0
+ * rails3 instrumentation (no developer mode support yet)
+ * removed the ensure_worker_thread started and instead defined an after_fork
+ handler that will set up the agent properly in forked processes.
+ * change at_exit handler so the shutdown always goes after other shutdown
+ handlers
+ * add visibility to active record db transactions in the rpm transaction
+ traces (thanks to jeremy kemper)
+ * fix regression in merb support which caused merb apps not to start
+ * added NewRelic::Agent.logger to the public api to write to the agent
+ log file.
+ * optimizations to background thread, controller instrumentation, memory
+ usage
+ * add logger method to public_api
+ * support list notation for ignored exceptions in the newrelic.yml
+
+v2.10.8
+ * fix bug in delayed_job instrumentation that caused the job queue sampler
+ to run in the wrong place
+ * change startup sequence and code that restarts the worker loop
+ thread
+ * detect the unicorn master and dont start the agent; hook in after_fork
+ * fix problem with the Authlogic metric names which caused errors in
+ developer mode. Authlogic metrics now adhere to the convention of
+ prefixing the name with 'Custom'
+ * allow more correct overriding of transaction trace settings in the
+ call to #manual_start
+ * simplify WorkerLoop and add better protection for concurrency
+ * preliminary support for rails3
+
+v2.10.6
+ * fix missing URL and referer on some traced errors and transactions
+ * gather traced errors *after* executing the rescue chain in ActionController
+ * always load controller instrumentation
+ * pick up token validation from newrelic.yml
+
+v2.10.5
+ * fix bug in delayed_job instrumentation occurring when there was no DJ log
+
+v2.10.4
+ * fix incompatibility with Capistrano 2.5.16
+ * strip down URLs reported in transactions and errors to path only
+
+v2.10.3
+ * optimization to reduce overhead: move background samplers into foreground thread
+ * change default config file to ignore RoutingErrors
+ * moved the background task instrumentation into a separate tab in the RPM UI
+ * allow override of the RPM application name via NEWRELIC_APP_NAME environment variable
+ * revised Delayed::Job instrumentation so no manual_start is required
+ * send buffered data on shutdown
+ * expanded support for queue length and queue time
+ * remove calls to starts_with to fix Sinatra and non-rails deployments
+ * fix problem with apdex scores recording too low in some circumstances
+ * switch to jeweler for gem building
+ * minor fixes, test improvements, doc and rakefile improvements
+ * fix incompatibility with Hoptoad where Hoptoad was not getting errors handled by New Relic
+ * many other optimizations, bug fixes and documentation improvements
+
+v2.10.2.
+ * beta release of 2.10
+ * fix bugs with Sinatra app instrumentation
+ * minor doc updates
+
+v2.10.1.
+ * alpha release of 2.10
+ * rack support, including metal; ignores 404s; requires a module inclusion (see docs)
+ * sinatra support, displays actions named by the URI pattern matched
+ * add API method to abort transaction recording for in-flight transactions
+ * remove account management calls from newrelic_api.rb
+ * truncating extremely large transaction traces for efficiency
+ * fix error reporting in recipes; add newrelic_rails_env option to recipes to
+ override the rails env used to pull the app_name out of newrelic.yml
+ * added TorqueBox recognition (thanks Bob McWhirter)
+ * renamed config settings: enabled => monitor_mode; developer => developer_mode;
+ old names will still work in newrelic.yml
+ * instrumentation for DelayedJob (thanks Travis Tilley)
+ * added config switches to turn off certain instrumentation when you aren't
+ interested in the metrics, to save on overhead--see newrelic.yml for details.
+ * add profiling support to dev mode; very experimental!
+ * add 'multi_threaded' config option to indicate when the app is running
+ multi-threaded, so we can disable some instrumentation
+ * fix test failures in JRuby, REE
+ * improve Net::HTTP instrumentation so its more efficient and distinguishes calls
+ between web and non-web transactions.
+ * database instrumentation notices all database commands in addition to the core commands
+ * add support for textmate to dev mode
+ * added add_transaction_tracer method to support instrumenting methods as
+ if they were web transactions; this will facilitate better visibility of background
+ tasks and eventually things like rack, metal and Sinatra
+ * adjusted apdex scores to reflect time spent in the mongrel queue
+ * fixed incompatibility with JRuby on startup
+ * implmented CPU measure for JRuby which reflects the cpu burn for
+ all controller actions (does not include background tasks)
+ * fixed scope issue with GC instrumentation, subtracting time from caller
+ * added # of GC calls to GC instrumentation
+ * renamed the dispatcher metric
+ * refactored stats_engine code for readability
+ * optimization: reduce wakeup times for harvest thread
+
+v2.10.0.
+ * alpha release of 2.10
+ * support unicorn
+ * instrumentation of GC for REE and MRE with GC patch
+ * support agent restarting when changes are made to the account
+ * removed #newrelic_notice_error from Object class, replaced by NewRelic::Agent#notic_error
+ * collect histogram statistics
+ * add custom parameters to newrelic_notice_error call to display
+ extra info for errors
+ * add method disable_all_tracing(&block) to execute a block without
+ capturing metrics
+ * newrelic_ignore now blocks all instrumentation collection for
+ the specified actions
+ * added doc to method_tracer API and removed second arg
+ requirement for add_method_tracer call
+ * instrumentation for Net::HTTP
+ * remove method_tracer shim to avoid timing problems in monitoring daemons
+ * for non-rails daemons, look at APP_ROOT and NRCONFIG env vars for custom locations
+
+v2.9.9.
+ * Disable at_exit handler for Unicorn which sometimes caused the
+ agent to stop reporting immediately.
+
+v2.9.8.
+ * add instrumentation for Net::HTTP calls, to show up as "External"
+ * added support for validating agents in the cloud.
+ * recognize Unicorn dispatcher
+ * add NewRelic module definitions to ActiveRecord instrumentation
+
+v2.9.5.
+ * Snow Leopard memory fix
+
+v2.9.4.
+ * clamp size of data sent to server
+ * reset statistics for passenger when forking to avoid erroneous data
+ * fix problem deserializing errors from the server
+ * fix incompatibility with postgres introduced in 2.9.
+
+v2.9.3.
+ * fix startup failure in Windows due to memory sampler
+ * add JRuby environment information
+
+v2.9.2.
+ * change default apdex_t to 0.5 seconds
+ * fix bug in deployments introduced by multi_homed setting
+ * support overriding the log in the agent api
+ * fix JRuby problem using objectspace
+ * display custom parameters when looking at transactions in dev mode
+ * display count of sql statements on the list of transactions in dev mode
+ * fixes for merb--thanks to Carl Lerche
+
+v2.9.1.
+ * add newrelic_ignore_apdex method to controller classes to allow
+ you to omit some actions from apdex statistics
+ * Add hook for Passenger shutdown events to get more timely shutdown
+ notices; this will help in more accurate memory readings in
+ Passenger
+ * add newrelic_notice_error to Object class
+ * optional ability to verify SSL certificates, note that this has some
+ performance and reliability implications
+ * support multi-homed host with multiple apps running on duplicate
+ ports
+
+v2.9.0.
+ Noteworthy Enhancements
+ * give visibility to templates and partials in Rails 2.1 and later, in
+ dev mode and production
+ * change active record metrics to capture statistics in adapter log()
+ call, resulting in lower overhead and improved visibility into
+ different DB operations; only AR operations that are not hitting the
+ query cache will be measured to avoid overhead
+ * added mongrel_rpm to the gem, a standalone daemon listening for custom
+ metric values sent from local processes (experimental); do mongrel_rpm
+ --help
+ * add API for system monitoring daemons (refer to KB articles); changed
+ API for manual starting of the agent; refer to
+ NewRelic::Agent.manual_start for details
+ * do certificate verification on ssl connections to
+ collector.newrelic.com
+ * support instances appearing in more than one application by allowing a
+ semicolon separated list of names for the newrelic.yml app_name
+ setting.
+ * combined agent logfiles into a single logfile
+ * use rpm server time for transaction traces rather than agent time
+
+ Developer Mode (only) Enhancements
+ * show partial rendering in traces
+ * improved formatting of metric names in traces
+ * added number of queries to transactions in the transaction list
+ * added some sorting options for the transaction list
+ * added a page showing the list of active threads
+
+ Compatibility Enhancements
+ * ruby 1.9.1 compatibility
+ * support concurrency when determining busy times, for 2.2 compatibility
+ * in jruby, use Java used heap for memory sampling if the system memory
+ is not accessible from an unsupported platform
+ * jruby will no longer start the agent now when running the console or
+ rake tasks
+ * API support for RPM as a footnote add-in
+ * webrick support restored
+
+ Noteworthy bugfixes
+ * sample memory on linux by reading /proc/#{$$}/status file
+ * fixed ambiguous 'View' metrics showing up in controller breakdown
+ * removed Numeric extensions, including round_to, and to_ms
+ * using a different timeout mechanism when we post data to RPM
+ * remove usage of Rails::Info which had a side effect of enabling
+ ActiveRecord even when it wasn't an active framework
+ * moved CPU sampler off background thread and onto the harvest thread
+ * tests now run cleanly in any rails app using test:newrelic or
+ test:plugins
+
+ Agent improvements to support future RPM enhancements
+ * add instrumentation to capture metrics on response codes; not yet
+ working in rails 2.3.*
+ * added http referer to traced errors
+ * capture gem requirements from rails
+ * capture cpu utilization adjusted for processor count
+ * transaction sampling
+
+v2.8.10.
+ * fix thin support with rails 2.3.2 when using script/server
+ * fix incompatibility with rails 2.3.2 and script/server options
+ processing
+ * minor tweak to environment gathering for gem mode
+
+v2.8.9.
+ * fix problem finding the newrelic controller in dev mode
+ * fix incompatibility with older versions of optparse
+ * fix potential jvm problem with jruby
+ * remove test:all task definition to avoid conflicts
+ * change error message about window sampler in windows not supported to a
+ warning message
+
+v2.8.8.
+ * fix error with jruby on windows
+ * fix problem where webrick was being incorrectly detected causing some
+ problems with mongrel application assignments--had to disable webrick
+ for now
+
+v2.8.7.
+ * fix for ssl connection hanging problems
+ * fix problem recognizing mongrel in rails 2.3.2
+ * fastcgi support in rails 2.3.2
+ * put back webrick support
+
+v2.8.6.
+ * fix for capture_params when using file uploads in controller actions
+ * use pure ruby NS lookup for collector host to eliminate possibly
+ blocking applications
+
+v2.8.5.
+ * fix reference to CommandError which was breaking some cap scripts
+ * fix incompatibility with Rails 2.0 in the server API
+ * fix problem with litespeed with Lite accounts
+ * fix problem when ActiveRecord is disabled
+ * moved merb instrumentation to Merb::Controller instead of
+ AbstractController to address incompatibility with MailController
+ * fix problem in devmode displaying sql with embedded urls
+
+v2.8.4.
+ * fix bug in capistrano recipe causing cap commands to fail with error
+ about not finding Version class
+
+v2.8.3.
+ * refactor unit tests so they will run in a generic rails environment
+ * require classes in advance to avoid autoloading. this is to address
+ incompatibilities with desert as well as more flexibility in gem
+ initialization
+ * fixed newrelic_helper.rb 1.9 incompatibility
+
+v2.8.2.
+ * fix Ruby 1.9 syntax compatibility errors
+ * update the class loading sanity check, will notify server of errors
+ * fix agent output on script and rake task execution
+
+v2.8.1.
+ * Convert the deployment information upload script to an executable and
+ put in the bin directory. When installed as a gem this command is
+ symlinked to /usr/bin. Usage: newrelic_cmd deployments --help
+ * Fix issue invoking api when host is not set in newrelic.yml
+ * Fix deployments api so it will work from a gem
+ * Fix thin incompatibility in developer mode
+
+v2.8.0.
+ * add beta of api in new_relic_api.rb
+ * instrumented dynamic finders in ActiveRecord
+ * preliminary support for capturing deployment information via capistrano
+ * change memory sampler for solaris to use /usr/bin/ps
+ * allow ERB in newrelic.yml file
+ * merged support for merb into this version
+ * fix incompatibility in the developer mode with the safe_erb plugin
+ * fix module namespace issue causing an error accessing
+ NewRelic::Instrumentation modules
+ * fix issue where the agent sometimes failed to start up if there was a
+ transient network problem
+ * fix IgnoreSilentlyException message
+
+v2.7.4.
+ * fix error when trying to serialize some kinds of Enumerable objects
+ * added extra debug logging
+ * added app_name to app mapping
+
+v2.7.3.
+ * fix compatibility issue with 1.8.5 causing error with Dir.glob
+
+v2.7.2.
+ * fix problem with passenger edge not being a detected environment
+
+v2.7.1.
+ * fix problem with skipped dispatcher instrumentation
+
+v2.7.0.
+ * Repackage to support both plugin and Gem installation
+ * Support passenger/litespeed/jruby application naming
+ * Update method for calculating dispatcher queue time
+ * Show stack traces in RPM Transaction Traces
+ * Capture error source for TemplateErrors
+ * Clean up error stack traces.
+ * Support query plans from postgres
+ * Performance tuning
+ * bugfixes
+
+v2.5.3.
+ * fix error in transaction tracing causing traces not to show up
+
+v2.5.2.
+ * fixes for postgres explain plan support
+
+v2.5.1.
+ * bugfixes
+
+v2.5.0.
+ * add agent support for rpm 1.1 features
+ * Fix regression error with thin support
+
+v2.4.3.
+ * added 'newrelic_ignore' controller class method with :except and :only options for finer grained control
+ over the blocking of instrumentation in controllers.
+ * bugfixes
+
+v2.4.2.
+ * error reporting in early access
+
+v2.4.1.
+ * bugfix: initializing developer mode
+
+v2.4.0.
+ * Beta support for LiteSpeed and Passenger
+
+v2.3.7.
+ * bugfixes
+
+v2.3.6.
+ * bugfixes
+
+v2.3.5.
+ * bugfixes: pie chart data, rails 1.1 compability
+
+v2.3.4.
+ * bugfix
+
+v2.3.3.
+ * bugfix for non-mysql databases
+
+v2.3.2.
+ * bugfixes
+ * Add enhancement for Transaction Traces early access feature
+
+v2.3.1.
+ * bugfixes
+
+v2.3.0.
+ + Add support for Transaction Traces early access feature
+
+v2.2.2.
+ * bugfixes
+
+v2.2.1.
+ + Add rails 2.1 support for Developer Mode
+ + Changes to memory sampler: Add support for JRuby and fix Solaris support.
+ * Stop catching exceptions and start catching StandardError; other exception cleanup
+ * Add protective exception catching to the stats engine
+ * Improved support for thin domain sockets
+ * Support JRuby environments
+
+v2.1.6.
+ * bugfixes
+
+v2.1.5.
+ * bugfixes
+
+v2.1.4.
+ * bugfixes
+
+v2.1.3.
+ * bugfixes
+
+v2.1.2.
+ * bugfixes
+
+v2.1.1.
+ * bugfixes
+
+v2.1.0.
+ * release for private beta
+
+
View
37 vendor/plugins/newrelic_rpm/LICENSE
@@ -0,0 +1,37 @@
+Copyright (c) 2008-2009 New Relic, Inc. All rights reserved.
+
+Certain inventions disclosed in this file may be claimed within
+patents owned or patent applications filed by New Relic, Inc. or third
+parties.
+
+Subject to the terms of this notice, New Relic grants you a
+nonexclusive, nontransferable license, without the right to
+sublicense, to (a) install and execute one copy of these files on any
+number of workstations owned or controlled by you and (b) distribute
+verbatim copies of these files to third parties. As a condition to the
+foregoing grant, you must provide this notice along with each copy you
+distribute and you must not remove, alter, or obscure this notice. All
+other use, reproduction, modification, distribution, or other
+exploitation of these files is strictly prohibited, except as may be set
+forth in a separate written license agreement between you and New
+Relic. The terms of any such license agreement will control over this
+notice. The license stated above will be automatically terminated and
+revoked if you exceed its scope or violate any of the terms of this
+notice.
+
+This License does not grant permission to use the trade names,
+trademarks, service marks, or product names of New Relic, except as
+required for reasonable and customary use in describing the origin of
+this file and reproducing the content of this notice. You may not
+mark or brand this file with any trade name, trademarks, service
+marks, or product names other than the original brand (if any)
+provided by New Relic.
+
+Unless otherwise expressly agreed by New Relic in a separate written
+license agreement, these files are provided AS IS, WITHOUT WARRANTY OF
+ANY KIND, including without any implied warranties of MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, TITLE, or NON-INFRINGEMENT. As a
+condition to your use of these files, you are solely responsible for
+such use. New Relic will have no liability to you for direct,
+indirect, consequential, incidental, special, or punitive damages or
+for lost profits or data.
View
138 vendor/plugins/newrelic_rpm/README.md
@@ -0,0 +1,138 @@
+New Relic RPM
+=============
+
+New Relic RPM is a Ruby performance management system, developed by
+[New Relic, Inc](http://www.newrelic.com). RPM provides you with deep
+information about the performance of your Ruby on Rails or Merb
+application as it runs in production. The New Relic Agent is
+dual-purposed as a either a Rails plugin or a Gem, hosted on
+[github](http://github.com/newrelic/rpm/tree/master) and Rubyforge.
+
+The New Relic Agent runs in one of two modes:
+
+**Developer Mode** : Adds a web interface mapped to /newrelic to your
+ application for showing detailed performance metrics on a page by
+ page basis.
+
+**Production Mode** : Low overhead instrumentation that captures
+ detailed information on your application running in production and
+ transmits them to rpm.newrelic.com where you can monitor them in
+ real time.
+
+### Supported Environments
+
+* Ruby 1.8.6, 1.8.7 or 1.9.1
+* JRuby
+* Rails 1.2.6 or above
+* Merb 1.0 or above
+
+Developer Mode
+--------------
+
+Developer mode is on by default when you run your application in the
+development environment (but not when it runs in other environments.)
+When running in developer mode, RPM will track the performance of
+every http request serviced by your application, and store in memory
+this information for the last 100 http transactions.
+
+When running in Developer Mode, the RPM will also add a few pages to
+your application that allow you to analyze this performance
+information. (Don't worry--those pages are not added to your
+application's routes when you run in production mode.)
+
+To view this performance information, including detailed SQL statement
+analysis, open `/newrelic` in your web application. For instance if
+you are running mongrel or thin on port 3000, enter the following into
+your browser:
+
+ http://localhost:3000/newrelic
+
+Production Mode
+---------------
+
+When your application runs in the production environment, the New
+Relic agent runs in production mode. It connects to the New Relic RPM
+service and sends deep performance data to the RPM service for your
+analysis. To view this data, login to
+[http://rpm.newrelic.com](http://rpm.newrelic.com).
+
+NOTE: You must have a valid account and license key to view this data
+online. Refer to instructions in *Getting Started*, below.
+
+Getting Started
+===============
+
+RPM requires an agent be installed in the application as either a
+Rails plug-in or a gem. Both are available on RubyForge--instructions
+below.
+
+To use Developer Mode, simply install the gem or plugin into your
+application and follow the instructions below.
+
+To monitor your applications in production, create an account at
+[www.newrelic.com](http://newrelic.com/get-RPM.html). There you can
+sign up for a free Lite account or one of our paid subscriptions.
+
+Once you receive the welcome e-mail with a license key and
+`newrelic.yml` file, copy the `newrelic.yml` file into your app config
+directory.
+
+### Rails Plug-In Installation
+
+ script/plugin install http://newrelic.rubyforge.org/svn/newrelic_rpm
+
+### Gem Installation
+
+ sudo gem install newrelic_rpm
+
+For Rails, edit `environment.rb` and add to the initalizer block:
+
+ config.gem "newrelic_rpm"
+
+The Developer Mode is unavailable when using the gem on Rails versions
+prior to 2.0.
+
+### Merb Support
+
+To monitor a merb app install the newrelic_rpm gem and add
+
+ dependency 'newrelic_rpm'
+
+to your init.rb file.
+
+Current features implemented:
+
+* Standard monitoring, overview pages
+* Error capturing
+* Full Active Record instrumentation, including SQL explains
+* Very limited Data Mapper instrumentation
+* Transaction Traces are implemented but will not be very useful
+ with Data Mapper until more work is done with the Data Mapper
+ instrumentation
+
+Still under development:
+
+* Developer Mode
+* Data Mapper bindings
+
+### Github
+
+The agent is also available on Github under newrelic/rpm. Fork away!
+
+### Support
+
+Reach out to us--and to fellow RPM users--at
+[support.newrelic.com](http://support.newrelic.com/discussions/support).
+There you'll find documentation, FAQs, and forums where you can submit
+suggestions and discuss RPM with New Relic staff and other users.
+
+Find a bug? E-mail support@newrelic.com, or post it to
+[support.newrelic.com](http://support.newrelic.com/discussions/support).
+
+Refer to [our website](http://www.newrelic.com/support) for other
+support channels.
+
+Thank you, and may your application scale to infinity plus one.
+
+Lew Cirne, Founder and CEO<br/>
+New Relic, Inc.
View
87 vendor/plugins/newrelic_rpm/Rakefile
@@ -0,0 +1,87 @@
+require 'rubygems'
+require 'rake'
+require "#{File.dirname(__FILE__)}/lib/new_relic/version.rb"
+require 'rake/testtask'
+
+GEM_NAME = "newrelic_rpm"
+GEM_VERSION = NewRelic::VERSION::STRING
+AUTHOR = "Bill Kayser"
+EMAIL = "support@newrelic.com"
+HOMEPAGE = "http://www.github.com/newrelic/rpm"
+SUMMARY = "New Relic Ruby Performance Monitoring Agent"
+URGENT_README = "README-#{GEM_VERSION}"
+# See http://www.rubygems.org/read/chapter/20
+begin
+ require 'jeweler'
+ Jeweler::Tasks.new do |gem|
+ gem.name = GEM_NAME
+ gem.summary = SUMMARY
+ gem.description = <<-EOF
+New Relic RPM is a Ruby performance management system, developed by
+New Relic, Inc (http://www.newrelic.com). RPM provides you with deep
+information about the performance of your Ruby on Rails or Merb
+application as it runs in production. The New Relic Agent is
+dual-purposed as a either a Rails plugin or a Gem, hosted on
+http://github.com/newrelic/rpm/tree/master.
+ EOF
+ gem.email = EMAIL
+ gem.homepage = HOMEPAGE
+ gem.author = AUTHOR
+ gem.version = GEM_VERSION
+ gem.files = FileList['**/*'].to_a - ['init.rb']
+ gem.test_files = [] # You can't really run the tests unless the gem is installed.
+ gem.rdoc_options << "--line-numbers" << "--inline-source" << "--title" << "New Relic RPM"
+ gem.files.reject! { |fn| fn =~ /Rakefile|pkg\/|rdoc\// }
+ gem.extra_rdoc_files = %w[CHANGELOG LICENSE]
+ if File.exists?(URGENT_README)
+ gem.post_install_message = File.read(URGENT_README)
+ else
+ gem.post_install_message = <<-EOF
+
+Please see http://support.newrelic.com/faqs/docs/ruby-agent-release-notes
+for a complete description of the features and enhancements available
+in version #{GEM_VERSION.split('.')[0..1].join('.')} of the Ruby Agent.
+
+For details on this specific release, refer to the CHANGELOG file.
+
+ EOF
+ end
+ end
+ Jeweler::GemcutterTasks.new
+rescue LoadError
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
+end
+
+load "#{File.dirname(__FILE__)}/lib/tasks/all.rb"
+
+task :manifest do
+ puts "Manifest task is no longer used since switching to jeweler."
+end
+
+task :test => Rake::Task['test:newrelic']
+
+begin
+ require 'rcov/rcovtask'
+ Rcov::RcovTask.new do |test|
+ test.libs << 'test'
+ test.pattern = 'test/**/test_*.rb'
+ test.verbose = true
+ end
+rescue LoadError
+ task :rcov do
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
+ end
+end
+
+task :test => :check_dependencies
+
+task :default => :test
+
+require 'rake/rdoctask'
+Rake::RDocTask.new do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = SUMMARY
+ rdoc.rdoc_files.include('LICENSE')
+ rdoc.rdoc_files.include('CHANGELOG')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
View
33 vendor/plugins/newrelic_rpm/bin/mongrel_rpm
@@ -0,0 +1,33 @@
+#!/usr/bin/env ruby
+require 'rubygems'
+require 'rack'
+require 'rack/handler/mongrel'
+require 'optparse'
+
+port = 3000
+options = { }
+appname = nil
+OptionParser.new do |opts|
+ opts.banner = "Usage: #{File.basename($0)} [options] [app_name]"
+ opts.on("-p", "--port=port", Integer, "default: #{port}") { | port | }
+ opts.on("--[no-]logging", "turn off request logging" ) { | l | options[:logging] = l }
+ opts.on("--license=rpm_license_key", "override license key" ) { | l | options[:license_key] = l }
+ opts.on("--install", "install a newrelic.yml template" ) { | l | options[:install] = true }
+ opts.separator ""
+ opts.separator "app_name is the name of the application where the metrics will be stored"
+ opts.separator ""
+ # The rackup file references this var
+ appname = opts.parse!(ARGV.clone).first
+end
+
+options[:app_name] = appname if appname
+
+ru_file = File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "new_relic", "rack", "mongrel_rpm.ru"))
+rackup_code = File.read ru_file
+builder = Rack::Builder.new { eval rackup_code, binding, ru_file }
+
+options = { :Host => '127.0.0.1', :Port => port }
+Rack::Handler::Mongrel.run(builder.to_app, options) do | server |
+ NewRelic::Control.instance.log! "Started Mongrel listening for '#{NewRelic::Control.instance.app_names.join(" and ")}' data at #{server.host}:#{server.port}"
+end
+
View
4 vendor/plugins/newrelic_rpm/bin/newrelic_cmd
@@ -0,0 +1,4 @@
+#!/usr/bin/env ruby
+# executes one of the commands in the new_relic/commands directory
+# pass the name of the command as an argument
+require File.dirname(__FILE__) + '/../lib/new_relic/commands/new_relic_commands'
View
34 vendor/plugins/newrelic_rpm/cert/cacert.pem
@@ -0,0 +1,34 @@
+-----BEGIN CERTIFICATE-----
+MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
+b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
+YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
+bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIy
+MjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
+d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEg
+UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
+LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
+A4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIi
+GQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCm
+DuJWBQ8YTfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwG
+lN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8sogTLDAHkY7FkX
+icnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPwnXS3qT6gpf+2SQMT2iLM7XGCK5nP
+Orf1LXLI
+-----END CERTIFICATE-----
+
+-----BEGIN CERTIFICATE-----
+MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
+b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
+YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
+bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw
+MTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
+d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIg
+UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
+LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
+A4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVC
+CSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7Rf
+ZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZ
+SWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbV
+UjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8
+W9ViH0Pd
+-----END CERTIFICATE-----
+
View
35 vendor/plugins/newrelic_rpm/init.rb
@@ -0,0 +1,35 @@
+# This is the initialization for the RPM Rails plugin
+require 'new_relic/control'
+
+# If you are having problems seeing data, be sure and check the
+# newrelic_agent log files.
+#
+# If you can't find any log files and you don't see anything in your
+# application log files, try uncommenting the two lines at the
+# bottom of this file to verify the plugin is being loaded,
+# then send the output to support@newrelic.com if you are unable to
+# resolve the issue.
+
+# Initializer for the NewRelic Agent
+
+begin
+ # JRuby's glassfish plugin is trying to run the Initializer twice,
+ # which isn't a good thing so we ignore subsequent invocations here.
+ if ! defined?(::NEWRELIC_STARTED)
+ ::NEWRELIC_STARTED = "#{caller.join("\n")}"
+
+ NewRelic::Control.instance.init_plugin(defined?(config) ? {:config => config} : {})
+ else
+ NewRelic::Control.instance.log.debug "Attempt to initialize the plugin twice!"
+ NewRelic::Control.instance.log.debug "Original call: \n#{::NEWRELIC_STARTED}"
+ NewRelic::Control.instance.log.debug "Here we are now: \n#{caller.join("\n")}"
+ end
+rescue => e
+ NewRelic::Control.instance.log! "Error initializing New Relic plugin (#{e})", :error
+ NewRelic::Control.instance.log! e.backtrace.join("\n"), :error
+ NewRelic::Control.instance.log! "Agent is disabled."
+end
+#ClassLoadingWatcher.flag_const_missing = nil
+
+# ::RAILS_DEFAULT_LOGGER.warn "RPM detected environment: #{NewRelic::Control.instance.local_env.to_s}, RAILS_ENV: #{RAILS_ENV}"
+# ::RAILS_DEFAULT_LOGGER.warn "Enabled? #{NewRelic::Control.instance.agent_enabled?}"
View
46 vendor/plugins/newrelic_rpm/install.rb
@@ -0,0 +1,46 @@
+require 'fileutils'
+require 'erb'
+
+def install_newrelic_config_file(license_key="PASTE_YOUR_LICENSE_KEY_HERE")
+ # Install a newrelic.yml file into the local config directory.
+ if File.directory? "config"
+ dest_dir = "config"
+ else
+ dest_dir = File.join(ENV["HOME"],".newrelic") rescue nil
+ FileUtils.mkdir(dest_dir) if dest_dir
+ end
+
+ src_config_file = File.join(File.dirname(__FILE__),"newrelic.yml")
+ dest_config_file = File.join(dest_dir, "newrelic.yml") if dest_dir
+
+ if !dest_dir
+ STDERR.puts "Could not find a config or ~/.newrelic directory to locate the default newrelic.yml file"
+ elsif File::exists? dest_config_file
+ STDERR.puts "\nA config file already exists at #{dest_config_file}.\n"
+ else
+ generated_for_user = ""
+ yaml = ERB.new(File.read(src_config_file)).result(binding)
+ File.open( dest_config_file, 'w' ) do |out|
+ out.puts yaml
+ end
+
+ puts <<-EOF
+
+Installed a default configuration file in #{dest_dir}.
+
+To monitor your application in production mode, sign up for an account
+at www.newrelic.com, and replace the newrelic.yml file with the one
+you receive upon registration.
+
+Please review the README.md file for more information.
+
+E-mail support@newrelic.com with any problems or questions.
+
+ EOF
+
+ end
+end
+
+if __FILE__ == $0 || $0 =~ /script\/plugin/
+ install_newrelic_config_file
+end
View
364 vendor/plugins/newrelic_rpm/lib/new_relic/agent.rb
@@ -0,0 +1,364 @@
+# = New Relic Agent
+#
+# New Relic RPM is a performance monitoring application for Ruby
+# applications running in production. For more information on RPM
+# please visit http://www.newrelic.com.
+#
+# The New Relic Agent can be installed in Rails applications to gather
+# runtime performance metrics, traces, and errors for display in a
+# Developer Mode UI (mapped to /newrelic in your application server)
+# or for monitoring and analysis at http://rpm.newrelic.com with just
+# about any Ruby application.
+#
+# For detailed information on configuring or customizing the RPM Agent
+# please visit our {support and documentation site}[http://support.newrelic.com].
+#
+# == Starting the Agent as a Gem
+#
+# For Rails, add:
+# config.gem 'newrelic_rpm'
+# to your initialization sequence.
+#
+# For merb, do
+# dependency 'newrelic_rpm'
+# in the Merb config/init.rb
+#
+# For Sinatra, just require the +newrelic_rpm+ gem and it will
+# automatically detect Sinatra and instrument all the handlers.
+#
+# For other frameworks, or to manage the agent manually,
+# invoke NewRelic::Agent#manual_start directly.
+#
+# == Configuring the Agent
+#
+# All agent configuration is done in the <tt>newrelic.yml</tt> file.
+# This file is by default read from the +config+ directory of the
+# application root and is subsequently searched for in the application
+# root directory, and then in a <tt>~/.newrelic</tt> directory
+#
+# == Using with Rack/Metal
+#
+# To instrument middlewares, refer to the docs in
+# NewRelic::Agent::Instrumentation::Rack.
+#
+# == Agent API
+#
+# For details on the Agent API, refer to NewRelic::Agent.
+#
+#
+# :main: lib/new_relic/agent.rb
+module NewRelic
+ # == Agent APIs
+ # This module contains the public API methods for the Agent.
+ #
+ # For adding custom instrumentation to method invocations, refer to
+ # the docs in the class NewRelic::Agent::MethodTracer.
+ #
+ # For information on how to customize the controller
+ # instrumentation, or to instrument something other than Rails so
+ # that high level dispatcher actions or background tasks show up as
+ # first class operations in RPM, refer to
+ # NewRelic::Agent::Instrumentation::ControllerInstrumentation and
+ # NewRelic::Agent::Instrumentation::ControllerInstrumentation::ClassMethods.
+ #
+ # Methods in this module as well as documented methods in
+ # NewRelic::Agent::MethodTracer and
+ # NewRelic::Agent::Instrumentation::ControllerInstrumentation are
+ # available to applications. When the agent is not enabled the
+ # method implementations are stubbed into no-ops to reduce overhead.
+ #
+ # Methods and classes in other parts of the agent are not guaranteed
+ # to be available between releases.
+ #
+ # Refer to the online docs at support.newrelic.com to see how to
+ # access the data collected by custom instrumentation, or e-mail
+ # support at New Relic for help.
+ module Agent
+ extend self
+
+ require 'new_relic/version'
+ require 'new_relic/local_environment'
+ require 'new_relic/stats'
+ require 'new_relic/delayed_job_injection'
+ require 'new_relic/metrics'
+ require 'new_relic/metric_spec'
+ require 'new_relic/metric_data'
+ require 'new_relic/metric_parser'
+ require 'new_relic/collection_helper'
+ require 'new_relic/transaction_analysis'
+ require 'new_relic/transaction_sample'
+ require 'new_relic/noticed_error'
+ require 'new_relic/histogram'
+
+ require 'new_relic/agent/chained_call'
+ require 'new_relic/agent/agent'
+ require 'new_relic/agent/shim_agent'
+ require 'new_relic/agent/method_tracer'
+ require 'new_relic/agent/worker_loop'
+ require 'new_relic/agent/stats_engine'
+ require 'new_relic/agent/transaction_sampler'
+ require 'new_relic/agent/error_collector'
+ require 'new_relic/agent/busy_calculator'
+ require 'new_relic/agent/sampler'
+
+ require 'new_relic/agent/instrumentation/controller_instrumentation'
+
+ require 'new_relic/agent/samplers/cpu_sampler'
+ require 'new_relic/agent/samplers/memory_sampler'
+ require 'new_relic/agent/samplers/object_sampler'
+ require 'new_relic/agent/samplers/delayed_job_lock_sampler'
+ require 'set'
+ require 'thread'
+ require 'resolv'
+ require 'timeout'
+
+ # An exception that is thrown by the server if the agent license is invalid.
+ class LicenseException < StandardError; end
+
+ # An exception that forces an agent to stop reporting until its mongrel is restarted.
+ class ForceDisconnectException < StandardError; end
+
+ # An exception that forces an agent to restart.
+ class ForceRestartException < StandardError; end
+
+ # Used to blow out of a periodic task without logging a an error, such as for routine
+ # failures.
+ class ServerConnectionException < StandardError; end
+
+ # Used for when a transaction trace or error report has too much
+ # data, so we reset the queue to clear the extra-large item
+ class PostTooBigException < ServerConnectionException; end
+
+ # Reserved for future use. Meant to represent a problem on the server side.
+ class ServerError < StandardError; end
+
+ class BackgroundLoadingError < StandardError; end
+
+ @agent = nil
+
+ # The singleton Agent instance. Used internally.
+ def agent #:nodoc:
+ raise "Plugin not initialized!" if @agent.nil?
+ @agent
+ end
+
+ def agent= new_instance #:nodoc:
+ @agent = new_instance
+ end
+
+ alias instance agent #:nodoc:
+
+ # Get or create a statistics gatherer that will aggregate numerical data
+ # under a metric name.
+ #
+ # +metric_name+ should follow a slash separated path convention. Application
+ # specific metrics should begin with "Custom/".
+ #
+ # Return a NewRelic::Stats that accepts data
+ # via calls to add_data_point(value).
+ def get_stats(metric_name, use_scope=false)
+ @agent.stats_engine.get_stats(metric_name, use_scope)
+ end
+
+ alias get_stats_no_scope get_stats
+
+ # Get the logger for the agent. Available after the agent has initialized.
+ # This sends output to the agent log file.
+ def logger
+ NewRelic::Control.instance.log
+ end
+
+ # Call this to manually start the Agent in situations where the Agent does
+ # not auto-start.
+ #
+ # When the app environment loads, so does the Agent. However, the
+ # Agent will only connect to RPM if a web front-end is found. If
+ # you want to selectively monitor ruby processes that don't use
+ # web plugins, then call this method in your code and the Agent
+ # will fire up and start reporting to RPM.
+ #
+ # Options are passed in as overrides for values in the
+ # newrelic.yml, such as app_name. In addition, the option +log+
+ # will take a logger that will be used instead of the standard
+ # file logger. The setting for the newrelic.yml section to use
+ # (ie, RAILS_ENV) can be overridden with an :env argument.
+ #
+ def manual_start(options={})
+ raise unless Hash === options
+ NewRelic::Control.instance.init_plugin({ :agent_enabled => true, :sync_startup => true }.merge(options))
+ end
+
+ # Register this method as a callback for processes that fork
+ # jobs.
+ #
+ # Pass <tt>:force_reconnect => true</tt> to force the agent to
+ # reconnect to the server and start a worker loop for sending
+ # data.
+ #
+ # If the master/parent connects to the agent prior to forking the
+ # agent in the forked process will use that agent_run. Otherwise
+ # the forked process will establish a new connection with the
+ # server.
+ #
+ # Use this especially when you fork the process to run background
+ # jobs or other work. If you are doing this with a web dispatcher
+ # that forks worker processes then you will need to force the
+ # agent to reconnect, which it won't do by default. Passenger and
+ # Unicorn are already handled, nothing special needed for them.
+ def after_fork(options={})
+ agent.after_fork(options)
+ end
+
+ # Clear out any unsent metric data.
+ def reset_stats
+ agent.reset_stats
+ end
+
+ # Shutdown the agent. Call this before exiting. Sends any queued data
+ # and kills the background thread.
+ def shutdown
+ agent.shutdown
+ end
+
+ # Add instrumentation files to the agent. The argument should be
+ # a glob matching ruby scripts which will be executed at the time
+ # instrumentation is loaded. Since instrumentation is not loaded
+ # when the agent is not running it's better to use this method to
+ # register instrumentation than just loading the files directly,
+ # although that probably also works.
+ def add_instrumentation file_pattern
+ NewRelic::Control.instance.add_instrumentation file_pattern
+ end
+
+ # This method sets the block sent to this method as a sql
+ # obfuscator. The block will be called with a single String SQL
+ # statement to obfuscate. The method must return the obfuscated
+ # String SQL. If chaining of obfuscators is required, use type =
+ # :before or :after
+ #
+ # type = :before, :replace, :after
+ #
+ # Example:
+ #
+ # NewRelic::Agent.set_sql_obfuscator(:replace) do |sql|
+ # my_obfuscator(sql)
+ # end
+ #
+ def set_sql_obfuscator(type = :replace, &block)
+ agent.set_sql_obfuscator type, &block
+ end
+
+
+ # This method sets the state of sql recording in the transaction
+ # sampler feature. Within the given block, no sql will be recorded
+ #
+ # usage:
+ #
+ # NewRelic::Agent.disable_sql_recording do
+ # ...
+ # end
+ #
+ def disable_sql_recording
+ state = agent.set_record_sql(false)
+ begin
+ yield
+ ensure
+ agent.set_record_sql(state)
+ end
+ end
+
+ # This method disables the recording of transaction traces in the given
+ # block. See also #disable_all_tracing
+ def disable_transaction_tracing
+ state = agent.set_record_tt(false)
+ begin
+ yield
+ ensure
+ agent.set_record_tt(state)
+ end
+ end
+
+ # Cancel the collection of the current transaction in progress, if
+ # any. Only affects the transaction started on this thread once
+ # it has started and before it has completed.
+ def abort_transaction!
+ # The class may not be loaded if the agent is disabled
+ if defined? NewRelic::Agent::Instrumentation::MetricFrame
+ NewRelic::Agent::Instrumentation::MetricFrame.abort_transaction!
+ end
+ end
+
+ # Yield to the block without collecting any metrics or traces in
+ # any of the subsequent calls. If executed recursively, will keep
+ # track of the first entry point and turn on tracing again after
+ # leaving that block. This uses the thread local
+ # +newrelic_untrace+
+ def disable_all_tracing
+ agent.push_trace_execution_flag(false)
+ yield
+ ensure
+ agent.pop_trace_execution_flag
+ end
+
+ # Check to see if we are capturing metrics currently on this thread.
+ def is_execution_traced?
+ Thread.current[:newrelic_untraced].nil? || Thread.current[:newrelic_untraced].last != false
+ end
+
+ # Set a filter to be applied to errors that RPM will track. The
+ # block should evalute to the exception to track (which could be
+ # different from the original exception) or nil to ignore this
+ # exception.
+ #
+ # The block is yielded to with the exception to filter.
+ #
+ # Return the new block or the existing filter Proc if no block is passed.
+ #
+ def ignore_error_filter(&block)
+ agent.error_collector.ignore_error_filter(&block)
+ end
+
+ # Record the given error in RPM. It will be passed through the
+ # #ignore_error_filter if there is one.
+ #
+ # * <tt>exception</tt> is the exception which will be recorded
+ # Options:
+ # * <tt>:uri</tt> => The request path, minus any request params or query string.
+ # * <tt>:referer</tt> => The URI of the referer
+ # * <tt>:metric</tt> => The metric name associated with the transaction
+ # * <tt>:request_params</tt> => Request parameters, already filtered if necessary
+ # * <tt>:custom_params</tt> => Custom parameters
+ #
+ # Anything left over is treated as custom params
+ #
+ def notice_error(exception, options={})
+ NewRelic::Agent::Instrumentation::MetricFrame.notice_error(exception, options)
+ end
+
+ # Add parameters to the current transaction trace on the call stack.
+ #
+ def add_custom_parameters(params)
+ NewRelic::Agent::Instrumentation::MetricFrame.add_custom_parameters(params)
+ end
+
+ # The #add_request_parameters method is aliased to #add_custom_parameters
+ # and is now deprecated.
+ alias add_request_parameters add_custom_parameters #:nodoc:
+
+ # Yield to a block that is run with a database metric name
+ # context. This means the Database instrumentation will use this
+ # for the metric name if it does not otherwise know about a model.
+ # This is re-entrant.
+ #
+ # * <tt>model</tt> is the DB model class
+ # * <tt>method</tt> is the name of the finder method or other
+ # method to identify the operation with.
+ def with_database_metric_name(model, method, &block)
+ if frame = NewRelic::Agent::Instrumentation::MetricFrame.current
+ frame.with_database_metric_name(model, method, &block)
+ else
+ yield
+ end
+ end
+ end
+end
View
649 vendor/plugins/newrelic_rpm/lib/new_relic/agent/agent.rb
@@ -0,0 +1,649 @@
+require 'socket'
+require 'net/https'
+require 'net/http'
+require 'logger'
+require 'zlib'
+require 'stringio'
+
+# The NewRelic Agent collects performance data from ruby applications
+# in realtime as the application runs, and periodically sends that
+# data to the NewRelic server.
+module NewRelic
+ module Agent
+
+ # The Agent is a singleton that is instantiated when the plugin is
+ # activated.
+ class Agent
+
+ # Specifies the version of the agent's communication protocol with
+ # the NewRelic hosted site.
+
+ PROTOCOL_VERSION = 8
+ # 14105: v8 (tag 2.10.3)
+ # (no v7)
+ # 10379: v6 (not tagged)
+ # 4078: v5 (tag 2.5.4)
+ # 2292: v4 (tag 2.3.6)
+ # 1754: v3 (tag 2.3.0)
+ # 534: v2 (shows up in 2.1.0, our first tag)
+
+
+ attr_reader :obfuscator
+ attr_reader :stats_engine
+ attr_reader :transaction_sampler
+ attr_reader :error_collector
+ attr_reader :record_sql
+ attr_reader :histogram
+ attr_reader :metric_ids
+
+ # Should only be called by NewRelic::Control
+ def self.instance
+ @instance ||= self.new
+ end
+ # This method is deprecated. Use NewRelic::Agent.manual_start
+ def manual_start(ignored=nil, also_ignored=nil)
+ raise "This method no longer supported. Instead use the class method NewRelic::Agent.manual_start"
+ end
+
+ # This method should be called in a forked process after a fork.
+ # It assumes the parent process initialized the agent, but does
+ # not assume the agent started.
+ #
+ # * It clears any metrics carried over from the parent process
+ # * Restarts the sampler thread if necessary
+ # * Initiates a new agent run and worker loop unless that was done
+ # in the parent process and +:force_reconnect+ is not true
+ #
+ def after_fork(options={})
+
+ # @connected gets false after we fail to connect or have an error
+ # connecting. @connected has nil if we haven't finished trying to connect.
+ # or we didn't attempt a connection because this is the master process
+
+ log.debug "Agent received after_fork notice in #$$: [#{control.agent_enabled?}; monitor=#{control.monitor_mode?}; connected: #{@connected.inspect}; thread=#{@worker_thread.inspect}]"
+ return if !control.agent_enabled? or
+ !control.monitor_mode? or
+ @connected == false or
+ @worker_thread && @worker_thread.alive?
+
+ log.debug "Detected that the worker thread is not running in #$$. Restarting."
+
+ # Clear out stats that are left over from parent process
+ reset_stats
+ start_worker_thread(options[:force_reconnect])
+ @stats_engine.start_sampler_thread
+ end
+
+ # True if we have initialized and completed 'start'
+ def started?
+ @started
+ end
+
+ # Attempt a graceful shutdown of the agent.
+ def shutdown
+ return if not started?
+ if @worker_loop
+ @worker_loop.stop
+
+ log.debug "Starting Agent shutdown"
+
+ # if litespeed, then ignore all future SIGUSR1 - it's
+ # litespeed trying to shut us down
+
+ if control.dispatcher == :litespeed
+ Signal.trap("SIGUSR1", "IGNORE")
+ Signal.trap("SIGTERM", "IGNORE")
+ end
+
+ begin
+ graceful_disconnect
+ rescue => e
+ log.error e
+ log.error e.backtrace.join("\n")
+ end
+ end
+ @started = nil
+ end
+
+ def start_transaction
+ @stats_engine.start_transaction
+ end
+
+ def end_transaction
+ @stats_engine.end_transaction
+ end
+
+ def set_record_sql(should_record)
+ prev = Thread::current[:record_sql]
+ Thread::current[:record_sql] = should_record
+ prev.nil? || prev
+ end
+
+ def set_record_tt(should_record)
+ prev = Thread::current[:record_tt]
+ Thread::current[:record_tt] = should_record
+ prev.nil? || prev
+ end
+ # Push flag indicating whether we should be tracing in this
+ # thread.
+ def push_trace_execution_flag(should_trace=false)
+ (Thread.current[:newrelic_untraced] ||= []) << should_trace
+ end
+
+ # Pop the current trace execution status. Restore trace execution status
+ # to what it was before we pushed the current flag.
+ def pop_trace_execution_flag
+ Thread.current[:newrelic_untraced].pop if Thread.current[:newrelic_untraced]
+ end
+
+ def set_sql_obfuscator(type, &block)
+ if type == :before
+ @obfuscator = NewRelic::ChainedCall.new(block, @obfuscator)
+ elsif type == :after
+ @obfuscator = NewRelic::ChainedCall.new(@obfuscator, block)
+ elsif type == :replace
+ @obfuscator = block
+ else
+ fail "unknown sql_obfuscator type #{type}"
+ end
+ end
+
+ def log
+ NewRelic::Agent.logger
+ end
+
+ # Start up the agent. This verifies that the agent_enabled? is
+ # true and initializes the sampler based on the current
+ # controluration settings. Then it will fire up the background
+ # thread for sending data to the server if applicable.
+ def start
+ if started?
+ control.log! "Agent Started Already!", :error
+ return
+ end
+ return if !control.agent_enabled?
+ @started = true
+ @local_host = determine_host
+
+ if control.dispatcher.nil? || control.dispatcher.to_s.empty?
+ log.info "No dispatcher detected."
+ else
+ log.info "Dispatcher: #{control.dispatcher.to_s}"
+ end
+ log.info "Application: #{control.app_names.join(", ")}" unless control.app_names.empty?
+
+ sampler_config = control.fetch('transaction_tracer', {})
+ @should_send_samples = sampler_config.fetch('enabled', true)
+ log.info "Transaction tracing not enabled." if not @should_send_samples
+
+ @record_sql = sampler_config.fetch('record_sql', :obfuscated).to_sym
+
+ # use transaction_threshold: 4.0 to force the TT collection
+ # threshold to 4 seconds
+ # use transaction_threshold: apdex_f to use your apdex t value
+ # multiplied by 4
+ # undefined transaction_threshold defaults to 2.0
+ apdex_f = 4 * NewRelic::Control.instance.apdex_t
+ @slowest_transaction_threshold = sampler_config.fetch('transaction_threshold', 2.0)
+ if @slowest_transaction_threshold =~ /apdex_f/i
+ @slowest_transaction_threshold = apdex_f
+ end
+ @slowest_transaction_threshold = @slowest_transaction_threshold.to_f
+
+ @explain_threshold = sampler_config.fetch('explain_threshold', 0.5).to_f
+ @explain_enabled = sampler_config.fetch('explain_enabled', true)
+ @random_sample = sampler_config.fetch('random_sample', false)
+ log.warn "Agent is configured to send raw SQL to RPM service" if @record_sql == :raw
+ # Initialize transaction sampler
+ @transaction_sampler.random_sampling = @random_sample
+
+ if control.monitor_mode?
+ if !control.license_key
+ control.log! "No license key found. Please edit your newrelic.yml file and insert your license key.", :error
+ elsif control.license_key.length != 40
+ control.log! "Invalid license key: #{control.license_key}", :error
+ else
+ # Do the connect in the foreground if we are in sync mode
+ NewRelic::Agent.disable_all_tracing { connect(false) } if control.sync_startup
+
+ # Start the event loop and initiate connection if necessary
+ start_worker_thread
+
+ # Our shutdown handler needs to run after other shutdown handlers
+ # that may be doing things like running the app (hello sinatra).
+ if RUBY_VERSION =~ /rubinius/i
+ list = at_exit { shutdown }
+ # move the shutdown handler to the front of the list, to execute last:
+ list.unshift(list.pop)
+ elsif !defined?(JRuby) or !defined(Sinatra::Application)
+ at_exit { at_exit { shutdown } }
+ end
+ end
+ end
+ control.log! "New Relic RPM Agent #{NewRelic::VERSION::STRING} Initialized: pid = #$$"
+ control.log! "Agent Log found in #{NewRelic::Control.instance.log_file}" if NewRelic::Control.instance.log_file
+ end
+
+ # Clear out the metric data, errors, and transaction traces. Reset the histogram data.
+ def reset_stats
+ @stats_engine.reset_stats
+ @unsent_errors = []
+ @traces = nil
+ @unsent_timeslice_data = {}
+ @last_harvest_time = Time.now
+ @launch_time = Time.now
+ @histogram = NewRelic::Histogram.new(NewRelic::Control.instance.apdex_t / 10)
+ end
+
+ private
+ def collector
+ @collector ||= control.server
+ end
+
+ # Try to launch the worker thread and connect to the server
+ def start_worker_thread(force_reconnect=false)
+ log.debug "Creating RPM worker thread."
+ @worker_thread = Thread.new do
+ begin
+ NewRelic::Agent.disable_all_tracing do
+ # We try to connect. If this returns false that means
+ # the server rejected us for a licensing reason and we should
+ # just exit the thread. If it returns nil
+ # that means it didn't try to connect because we're in the master.
+ connect if !@connected or force_reconnect
+ if @connected
+ # disable transaction sampling if disabled by the server and we're not in dev mode
+ if !control.developer_mode? && !@should_send_samples
+ @transaction_sampler.disable
+ end
+ log.info "Reporting performance data every #{@report_period} seconds."
+ log.debug "Running worker loop"
+ # note if the agent attempts to report more frequently than allowed by the server
+ # the server will start dropping data.
+ @worker_loop = WorkerLoop.new
+ @worker_loop.run(@report_period) do
+ harvest_and_send_timeslice_data
+ harvest_and_send_slowest_sample if @should_send_samples
+ harvest_and_send_errors if error_collector.enabled
+ end
+ else
+ log.debug "No connection. Worker thread finished."
+ end
+ end
+ rescue NewRelic::Agent::ForceRestartException => e
+ log.info e.message
+ # disconnect and start over.
+ # clear the stats engine
+ reset_stats
+ @metric_ids = {}
+ @connected = nil
+ # Wait a short time before trying to reconnect
+ sleep 30
+ retry
+ rescue NewRelic::Agent::ForceDisconnectException => e
+ # when a disconnect is requested, stop the current thread, which
+ # is the worker thread that gathers data and talks to the
+ # server.
+ log.error "RPM forced this agent to disconnect (#{e.message})"
+ @connected = false
+ rescue NewRelic::Agent::ServerConnectionException => e
+ control.log! "Unable to establish connection with the server. Run with log level set to debug for more information."
+ log.debug("#{e.class.name}: #{e.message}\n#{e.backtrace.first}")
+ @connected = false
+ rescue Exception => e
+ log.error "Terminating worker loop: #{e.class.name}: #{e}\n #{e.backtrace.join("\n ")}"
+ @connected = false
+ end # begin
+ end # thread new
+ @worker_thread['newrelic_label'] = 'Worker Loop'
+ end
+
+ def control
+ NewRelic::Control.instance
+ end
+
+ def initialize
+ @launch_time = Time.now
+
+ @metric_ids = {}
+ @histogram = NewRelic::Histogram.new(NewRelic::Control.instance.apdex_t / 10)
+ @stats_engine = NewRelic::Agent::StatsEngine.new
+ @transaction_sampler = NewRelic::Agent::TransactionSampler.new
+ @stats_engine.transaction_sampler = @transaction_sampler
+ @error_collector = NewRelic::Agent::ErrorCollector.new
+
+ @request_timeout = NewRelic::Control.instance.fetch('timeout', 2 * 60)
+
+ @last_harvest_time = Time.now
+ @obfuscator = method(:default_sql_obfuscator)
+ end
+
+ # Connect to the server and validate the license. If successful,
+ # @connected has true when finished. If not successful, you can
+ # keep calling this. Return false if we could not establish a
+ # connection with the server and we should not retry, such as if
+ # there's a bad license key.
+ #
+ # Set keep_retrying=false to disable retrying and return asap, such as when
+ # invoked in the foreground. Otherwise this runs until a successful
+ # connection is made, or the server rejects us.
+
+ def connect(keep_retrying = true)
+
+ # wait a few seconds for the web server to boot, necessary in development
+ connect_retry_period = keep_retrying ? 10 : 0
+ connect_attempts = 0
+ @agent_id = nil
+ begin
+ sleep connect_retry_period.to_i
+ # Running in the Passenger or Unicorn spawners?
+ if $0 =~ /ApplicationSpawner|unicorn.* master/
+ log.debug "Process is master spawner (#$0) -- don't connect to RPM service"
+ @connected = nil
+ return
+ else
+ log.debug "Connecting Process to RPM: #$0"
+ end
+ environment = control['send_environment_info'] != false ? control.local_env.snapshot : []
+ log.debug "Connecting with validation seed/token: #{control.validate_seed}/#{control.validate_token}" if control.validate_seed
+ @agent_id ||= invoke_remote :start, @local_host, {
+ :pid => $$,
+ :launch_time => @launch_time.to_f,
+ :agent_version => NewRelic::VERSION::STRING,
+ :environment => environment,
+ :settings => control.settings,
+ :validate_seed => control.validate_seed,
+ :validate_token => control.validate_token }
+
+ host = invoke_remote(:get_redirect_host)
+
+ @collector = control.server_from_host(host) if host
+
+ @report_period = invoke_remote :get_data_report_period, @agent_id
+
+ control.log! "Connected to NewRelic Service at #{@collector}"
+ log.debug "Agent ID = #{@agent_id}."
+
+ # Ask the server for permission to send transaction samples.
+ # determined by subscription license.
+ @should_send_samples &&= invoke_remote :should_collect_samples, @agent_id
+
+ if @should_send_samples
+ sampling_rate = invoke_remote :sampling_rate, @agent_id if @random_sample
+ @transaction_sampler.sampling_rate = sampling_rate
+ log.info "Transaction sample rate: #{@transaction_sampler.sampling_rate}" if sampling_rate
+ log.info "Transaction tracing threshold is #{@slowest_transaction_threshold} seconds."
+ end
+
+ # Ask for permission to collect error data
+ error_collector.enabled &&= invoke_remote(:should_collect_errors, @agent_id)
+
+ log.info "Transaction traces will be sent to the RPM service." if @should_send_samples
+ log.info "Errors will be sent to the RPM service." if error_collector.enabled
+
+ @connected_pid = $$
+ @connected = true
+
+ rescue NewRelic::Agent::LicenseException => e
+ control.log! e.message, :error
+ control.log! "Visit NewRelic.com to obtain a valid license key, or to upgrade your account."
+ @connected = false
+
+ rescue Timeout::Error, StandardError => e
+ log.info "Unable to establish connection with New Relic RPM Service at #{control.server}"
+ unless e.instance_of? NewRelic::Agent::ServerConnectionException
+ log.error e.message
+ log.debug e.backtrace.join("\n")
+ end
+ # retry logic
+ if keep_retrying
+ connect_attempts += 1
+ case connect_attempts
+ when 1..2
+ connect_retry_period, period_msg = 60, "1 minute"
+ when 3..5
+ connect_retry_period, period_msg = 60 * 2, "2 minutes"
+ else
+ connect_retry_period, period_msg = 5 * 60, "5 minutes"
+ end
+ log.info "Will re-attempt in #{period_msg}"
+ retry
+ else
+ @connected = nil
+ end
+ end
+ end
+
+ def determine_host
+ Socket.gethostname
+ end
+
+ def determine_home_directory
+ control.root
+ end
+
+ def harvest_and_send_timeslice_data
+
+ NewRelic::Agent::BusyCalculator.harvest_busy
+
+ now = Time.now
+
+ @unsent_timeslice_data ||= {}
+ @unsent_timeslice_data = @stats_engine.harvest_timeslice_data(@unsent_timeslice_data, @metric_ids)
+
+ begin
+ # In this version of the protocol, we get back an assoc array of spec to id.
+ metric_ids = invoke_remote(:metric_data, @agent_id,
+ @last_harvest_time.to_f,
+ now.to_f,
+ @unsent_timeslice_data.values)
+
+ rescue Timeout::Error
+ # assume that the data was received. chances are that it was
+ metric_ids = nil
+ end
+
+ metric_ids.each do | spec, id |
+ @metric_ids[spec] = id
+ end if metric_ids
+
+ log.debug "#{now}: sent #{@unsent_timeslice_data.length} timeslices (#{@agent_id}) in #{Time.now - now} seconds"
+
+ # if we successfully invoked this web service, then clear the unsent message cache.
+ @unsent_timeslice_data = {}
+ @last_harvest_time = now
+
+ # handle_messages
+
+ # note - exceptions are logged in invoke_remote. If an exception is encountered here,
+ # then the metric data is downsampled for another timeslices
+ end
+
+ def harvest_and_send_slowest_sample
+ @traces = @transaction_sampler.harvest(@traces, @slowest_transaction_threshold)
+
+ unless @traces.empty?
+ now = Time.now
+ log.debug "Sending (#{@traces.length}) transaction traces"
+ begin
+ # take the traces and prepare them for sending across the
+ # wire. This includes gathering SQL explanations, stripping
+ # out stack traces, and normalizing SQL. note that we
+ # explain only the sql statements whose segments' execution
+ # times exceed our threshold (to avoid unnecessary overhead
+ # of running explains on fast queries.)
+ traces = @traces.collect {|trace| trace.prepare_to_send(:explain_sql => @explain_threshold, :record_sql => @record_sql, :keep_backtraces => true, :explain_enabled => @explain_enabled)}
+ invoke_remote :transaction_sample_data, @agent_id, traces
+ rescue PostTooBigException
+ # we tried to send too much data, drop the first trace and
+ # try again
+ retry if @traces.shift
+ end
+
+ log.debug "Sent slowest sample (#{@agent_id}) in #{Time.now - now} seconds"
+ end
+
+ # if we succeed sending this sample, then we don't need to keep
+ # the slowest sample around - it has been sent already and we
+ # can collect the next one
+ @traces = nil
+
+ # note - exceptions are logged in invoke_remote. If an
+ # exception is encountered here, then the slowest sample of is
+ # determined of the entire period since the last reported
+ # sample.
+ end
+
+ def harvest_and_send_errors
+ @unsent_errors = @error_collector.harvest_errors(@unsent_errors)
+ if @unsent_errors && @unsent_errors.length > 0
+ log.debug "Sending #{@unsent_errors.length} errors"
+ begin
+ invoke_remote :error_data, @agent_id, @unsent_errors
+ rescue PostTooBigException
+ @unsent_errors.shift
+ retry
+ end
+ # if the remote invocation fails, then we never clear
+ # @unsent_errors, and therefore we can re-attempt to send on
+ # the next heartbeat. Note the error collector maxes out at
+ # 20 instances to prevent leakage
+ @unsent_errors = []
+ end
+ end
+
+ def compress_data(object)
+ dump = Marshal.dump(object)
+
+ # this checks to make sure mongrel won't choke on big uploads
+ check_post_size(dump)
+
+ # we currently optimize for CPU here since we get roughly a 10x
+ # reduction in message size with this, and CPU overhead is at a
+ # premium. For extra-large posts, we use the higher compression
+ # since otherwise it actually errors out.
+
+ dump_size = dump.size
+
+ # small payloads don't need compression
+ return [dump, 'identity'] if dump_size < 2000
+
+ # medium payloads get fast compression, to save CPU
+ # big payloads get all the compression possible, to stay under
+ # the 2,000,000 byte post threshold
+ compression = dump_size < 2000000 ? Zlib::BEST_SPEED : Zlib::BEST_COMPRESSION
+
+ [Zlib::Deflate.deflate(dump, compression), 'deflate']
+ end
+
+ def check_post_size(post_string)
+ # TODO: define this as a config option on the server side
+ return if post_string.size < control.post_size_limit
+ log.warn "Tried to send too much data: #{post_string.size} bytes"
+ raise PostTooBigException
+ end
+
+ def send_request(opts)
+ request = Net::HTTP::Post.new(opts[:uri], 'CONTENT-ENCODING' => opts[:encoding], 'ACCEPT-ENCODING' => 'gzip', 'HOST' => opts[:collector].name)
+ request.content_type = "application/octet-stream"
+ request.body = opts[:data]
+
+ log.debug "Connect to #{opts[:collector]}#{opts[:uri]}"
+
+ response = nil
+ http = control.http_connection(collector)
+ begin
+ timeout(@request_timeout) do
+ response = http.request(request)
+ end
+ rescue Timeout::Error
+ log.warn "Timed out trying to post data to RPM (timeout = #{@request_timeout} seconds)" unless @request_timeout < 30
+ raise
+ end
+ if response.is_a? Net::HTTPServiceUnavailable
+ raise NewRelic::Agent::ServerConnectionException, "Service unavailable: #{response.body || response.message}"
+ elsif response.is_a? Net::HTTPGatewayTimeOut
+ log.debug("Timed out getting response: #{response.message}")
+ raise Timeout::Error, response.message
+ elsif !(response.is_a? Net::HTTPSuccess)
+ raise NewRelic::Agent::ServerConnectionException, "Unexpected response from server: #{response.code}: #{response.message}"
+ end
+ response
+ end
+
+ def decompress_response(response)
+ if response['content-encoding'] != 'gzip'
+ log.debug "Uncompressed content returned"
+ return response.body
+ end
+ log.debug "Decompressing return value"
+ i = Zlib::GzipReader.new(StringIO.new(response.body))
+ i.read
+ end
+
+ def check_for_exception(response)
+ dump = decompress_response(response)
+ value = Marshal.load(dump)
+ raise value if value.is_a? Exception
+ value
+ end
+
+ def remote_method_uri(method)
+ uri = "/agent_listener/#{PROTOCOL_VERSION}/#{control.license_key}/#{method}"
+ uri << "?run_id=#{@agent_id}" if @agent_id
+ uri
+ end
+
+ # send a message via post
+ def invoke_remote(method, *args)
+ #determines whether to zip the data or send plain
+ post_data, encoding = compress_data(args)
+
+ response = send_request({:uri => remote_method_uri(method), :encoding => encoding, :collector => collector, :data => post_data})
+
+ # raises the right exception if the remote server tells it to die
+ return check_for_exception(response)
+ rescue NewRelic::Agent::ForceRestartException => e
+ log.info e.message
+ raise
+ rescue SystemCallError, SocketError => e
+ # These include Errno connection errors
+ raise NewRelic::Agent::ServerConnectionException, "Recoverable error connecting to the server: #{e}"
+ end
+
+ def graceful_disconnect
+ if @connected
+ begin
+ log.debug "Sending graceful shutdown message to #{control.server}"
+
+ @request_timeout = 10
+ log.debug "Flushing unsent metric data to server"
+ @worker_loop.run_task
+ if @connected_pid == $$
+ log.debug "Sending RPM service agent run shutdown message"
+ invoke_remote :shutdown, @agent_id, Time.now.to_f
+ else
+ log.debug "This agent connected from #{@connected_pid}--not sending shutdown"
+ end
+ log.debug "Graceful disconnect complete"
+ rescue Timeout::Error, StandardError
+ end
+ else
+ log.debug "Bypassing graceful disconnect - agent not connected"
+ end
+ end
+ def default_sql_obfuscator(sql)
+ sql = sql.dup
+ # This is hardly readable. Use the unit tests.
+ # remove single quoted strings:
+ sql.gsub!(/'(.*?[^\\'])??'(?!')/, '?')
+ # remove double quoted strings:
+ sql.gsub!(/"(.*?[^\\"])??"(?!")/, '?')
+ # replace all number literals
+ sql.gsub!(/\d+/, "?")
+ sql
+ end
+ end
+
+end
+end
View
91 vendor/plugins/newrelic_rpm/lib/new_relic/agent/busy_calculator.rb
@@ -0,0 +1,91 @@
+# This module supports calculation of actual time spent processing requests over the course of
+# one harvest period. It's similar to what you would get if you just added up all the
+# execution times of controller calls, however that will be inaccurate when requests
+# span the minute boundaries. This module manages accounting of requests not yet
+# completed.
+#
+# Calls are re-entrant. All start calls must be paired with finish
+# calls, or a reset call.
+module NewRelic
+ module Agent
+ module BusyCalculator
+
+ extend self
+
+ # For testability, add accessors:
+ attr_reader :harvest_start, :accumulator
+
+ def dispatcher_start(time)
+ Thread.current[:busy_entries] ||= 0
+ callers = Thread.current[:busy_entries] += 1
+ return if callers > 1
+ @lock.synchronize do
+ @entrypoint_stack.push time
+ end
+ end
+
+ def dispatcher_finish(end_time = Time.now.to_f)
+ callers = Thread.current[:busy_entries] -= 1
+ # Ignore nested calls
+ return if callers > 0
+ @lock.synchronize do
+ if @entrypoint_stack.empty?
+ NewRelic::Agent.logger.error("Stack underflow tracking dispatcher entry and exit!\n #{caller.join(" \n")}")
+ else
+ @accumulator += (end_time - @entrypoint_stack.pop)
+ end
+ end
+ end
+
+ def busy_count
+ @entrypoint_stack.size
+ end
+
+ # Reset the state of the information accumulated by all threads,
+ # but only reset the recursion counter for this thread.
+ def reset
+ @entrypoint_stack = []
+ Thread.current[:busy_entries] = 0
+ @lock ||= Mutex.new
+ @accumulator = 0
+ @harvest_start = Time.now.to_f
+ end
+
+ self.reset
+
+ # Called before uploading to to the server to collect current busy stats.
+ def harvest_busy
+ busy = 0
+ t0 = Time.now.to_f
+ @lock.synchronize do
+ busy = accumulator
+ @accumulator = 0
+
+ # Walk through the stack and capture all times up to
+ # now for entrypoints
+ @entrypoint_stack.size.times do |frame|
+ busy += (t0 - @entrypoint_stack[frame])
+ @entrypoint_stack[frame] = t0
+ end
+
+ end
+
+ busy = 0.0 if busy < 0.0 # don't go below 0%
+
+ time_window = (t0 - harvest_start)
+ time_window = 1.0 if time_window == 0.0 # protect against divide by zero
+
+ busy = busy / time_window
+
+ instance_busy_stats.record_data_point busy
+ @harvest_start = t0
+ end
+ private
+ def instance_busy_stats
+ # Late binding on the Instance/busy stats
+ NewRelic::Agent.agent.stats_engine.get_stats_no_scope 'Instance/Busy'
+ end
+
+end
+end
+end
View
13 vendor/plugins/newrelic_rpm/lib/new_relic/agent/chained_call.rb
@@ -0,0 +1,13 @@
+# This is used to allow obfuscators to be chained.
+
+class NewRelic::ChainedCall
+ def initialize(block1, block2)
+ @block1 = block1
+ @block2 = block2
+ end
+
+ def call(sql)
+ sql = @block1.call(sql)
+ @block2.call(sql)
+ end
+end
View
128 vendor/plugins/newrelic_rpm/lib/new_relic/agent/error_collector.rb
@@ -0,0 +1,128 @@
+
+module NewRelic
+ module Agent
+ class ErrorCollector
+ include NewRelic::CollectionHelper
+
+ # Defined the methods that need to be stubbed out when the
+ # agent is disabled
+ module Shim #:nodoc:
+ def notice_error(*args); end
+ end
+
+ MAX_ERROR_QUEUE_LENGTH = 20 unless defined? MAX_ERROR_QUEUE_LENGTH
+
+ attr_accessor :enabled
+
+ def initialize
+ @errors = []
+ # lookup of exception class names to ignore. Hash for fast access
+ @ignore = {}
+ @ignore_filter = nil
+
+ config = NewRelic::Control.instance.fetch('error_collector', {})
+
+ @enabled = config.fetch('enabled', true)
+ @capture_source = config.fetch('capture_source', true)
+
+ ignore_errors = config.fetch('ignore_errors', "")
+ ignore_errors = ignore_errors.split(",") if ignore_errors.is_a? String
+ ignore_errors.each { |error| error.strip! }
+ ignore(ignore_errors)
+ @lock = Mutex.new
+ end
+
+ def ignore_error_filter(&block)
+ if block
+ @ignore_filter = block
+ else
+ @ignore_filter
+ end
+ end
+
+ # errors is an array of Exception Class Names
+ #
+ def ignore(errors)
+ errors.each { |error| @ignore[error] = true; log.debug("Ignoring errors of type '#{error}'") }
+ end
+
+ # Notice the error with the given available options:
+ #
+ # * <tt>:uri</tt> => The request path, minus any request params or query string.
+ # * <tt>:referer</tt> => The URI of the referer
+ # * <tt>:metric</tt> => The metric name associated with the transaction
+ # * <tt>:request_params</tt> => Request parameters, already filtered if necessary
+ # * <tt>:custom_params</tt> => Custom parameters
+ #
+ # If anything is left over, it's added to custom params
+ def notice_error(exception, options={})
+ return unless @enabled
+ return if @ignore[exception.class.name]
+ if @ignore_filter
+ exception = @ignore_filter.call(exception)
+ return if exception.nil?
+ end
+