techarch-newrelic_rpm 2.10.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (158) hide show
  1. data/CHANGELOG +335 -0
  2. data/LICENSE +37 -0
  3. data/Manifest +159 -0
  4. data/README.md +138 -0
  5. data/Rakefile +22 -0
  6. data/bin/mongrel_rpm +33 -0
  7. data/bin/newrelic_cmd +4 -0
  8. data/cert/cacert.pem +34 -0
  9. data/init.rb +38 -0
  10. data/install.rb +45 -0
  11. data/lib/new_relic/agent.rb +281 -0
  12. data/lib/new_relic/agent/agent.rb +636 -0
  13. data/lib/new_relic/agent/chained_call.rb +13 -0
  14. data/lib/new_relic/agent/collection_helper.rb +66 -0
  15. data/lib/new_relic/agent/error_collector.rb +121 -0
  16. data/lib/new_relic/agent/instrumentation/active_merchant.rb +18 -0
  17. data/lib/new_relic/agent/instrumentation/active_record_instrumentation.rb +88 -0
  18. data/lib/new_relic/agent/instrumentation/authlogic.rb +8 -0
  19. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +437 -0
  20. data/lib/new_relic/agent/instrumentation/data_mapper.rb +90 -0
  21. data/lib/new_relic/agent/instrumentation/dispatcher_instrumentation.rb +167 -0
  22. data/lib/new_relic/agent/instrumentation/memcache.rb +24 -0
  23. data/lib/new_relic/agent/instrumentation/merb/controller.rb +26 -0
  24. data/lib/new_relic/agent/instrumentation/merb/dispatcher.rb +13 -0
  25. data/lib/new_relic/agent/instrumentation/merb/errors.rb +8 -0
  26. data/lib/new_relic/agent/instrumentation/net.rb +23 -0
  27. data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +20 -0
  28. data/lib/new_relic/agent/instrumentation/rack.rb +108 -0
  29. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +59 -0
  30. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +27 -0
  31. data/lib/new_relic/agent/instrumentation/rails/dispatcher.rb +41 -0
  32. data/lib/new_relic/agent/instrumentation/rails/errors.rb +27 -0
  33. data/lib/new_relic/agent/instrumentation/sinatra.rb +39 -0
  34. data/lib/new_relic/agent/method_tracer.rb +349 -0
  35. data/lib/new_relic/agent/patch_const_missing.rb +125 -0
  36. data/lib/new_relic/agent/sampler.rb +12 -0
  37. data/lib/new_relic/agent/samplers/cpu_sampler.rb +49 -0
  38. data/lib/new_relic/agent/samplers/memory_sampler.rb +138 -0
  39. data/lib/new_relic/agent/samplers/mongrel_sampler.rb +22 -0
  40. data/lib/new_relic/agent/shim_agent.rb +21 -0
  41. data/lib/new_relic/agent/stats_engine.rb +22 -0
  42. data/lib/new_relic/agent/stats_engine/metric_stats.rb +111 -0
  43. data/lib/new_relic/agent/stats_engine/samplers.rb +71 -0
  44. data/lib/new_relic/agent/stats_engine/transactions.rb +152 -0
  45. data/lib/new_relic/agent/transaction_sampler.rb +310 -0
  46. data/lib/new_relic/agent/worker_loop.rb +118 -0
  47. data/lib/new_relic/commands/deployments.rb +145 -0
  48. data/lib/new_relic/commands/new_relic_commands.rb +30 -0
  49. data/lib/new_relic/control.rb +473 -0
  50. data/lib/new_relic/control/external.rb +13 -0
  51. data/lib/new_relic/control/merb.rb +22 -0
  52. data/lib/new_relic/control/rails.rb +145 -0
  53. data/lib/new_relic/control/ruby.rb +36 -0
  54. data/lib/new_relic/control/sinatra.rb +14 -0
  55. data/lib/new_relic/histogram.rb +89 -0
  56. data/lib/new_relic/local_environment.rb +328 -0
  57. data/lib/new_relic/merbtasks.rb +6 -0
  58. data/lib/new_relic/metric_data.rb +42 -0
  59. data/lib/new_relic/metric_parser.rb +124 -0
  60. data/lib/new_relic/metric_parser/action_mailer.rb +9 -0
  61. data/lib/new_relic/metric_parser/active_merchant.rb +26 -0
  62. data/lib/new_relic/metric_parser/active_record.rb +25 -0
  63. data/lib/new_relic/metric_parser/controller.rb +54 -0
  64. data/lib/new_relic/metric_parser/controller_cpu.rb +38 -0
  65. data/lib/new_relic/metric_parser/errors.rb +6 -0
  66. data/lib/new_relic/metric_parser/external.rb +50 -0
  67. data/lib/new_relic/metric_parser/mem_cache.rb +12 -0
  68. data/lib/new_relic/metric_parser/view.rb +61 -0
  69. data/lib/new_relic/metric_parser/web_frontend.rb +14 -0
  70. data/lib/new_relic/metric_parser/web_service.rb +9 -0
  71. data/lib/new_relic/metric_spec.rb +52 -0
  72. data/lib/new_relic/metrics.rb +7 -0
  73. data/lib/new_relic/noticed_error.rb +23 -0
  74. data/lib/new_relic/rack/metric_app.rb +56 -0
  75. data/lib/new_relic/rack/newrelic.ru +25 -0
  76. data/lib/new_relic/rack/newrelic.yml +25 -0
  77. data/lib/new_relic/rack_app.rb +5 -0
  78. data/lib/new_relic/recipes.rb +82 -0
  79. data/lib/new_relic/stats.rb +361 -0
  80. data/lib/new_relic/transaction_analysis.rb +121 -0
  81. data/lib/new_relic/transaction_sample.rb +666 -0
  82. data/lib/new_relic/version.rb +54 -0
  83. data/lib/new_relic_api.rb +313 -0
  84. data/lib/newrelic_rpm.rb +40 -0
  85. data/lib/tasks/all.rb +4 -0
  86. data/lib/tasks/install.rake +7 -0
  87. data/lib/tasks/tests.rake +13 -0
  88. data/newrelic.yml +227 -0
  89. data/recipes/newrelic.rb +6 -0
  90. data/techarch-newrelic_rpm.gemspec +32 -0
  91. data/test/active_record_fixtures.rb +55 -0
  92. data/test/config/newrelic.yml +46 -0
  93. data/test/config/test_control.rb +39 -0
  94. data/test/new_relic/agent/active_record_instrumentation_test.rb +264 -0
  95. data/test/new_relic/agent/agent_controller_test.rb +107 -0
  96. data/test/new_relic/agent/agent_test.rb +119 -0
  97. data/test/new_relic/agent/agent_test_controller.rb +44 -0
  98. data/test/new_relic/agent/classloader_patch_test.rb +56 -0
  99. data/test/new_relic/agent/collection_helper_test.rb +125 -0
  100. data/test/new_relic/agent/dispatcher_instrumentation_test.rb +76 -0
  101. data/test/new_relic/agent/error_collector_test.rb +172 -0
  102. data/test/new_relic/agent/method_tracer_test.rb +340 -0
  103. data/test/new_relic/agent/metric_data_test.rb +56 -0
  104. data/test/new_relic/agent/mock_ar_connection.rb +40 -0
  105. data/test/new_relic/agent/mock_scope_listener.rb +23 -0
  106. data/test/new_relic/agent/net_instrumentation_test.rb +63 -0
  107. data/test/new_relic/agent/stats_engine/metric_stats_test.rb +79 -0
  108. data/test/new_relic/agent/stats_engine/samplers_test.rb +81 -0
  109. data/test/new_relic/agent/stats_engine/stats_engine_test.rb +184 -0
  110. data/test/new_relic/agent/task_instrumentation_test.rb +126 -0
  111. data/test/new_relic/agent/testable_agent.rb +13 -0
  112. data/test/new_relic/agent/transaction_sample_builder_test.rb +195 -0
  113. data/test/new_relic/agent/transaction_sample_test.rb +186 -0
  114. data/test/new_relic/agent/transaction_sampler_test.rb +385 -0
  115. data/test/new_relic/agent/worker_loop_test.rb +103 -0
  116. data/test/new_relic/control_test.rb +113 -0
  117. data/test/new_relic/deployments_api_test.rb +68 -0
  118. data/test/new_relic/environment_test.rb +75 -0
  119. data/test/new_relic/metric_parser_test.rb +172 -0
  120. data/test/new_relic/metric_spec_test.rb +177 -0
  121. data/test/new_relic/shim_agent_test.rb +9 -0
  122. data/test/new_relic/stats_test.rb +291 -0
  123. data/test/new_relic/version_number_test.rb +74 -0
  124. data/test/test_helper.rb +38 -0
  125. data/test/ui/newrelic_controller_test.rb +14 -0
  126. data/test/ui/newrelic_helper_test.rb +53 -0
  127. data/ui/controllers/newrelic_controller.rb +220 -0
  128. data/ui/helpers/google_pie_chart.rb +55 -0
  129. data/ui/helpers/newrelic_helper.rb +317 -0
  130. data/ui/views/layouts/newrelic_default.rhtml +47 -0
  131. data/ui/views/newrelic/_explain_plans.rhtml +27 -0
  132. data/ui/views/newrelic/_sample.rhtml +19 -0
  133. data/ui/views/newrelic/_segment.rhtml +28 -0
  134. data/ui/views/newrelic/_segment_limit_message.rhtml +1 -0
  135. data/ui/views/newrelic/_segment_row.rhtml +14 -0
  136. data/ui/views/newrelic/_show_sample_detail.rhtml +24 -0
  137. data/ui/views/newrelic/_show_sample_sql.rhtml +20 -0
  138. data/ui/views/newrelic/_show_sample_summary.rhtml +3 -0
  139. data/ui/views/newrelic/_sql_row.rhtml +11 -0
  140. data/ui/views/newrelic/_stack_trace.rhtml +30 -0
  141. data/ui/views/newrelic/_table.rhtml +12 -0
  142. data/ui/views/newrelic/explain_sql.rhtml +42 -0
  143. data/ui/views/newrelic/images/arrow-close.png +0 -0
  144. data/ui/views/newrelic/images/arrow-open.png +0 -0
  145. data/ui/views/newrelic/images/blue_bar.gif +0 -0
  146. data/ui/views/newrelic/images/file_icon.png +0 -0
  147. data/ui/views/newrelic/images/gray_bar.gif +0 -0
  148. data/ui/views/newrelic/images/new_relic_rpm_desktop.gif +0 -0
  149. data/ui/views/newrelic/images/textmate.png +0 -0
  150. data/ui/views/newrelic/index.rhtml +57 -0
  151. data/ui/views/newrelic/javascript/prototype-scriptaculous.js +7288 -0
  152. data/ui/views/newrelic/javascript/transaction_sample.js +107 -0
  153. data/ui/views/newrelic/sample_not_found.rhtml +2 -0
  154. data/ui/views/newrelic/show_sample.rhtml +80 -0
  155. data/ui/views/newrelic/show_source.rhtml +3 -0
  156. data/ui/views/newrelic/stylesheets/style.css +484 -0
  157. data/ui/views/newrelic/threads.rhtml +52 -0
  158. metadata +330 -0
@@ -0,0 +1,138 @@
1
+ New Relic RPM
2
+ =============
3
+
4
+ New Relic RPM is a Ruby performance management system, developed by
5
+ [New Relic, Inc](http://www.newrelic.com). RPM provides you with deep
6
+ information about the performance of your Ruby on Rails or Merb
7
+ application as it runs in production. The New Relic Agent is
8
+ dual-purposed as a either a Rails plugin or a Gem, hosted on
9
+ [github](http://github.com/newrelic/rpm/tree/master) and Rubyforge.
10
+
11
+ The New Relic Agent runs in one of two modes:
12
+
13
+ **Developer Mode** : Adds a web interface mapped to /newrelic to your
14
+ application for showing detailed performance metrics on a page by
15
+ page basis.
16
+
17
+ **Production Mode** : Low overhead instrumentation that captures
18
+ detailed information on your application running in production and
19
+ transmits them to rpm.newrelic.com where you can monitor them in
20
+ real time.
21
+
22
+ ### Supported Environments
23
+
24
+ * Ruby 1.8.6, 1.8.7 or 1.9.1
25
+ * JRuby
26
+ * Rails 1.2.6 or above
27
+ * Merb 1.0 or above
28
+
29
+ Developer Mode
30
+ --------------
31
+
32
+ Developer mode is on by default when you run your application in the
33
+ development environment (but not when it runs in other environments.)
34
+ When running in developer mode, RPM will track the performance of
35
+ every http request serviced by your application, and store in memory
36
+ this information for the last 100 http transactions.
37
+
38
+ When running in Developer Mode, the RPM will also add a few pages to
39
+ your application that allow you to analyze this performance
40
+ information. (Don't worry--those pages are not added to your
41
+ application's routes when you run in production mode.)
42
+
43
+ To view this performance information, including detailed SQL statement
44
+ analysis, open `/newrelic` in your web application. For instance if
45
+ you are running mongrel or thin on port 3000, enter the following into
46
+ your browser:
47
+
48
+ http://localhost:3000/newrelic
49
+
50
+ Production Mode
51
+ ---------------
52
+
53
+ When your application runs in the production environment, the New
54
+ Relic agent runs in production mode. It connects to the New Relic RPM
55
+ service and sends deep performance data to the RPM service for your
56
+ analysis. To view this data, login to
57
+ [http://rpm.newrelic.com](http://rpm.newrelic.com).
58
+
59
+ NOTE: You must have a valid account and license key to view this data
60
+ online. Refer to instructions in *Getting Started*, below.
61
+
62
+ Getting Started
63
+ ===============
64
+
65
+ RPM requires an agent be installed in the application as either a
66
+ Rails plug-in or a gem. Both are available on RubyForge--instructions
67
+ below.
68
+
69
+ To use Developer Mode, simply install the gem or plugin into your
70
+ application and follow the instructions below.
71
+
72
+ To monitor your applications in production, create an account at
73
+ [www.newrelic.com](http://newrelic.com/get-RPM.html). There you can
74
+ sign up for a free Lite account or one of our paid subscriptions.
75
+
76
+ Once you receive the welcome e-mail with a license key and
77
+ `newrelic.yml` file, copy the `newrelic.yml` file into your app config
78
+ directory.
79
+
80
+ ### Rails Plug-In Installation
81
+
82
+ script/plugin install http://newrelic.rubyforge.org/svn/newrelic_rpm
83
+
84
+ ### Gem Installation
85
+
86
+ sudo gem install newrelic_rpm
87
+
88
+ For Rails, edit `environment.rb` and add to the initalizer block:
89
+
90
+ config.gem "newrelic_rpm"
91
+
92
+ The Developer Mode is unavailable when using the gem on Rails versions
93
+ prior to 2.0.
94
+
95
+ ### Merb Support
96
+
97
+ To monitor a merb app install the newrelic_rpm gem and add
98
+
99
+ dependency 'newrelic_rpm'
100
+
101
+ to your init.rb file.
102
+
103
+ Current features implemented:
104
+
105
+ * Standard monitoring, overview pages
106
+ * Error capturing
107
+ * Full Active Record instrumentation, including SQL explains
108
+ * Very limited Data Mapper instrumentation
109
+ * Transaction Traces are implemented but will not be very useful
110
+ with Data Mapper until more work is done with the Data Mapper
111
+ instrumentation
112
+
113
+ Still under development:
114
+
115
+ * Developer Mode
116
+ * Data Mapper bindings
117
+
118
+ ### Github
119
+
120
+ The agent is also available on Github under newrelic/rpm. Fork away!
121
+
122
+ ### Support
123
+
124
+ Reach out to us--and to fellow RPM users--at
125
+ [support.newrelic.com](http://support.newrelic.com/discussions/support).
126
+ There you'll find documentation, FAQs, and forums where you can submit
127
+ suggestions and discuss RPM with New Relic staff and other users.
128
+
129
+ Find a bug? E-mail support@newrelic.com, or post it to
130
+ [support.newrelic.com](http://support.newrelic.com/discussions/support).
131
+
132
+ Refer to [our website](http://www.newrelic.com/support) for other
133
+ support channels.
134
+
135
+ Thank you, and may your application scale to infinity plus one.
136
+
137
+ Lew Cirne, Founder and CEO<br/>
138
+ New Relic, Inc.
@@ -0,0 +1,22 @@
1
+ require 'rubygems'
2
+ require 'lib/new_relic/version.rb'
3
+ require 'echoe'
4
+
5
+ GEM_NAME = "newrelic_rpm"
6
+ GEM_VERSION = NewRelic::VERSION::STRING
7
+ AUTHOR = "Bill Kayser"
8
+ EMAIL = "bkayser@newrelic.com"
9
+ HOMEPAGE = "http://www.newrelic.com"
10
+ SUMMARY = "New Relic Ruby Performance Monitoring Agent"
11
+
12
+ Echoe.new(GEM_NAME) do |p|
13
+ p.author = AUTHOR
14
+ p.summary = SUMMARY
15
+ p.url = HOMEPAGE
16
+ p.email = EMAIL
17
+ p.project = 'newrelic'
18
+ p.need_tar_gz = false
19
+ p.need_gem = true
20
+ p.ignore_pattern = %w[]
21
+ end
22
+
@@ -0,0 +1,33 @@
1
+ #!/usr/bin/env ruby
2
+ require 'rubygems'
3
+ require 'rack'
4
+ require 'rack/handler/mongrel'
5
+ require 'optparse'
6
+
7
+ port = 3000
8
+ options = { }
9
+ appname = nil
10
+ OptionParser.new do |opts|
11
+ opts.banner = "Usage: #{File.basename($0)} [options] [app_name]"
12
+ opts.on("-p", "--port=port", Integer, "default: #{port}") { | port | }
13
+ opts.on("--[no-]logging", "turn off request logging" ) { | l | options[:logging] = l }
14
+ opts.on("--license=rpm_license_key", "override license key" ) { | l | options[:license_key] = l }
15
+ opts.on("--install", "install a newrelic.yml template" ) { | l | options[:install] = true }
16
+ opts.separator ""
17
+ opts.separator "app_name is the name of the application where the metrics will be stored"
18
+ opts.separator ""
19
+ # The rackup file references this var
20
+ appname = opts.parse!(ARGV.clone).first
21
+ end
22
+
23
+ options[:app_name] = appname if appname
24
+
25
+ ru_file = File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "new_relic", "rack", "newrelic.ru"))
26
+ rackup_code = File.read ru_file
27
+ builder = Rack::Builder.new { eval rackup_code, binding, ru_file }
28
+
29
+ options = { :Host => '127.0.0.1', :Port => port }
30
+ Rack::Handler::Mongrel.run(builder.to_app, options) do | server |
31
+ NewRelic::Control.instance.log! "Started Mongrel listening for '#{NewRelic::Control.instance.app_names.join(" and ")}' data at #{server.host}:#{server.port}"
32
+ end
33
+
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env ruby
2
+ # executes one of the commands in the new_relic/commands directory
3
+ # pass the name of the command as an argument
4
+ require File.dirname(__FILE__) + '/../lib/new_relic/commands/new_relic_commands'
@@ -0,0 +1,34 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
3
+ b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
4
+ YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
5
+ bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIy
6
+ MjM0OFoXDTE5MDYyNTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
7
+ d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEg
8
+ UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
9
+ LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
10
+ A4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9YLqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIi
11
+ GQj4/xEjm84H9b9pGib+TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCm
12
+ DuJWBQ8YTfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0LBwG
13
+ lN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLWI8sogTLDAHkY7FkX
14
+ icnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPwnXS3qT6gpf+2SQMT2iLM7XGCK5nP
15
+ Orf1LXLI
16
+ -----END CERTIFICATE-----
17
+
18
+ -----BEGIN CERTIFICATE-----
19
+ MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRp
20
+ b24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
21
+ YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZh
22
+ bGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAw
23
+ MTk1NFoXDTE5MDYyNjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0
24
+ d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIg
25
+ UG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0
26
+ LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMIGfMA0GCSqGSIb3DQEBAQUA
27
+ A4GNADCBiQKBgQDOOnHK5avIWZJV16vYdA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVC
28
+ CSRrCl6zfN1SLUzm1NZ9WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7Rf
29
+ ZHM047QSv4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9vUJSZ
30
+ SWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTuIYEZoDJJKPTEjlbV
31
+ UjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwCW/POuZ6lcg5Ktz885hZo+L7tdEy8
32
+ W9ViH0Pd
33
+ -----END CERTIFICATE-----
34
+
data/init.rb ADDED
@@ -0,0 +1,38 @@
1
+ # This is the initialization for the RPM Rails plugin
2
+ require 'new_relic/control'
3
+
4
+ # If you are having problems seeing data, be sure and check the
5
+ # newrelic_agent log files.
6
+ #
7
+ # If you can't find any log files and you don't see anything in your
8
+ # application log files, try uncommenting the two lines at the
9
+ # bottom of this file to verify the plugin is being loaded,
10
+ # then send the output to support@newrelic.com if you are unable to
11
+ # resolve the issue.
12
+
13
+ # Initializer for the NewRelic Agent
14
+
15
+ # We use this to test the agent to ensure it's not loading classes inappropriately
16
+ #require 'new_relic/agent/patch_const_missing'
17
+ #ClassLoadingWatcher.flag_const_missing = true
18
+ begin
19
+ # JRuby's glassfish plugin is trying to run the Initializer twice,
20
+ # which isn't a good thing so we ignore subsequent invocations here.
21
+ if ! defined?(::NEWRELIC_STARTED)
22
+ ::NEWRELIC_STARTED = "#{caller.join("\n")}"
23
+
24
+ NewRelic::Control.instance.init_plugin(defined?(config) ? {:config => config} : {})
25
+ else
26
+ NewRelic::Control.instance.log.debug "Attempt to initialize the plugin twice!"
27
+ NewRelic::Control.instance.log.debug "Original call: \n#{::NEWRELIC_STARTED}"
28
+ NewRelic::Control.instance.log.debug "Here we are now: \n#{caller.join("\n")}"
29
+ end
30
+ rescue => e
31
+ NewRelic::Control.instance.log! "Error initializing New Relic plugin (#{e})", :error
32
+ NewRelic::Control.instance.log! e.backtrace.join("\n"), :error
33
+ NewRelic::Control.instance.log! "Agent is disabled."
34
+ end
35
+ #ClassLoadingWatcher.flag_const_missing = nil
36
+
37
+ # ::RAILS_DEFAULT_LOGGER.warn "RPM detected environment: #{NewRelic::Control.instance.local_env.to_s}, RAILS_ENV: #{RAILS_ENV}"
38
+ # ::RAILS_DEFAULT_LOGGER.warn "Enabled? #{NewRelic::Control.instance.agent_enabled?}"
@@ -0,0 +1,45 @@
1
+ require 'fileutils'
2
+ require 'erb'
3
+
4
+ def install_newrelic_config_file(license_key="PASTE_YOUR_LICENSE_KEY_HERE")
5
+ # Install a newrelic.yml file into the local config directory.
6
+ if File.directory? "config"
7
+ dest_dir = "config"
8
+ else
9
+ dest_dir = File.join(ENV["HOME"],".newrelic") rescue nil
10
+ FileUtils.mkdir(dest_dir) if dest_dir
11
+ end
12
+
13
+ src_config_file = File.join(File.dirname(__FILE__),"newrelic.yml")
14
+ dest_config_file = File.join(dest_dir, "newrelic.yml") if dest_dir
15
+
16
+ if !dest_dir
17
+ STDERR.puts "Could not find a config or ~/.newrelic directory to locate the default newrelic.yml file"
18
+ elsif File::exists? dest_config_file
19
+ STDERR.puts "\nA config file already exists at #{dest_config_file}.\n"
20
+ else
21
+ generated_for_user = ""
22
+ yaml = ERB.new(File.read(src_config_file)).result(binding)
23
+ File.open( dest_config_file, 'w' ) do |out|
24
+ out.puts yaml
25
+ end
26
+
27
+ puts <<-EOF
28
+
29
+ Installed a default configuration file in #{dest_dir}.
30
+
31
+ To monitor your application in production mode, sign up for an account
32
+ at www.newrelic.com, and replace the newrelic.yml file with the one
33
+ you receive upon registration.
34
+
35
+ Please review the README.md file for more information.
36
+
37
+ E-mail support@newrelic.com with any problems or questions.
38
+
39
+ EOF
40
+ end
41
+ end
42
+
43
+ if __FILE__ == $0 || $0 =~ /script\/plugin/
44
+ install_newrelic_config_file
45
+ end
@@ -0,0 +1,281 @@
1
+ # = New Relic Agent
2
+ #
3
+ # New Relic RPM is a performance monitoring application for Ruby
4
+ # applications running in production. For more information on RPM
5
+ # please visit http://www.newrelic.com.
6
+ #
7
+ # The New Relic Agent can be installed in Rails applications to gather
8
+ # runtime performance metrics, traces, and errors for display in a
9
+ # Developer Mode UI (mapped to /newrelic in your application server)
10
+ # or for monitoring and analysis at http://rpm.newrelic.com with just
11
+ # about any Ruby application.
12
+ #
13
+ # For detailed information on configuring or customizing the RPM Agent
14
+ # please visit our {support and documentation site}[http://support.newrelic.com].
15
+ #
16
+ # == Starting the Agent as a Gem
17
+ #
18
+ # For Rails, add:
19
+ # config.gem 'newrelic_rpm'
20
+ # to your initialization sequence.
21
+ #
22
+ # For merb, do
23
+ # dependency 'newrelic_rpm'
24
+ # in the Merb config/init.rb
25
+ #
26
+ # For Sinatra, just require the +newrelic_rpm+ gem and it will
27
+ # automatically detect Sinatra and instrument all the handlers.
28
+ #
29
+ # For other frameworks, or to manage the agent manually,
30
+ # invoke NewRelic::Agent#manual_start directly.
31
+ #
32
+ # == Configuring the Agent
33
+ #
34
+ # All agent configuration is done in the <tt>newrelic.yml</tt> file. This
35
+ # file is by default read from the +config+ directory of the
36
+ # application root and is subsequently searched for in the application
37
+ # root directory, and then in a <tt>~/.newrelic</tt> directory
38
+ #
39
+ # == Using with Rack/Metal
40
+ #
41
+ # To instrument middlewares, refer to the docs in
42
+ # NewRelic::Agent::Instrumentation::Rack.
43
+ #
44
+ # == Agent API
45
+ #
46
+ # For details on the Agent API, refer to NewRelic::Agent.
47
+ #
48
+ #
49
+ # :main: lib/new_relic/agent.rb
50
+ module NewRelic
51
+ # == Agent APIs
52
+ # This module contains the public API methods for the Agent.
53
+ #
54
+ # For adding custom instrumentation to method invocations, refer to
55
+ # the docs in the class NewRelic::Agent::MethodTracer.
56
+ #
57
+ # For information on how to customize the controller
58
+ # instrumentation, or to instrument something other than Rails so
59
+ # that high level dispatcher actions or background tasks show up as
60
+ # first class operations in RPM, refer to
61
+ # NewRelic::Agent::Instrumentation::ControllerInstrumentation and
62
+ # NewRelic::Agent::Instrumentation::ControllerInstrumentation::ClassMethods.
63
+ #
64
+ # Methods in this module as well as documented methods in
65
+ # NewRelic::Agent::MethodTracer and
66
+ # NewRelic::Agent::Instrumentation::ControllerInstrumentation are
67
+ # available to applications. When the agent is not enabled the
68
+ # method implementations are stubbed into no-ops to reduce overhead.
69
+ #
70
+ # Methods and classes in other parts of the agent are not guaranteed
71
+ # to be available between releases.
72
+ #
73
+ # Refer to the online docs at support.newrelic.com to see how to
74
+ # access the data collected by custom instrumentation, or e-mail
75
+ # support at New Relic for help.
76
+ module Agent
77
+ extend self
78
+
79
+ require 'new_relic/version'
80
+ require 'new_relic/local_environment'
81
+ require 'new_relic/stats'
82
+ require 'new_relic/metric_spec'
83
+ require 'new_relic/metric_data'
84
+ require 'new_relic/metric_parser'
85
+ require 'new_relic/transaction_analysis'
86
+ require 'new_relic/transaction_sample'
87
+ require 'new_relic/noticed_error'
88
+ require 'new_relic/histogram'
89
+
90
+ require 'new_relic/agent/chained_call'
91
+ require 'new_relic/agent/agent'
92
+ require 'new_relic/agent/shim_agent'
93
+ require 'new_relic/agent/method_tracer'
94
+ require 'new_relic/agent/worker_loop'
95
+ require 'new_relic/agent/stats_engine'
96
+ require 'new_relic/agent/collection_helper'
97
+ require 'new_relic/agent/transaction_sampler'
98
+ require 'new_relic/agent/error_collector'
99
+ require 'new_relic/agent/sampler'
100
+
101
+ require 'new_relic/agent/samplers/cpu_sampler'
102
+ require 'new_relic/agent/samplers/memory_sampler'
103
+ require 'new_relic/agent/samplers/mongrel_sampler'
104
+ require 'new_relic/agent/samplers/object_sampler'
105
+ require 'set'
106
+ require 'sync'
107
+ require 'thread'
108
+ require 'resolv'
109
+ require 'timeout'
110
+
111
+ # An exception that is thrown by the server if the agent license is invalid.
112
+ class LicenseException < StandardError; end
113
+
114
+ # An exception that forces an agent to stop reporting until its mongrel is restarted.
115
+ class ForceDisconnectException < StandardError; end
116
+
117
+ # An exception that forces an agent to restart.
118
+ class ForceRestartException < StandardError; end
119
+
120
+ # Used to blow out of a periodic task without logging a an error, such as for routine
121
+ # failures.
122
+ class IgnoreSilentlyException < StandardError; end
123
+
124
+ # Used for when a transaction trace or error report has too much
125
+ # data, so we reset the queue to clear the extra-large item
126
+ class PostTooBigException < IgnoreSilentlyException; end
127
+
128
+ # Reserved for future use. Meant to represent a problem on the server side.
129
+ class ServerError < StandardError; end
130
+
131
+ class BackgroundLoadingError < StandardError; end
132
+
133
+ @agent = nil
134
+
135
+ # The singleton Agent instance. Used internally.
136
+ def agent #:nodoc:
137
+ raise "Plugin not initialized!" if @agent.nil?
138
+ @agent
139
+ end
140
+
141
+ def agent= new_instance #:nodoc:
142
+ @agent = new_instance
143
+ end
144
+
145
+ alias instance agent #:nodoc:
146
+
147
+ # Get or create a statistics gatherer that will aggregate numerical data
148
+ # under a metric name.
149
+ #
150
+ # +metric_name+ should follow a slash separated path convention. Application
151
+ # specific metrics should begin with "Custom/".
152
+ #
153
+ # Return a NewRelic::Stats that accepts data
154
+ # via calls to add_data_point(value).
155
+ def get_stats(metric_name, use_scope=false)
156
+ @agent.stats_engine.get_stats(metric_name, use_scope)
157
+ end
158
+
159
+ alias get_stats_no_scope get_stats
160
+
161
+ # Call this to manually start the Agent in situations where the Agent does
162
+ # not auto-start.
163
+ #
164
+ # When the app environment loads, so does the Agent. However, the Agent will
165
+ # only connect to RPM if a web front-end is found. If you want to selectively monitor
166
+ # ruby processes that don't use web plugins, then call this method in your
167
+ # code and the Agent will fire up and start reporting to RPM.
168
+ #
169
+ # Options are passed in as overrides for values in the newrelic.yml, such
170
+ # as app_name. In addition, the option +log+ will take a logger that
171
+ # will be used instead of the standard file logger. The setting for
172
+ # the newrelic.yml section to use (ie, RAILS_ENV) can be overridden
173
+ # with an :env argument.
174
+ #
175
+ def manual_start(options={})
176
+ raise unless Hash === options
177
+ # Ignore all args but hash options
178
+ options.merge! :agent_enabled => true
179
+ NewRelic::Control.instance.init_plugin options
180
+ end
181
+
182
+ # Shutdown the agent. Call this before exiting. Sends any queued data
183
+ # and kills the background thread.
184
+ def shutdown
185
+ @agent.shutdown
186
+ end
187
+
188
+ # This method sets the block sent to this method as a sql obfuscator.
189
+ # The block will be called with a single String SQL statement to obfuscate.
190
+ # The method must return the obfuscated String SQL.
191
+ # If chaining of obfuscators is required, use type = :before or :after
192
+ #
193
+ # type = :before, :replace, :after
194
+ #
195
+ # Example:
196
+ #
197
+ # NewRelic::Agent.set_sql_obfuscator(:replace) do |sql|
198
+ # my_obfuscator(sql)
199
+ # end
200
+ #
201
+ def set_sql_obfuscator(type = :replace, &block)
202
+ agent.set_sql_obfuscator type, &block
203
+ end
204
+
205
+
206
+ # This method sets the state of sql recording in the transaction
207
+ # sampler feature. Within the given block, no sql will be recorded
208
+ #
209
+ # usage:
210
+ #
211
+ # NewRelic::Agent.disable_sql_recording do
212
+ # ...
213
+ # end
214
+ #
215
+ def disable_sql_recording
216
+ state = agent.set_record_sql(false)
217
+ begin
218
+ yield
219
+ ensure
220
+ agent.set_record_sql(state)
221
+ end
222
+ end
223
+
224
+ # This method disables the recording of transaction traces in the given
225
+ # block. See also #disable_all_tracing
226
+ def disable_transaction_tracing
227
+ state = agent.set_record_tt(false)
228
+ begin
229
+ yield
230
+ ensure
231
+ agent.set_record_tt(state)
232
+ end
233
+ end
234
+
235
+ # Yield to the block without collecting any metrics or traces in any of the
236
+ # subsequent calls. If executed recursively, will keep track of the first
237
+ # entry point and turn on tracing again after leaving that block.
238
+ # This uses the thread local +newrelic_untrace+
239
+ def disable_all_tracing
240
+ agent.push_trace_execution_flag(false)
241
+ yield
242
+ ensure
243
+ agent.pop_trace_execution_flag
244
+ end
245
+
246
+ # Check to see if we are capturing metrics currently on this thread.
247
+ def is_execution_traced?
248
+ Thread.current[:newrelic_untraced].nil? || Thread.current[:newrelic_untraced].last != false
249
+ end
250
+
251
+ # Set a filter to be applied to errors that RPM will track.
252
+ # The block should return the exception to track (which could be different from
253
+ # the original exception) or nil to ignore this exception.
254
+ #
255
+ # The block is yielded to with the exception to filter.
256
+ #
257
+ def ignore_error_filter(&block)
258
+ agent.error_collector.ignore_error_filter(&block)
259
+ end
260
+
261
+ # Record the given error in RPM. It will be passed through the #ignore_error_filter
262
+ # if there is one.
263
+ #
264
+ # * <tt>exception</tt> is the exception which will be recorded
265
+ # * <tt>extra_params</tt> is a hash of name value pairs to appear alongside
266
+ # the exception in RPM.
267
+ #
268
+ def notice_error(exception, extra_params = {})
269
+ NewRelic::Agent.agent.error_collector.notice_error(exception, nil, nil, extra_params)
270
+ end
271
+
272
+ # Add parameters to the current transaction trace on the call stack.
273
+ #
274
+ def add_custom_parameters(params)
275
+ agent.add_custom_parameters(params)
276
+ end
277
+
278
+ alias add_request_parameters add_custom_parameters
279
+
280
+ end
281
+ end