dolores_rpm 3.2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +559 -0
- data/LICENSE +64 -0
- data/README.rdoc +179 -0
- data/bin/mongrel_rpm +33 -0
- data/bin/newrelic +13 -0
- data/bin/newrelic_cmd +5 -0
- data/cert/cacert.pem +118 -0
- data/cert/oldsite.pem +28 -0
- data/cert/site.pem +27 -0
- data/dolores_rpm-3.3.4.fork.gem +0 -0
- data/install.rb +9 -0
- data/lib/conditional_vendored_dependency_detection.rb +3 -0
- data/lib/conditional_vendored_metric_parser.rb +5 -0
- data/lib/new_relic/agent/agent.rb +1311 -0
- data/lib/new_relic/agent/beacon_configuration.rb +110 -0
- data/lib/new_relic/agent/browser_monitoring.rb +102 -0
- data/lib/new_relic/agent/busy_calculator.rb +99 -0
- data/lib/new_relic/agent/chained_call.rb +13 -0
- data/lib/new_relic/agent/database.rb +203 -0
- data/lib/new_relic/agent/error_collector.rb +251 -0
- data/lib/new_relic/agent/instrumentation/active_merchant.rb +27 -0
- data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +68 -0
- data/lib/new_relic/agent/instrumentation/authlogic.rb +19 -0
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +424 -0
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +57 -0
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +52 -0
- data/lib/new_relic/agent/instrumentation/memcache.rb +80 -0
- data/lib/new_relic/agent/instrumentation/merb/controller.rb +41 -0
- data/lib/new_relic/agent/instrumentation/merb/errors.rb +29 -0
- data/lib/new_relic/agent/instrumentation/metric_frame/pop.rb +80 -0
- data/lib/new_relic/agent/instrumentation/metric_frame.rb +332 -0
- data/lib/new_relic/agent/instrumentation/net.rb +29 -0
- data/lib/new_relic/agent/instrumentation/passenger_instrumentation.rb +36 -0
- data/lib/new_relic/agent/instrumentation/queue_time.rb +210 -0
- data/lib/new_relic/agent/instrumentation/rack.rb +98 -0
- data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +114 -0
- data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +42 -0
- data/lib/new_relic/agent/instrumentation/rails/active_record_instrumentation.rb +115 -0
- data/lib/new_relic/agent/instrumentation/rails/errors.rb +42 -0
- data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +118 -0
- data/lib/new_relic/agent/instrumentation/rails3/active_record_instrumentation.rb +122 -0
- data/lib/new_relic/agent/instrumentation/rails3/errors.rb +37 -0
- data/lib/new_relic/agent/instrumentation/sinatra.rb +58 -0
- data/lib/new_relic/agent/instrumentation/sunspot.rb +29 -0
- data/lib/new_relic/agent/instrumentation/unicorn_instrumentation.rb +21 -0
- data/lib/new_relic/agent/instrumentation.rb +9 -0
- data/lib/new_relic/agent/method_tracer.rb +528 -0
- data/lib/new_relic/agent/sampler.rb +50 -0
- data/lib/new_relic/agent/samplers/cpu_sampler.rb +58 -0
- data/lib/new_relic/agent/samplers/delayed_job_lock_sampler.rb +40 -0
- data/lib/new_relic/agent/samplers/memory_sampler.rb +144 -0
- data/lib/new_relic/agent/samplers/object_sampler.rb +26 -0
- data/lib/new_relic/agent/shim_agent.rb +29 -0
- data/lib/new_relic/agent/sql_sampler.rb +267 -0
- data/lib/new_relic/agent/stats_engine/metric_stats.rb +187 -0
- data/lib/new_relic/agent/stats_engine/samplers.rb +95 -0
- data/lib/new_relic/agent/stats_engine/transactions.rb +208 -0
- data/lib/new_relic/agent/stats_engine.rb +25 -0
- data/lib/new_relic/agent/transaction_sample_builder.rb +101 -0
- data/lib/new_relic/agent/transaction_sampler.rb +397 -0
- data/lib/new_relic/agent/worker_loop.rb +89 -0
- data/lib/new_relic/agent.rb +454 -0
- data/lib/new_relic/collection_helper.rb +75 -0
- data/lib/new_relic/command.rb +85 -0
- data/lib/new_relic/commands/deployments.rb +105 -0
- data/lib/new_relic/commands/install.rb +80 -0
- data/lib/new_relic/control/class_methods.rb +53 -0
- data/lib/new_relic/control/configuration.rb +202 -0
- data/lib/new_relic/control/frameworks/external.rb +16 -0
- data/lib/new_relic/control/frameworks/merb.rb +31 -0
- data/lib/new_relic/control/frameworks/rails.rb +164 -0
- data/lib/new_relic/control/frameworks/rails3.rb +75 -0
- data/lib/new_relic/control/frameworks/ruby.rb +42 -0
- data/lib/new_relic/control/frameworks/sinatra.rb +20 -0
- data/lib/new_relic/control/frameworks.rb +10 -0
- data/lib/new_relic/control/instance_methods.rb +179 -0
- data/lib/new_relic/control/instrumentation.rb +100 -0
- data/lib/new_relic/control/logging_methods.rb +143 -0
- data/lib/new_relic/control/profiling.rb +25 -0
- data/lib/new_relic/control/server_methods.rb +114 -0
- data/lib/new_relic/control.rb +46 -0
- data/lib/new_relic/data_serialization.rb +157 -0
- data/lib/new_relic/delayed_job_injection.rb +46 -0
- data/lib/new_relic/language_support.rb +69 -0
- data/lib/new_relic/local_environment.rb +414 -0
- data/lib/new_relic/merbtasks.rb +6 -0
- data/lib/new_relic/metric_data.rb +51 -0
- data/lib/new_relic/metric_spec.rb +75 -0
- data/lib/new_relic/metrics.rb +9 -0
- data/lib/new_relic/noticed_error.rb +24 -0
- data/lib/new_relic/rack/browser_monitoring.rb +68 -0
- data/lib/new_relic/rack/developer_mode.rb +268 -0
- data/lib/new_relic/recipes.rb +73 -0
- data/lib/new_relic/stats.rb +388 -0
- data/lib/new_relic/timer_lib.rb +27 -0
- data/lib/new_relic/transaction_analysis/segment_summary.rb +49 -0
- data/lib/new_relic/transaction_analysis.rb +77 -0
- data/lib/new_relic/transaction_sample/composite_segment.rb +27 -0
- data/lib/new_relic/transaction_sample/fake_segment.rb +9 -0
- data/lib/new_relic/transaction_sample/segment.rb +201 -0
- data/lib/new_relic/transaction_sample/summary_segment.rb +21 -0
- data/lib/new_relic/transaction_sample.rb +245 -0
- data/lib/new_relic/url_rule.rb +14 -0
- data/lib/new_relic/version.rb +55 -0
- data/lib/newrelic_rpm.rb +49 -0
- data/lib/tasks/all.rb +4 -0
- data/lib/tasks/install.rake +7 -0
- data/lib/tasks/tests.rake +19 -0
- data/newrelic.yml +265 -0
- data/recipes/newrelic.rb +6 -0
- data/test/active_record_fixtures.rb +77 -0
- data/test/config/newrelic.yml +48 -0
- data/test/config/test_control.rb +48 -0
- data/test/new_relic/agent/agent/connect_test.rb +410 -0
- data/test/new_relic/agent/agent/start_test.rb +255 -0
- data/test/new_relic/agent/agent/start_worker_thread_test.rb +153 -0
- data/test/new_relic/agent/agent_test.rb +139 -0
- data/test/new_relic/agent/agent_test_controller.rb +77 -0
- data/test/new_relic/agent/agent_test_controller_test.rb +363 -0
- data/test/new_relic/agent/apdex_from_server_test.rb +9 -0
- data/test/new_relic/agent/beacon_configuration_test.rb +108 -0
- data/test/new_relic/agent/browser_monitoring_test.rb +278 -0
- data/test/new_relic/agent/busy_calculator_test.rb +81 -0
- data/test/new_relic/agent/database_test.rb +162 -0
- data/test/new_relic/agent/error_collector/notice_error_test.rb +257 -0
- data/test/new_relic/agent/error_collector_test.rb +175 -0
- data/test/new_relic/agent/instrumentation/active_record_instrumentation_test.rb +538 -0
- data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +36 -0
- data/test/new_relic/agent/instrumentation/instrumentation_test.rb +11 -0
- data/test/new_relic/agent/instrumentation/metric_frame/pop_test.rb +172 -0
- data/test/new_relic/agent/instrumentation/metric_frame_test.rb +50 -0
- data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +84 -0
- data/test/new_relic/agent/instrumentation/queue_time_test.rb +387 -0
- data/test/new_relic/agent/instrumentation/rack_test.rb +35 -0
- data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +184 -0
- data/test/new_relic/agent/memcache_instrumentation_test.rb +143 -0
- data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +164 -0
- data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +234 -0
- data/test/new_relic/agent/method_tracer_test.rb +386 -0
- data/test/new_relic/agent/mock_scope_listener.rb +23 -0
- data/test/new_relic/agent/rpm_agent_test.rb +149 -0
- data/test/new_relic/agent/sampler_test.rb +19 -0
- data/test/new_relic/agent/shim_agent_test.rb +20 -0
- data/test/new_relic/agent/sql_sampler_test.rb +160 -0
- data/test/new_relic/agent/stats_engine/metric_stats/harvest_test.rb +150 -0
- data/test/new_relic/agent/stats_engine/metric_stats_test.rb +82 -0
- data/test/new_relic/agent/stats_engine/samplers_test.rb +99 -0
- data/test/new_relic/agent/stats_engine_test.rb +185 -0
- data/test/new_relic/agent/transaction_sample_builder_test.rb +195 -0
- data/test/new_relic/agent/transaction_sampler_test.rb +955 -0
- data/test/new_relic/agent/worker_loop_test.rb +66 -0
- data/test/new_relic/agent_test.rb +175 -0
- data/test/new_relic/collection_helper_test.rb +149 -0
- data/test/new_relic/command/deployments_test.rb +68 -0
- data/test/new_relic/control/class_methods_test.rb +62 -0
- data/test/new_relic/control/configuration_test.rb +72 -0
- data/test/new_relic/control/logging_methods_test.rb +185 -0
- data/test/new_relic/control_test.rb +254 -0
- data/test/new_relic/data_serialization_test.rb +208 -0
- data/test/new_relic/delayed_job_injection_test.rb +16 -0
- data/test/new_relic/local_environment_test.rb +72 -0
- data/test/new_relic/metric_data_test.rb +125 -0
- data/test/new_relic/metric_spec_test.rb +95 -0
- data/test/new_relic/rack/all_test.rb +11 -0
- data/test/new_relic/rack/browser_monitoring_test.rb +84 -0
- data/test/new_relic/rack/developer_mode_helper_test.rb +141 -0
- data/test/new_relic/rack/developer_mode_test.rb +43 -0
- data/test/new_relic/stats_test.rb +426 -0
- data/test/new_relic/transaction_analysis/segment_summary_test.rb +91 -0
- data/test/new_relic/transaction_analysis_test.rb +121 -0
- data/test/new_relic/transaction_sample/composite_segment_test.rb +35 -0
- data/test/new_relic/transaction_sample/fake_segment_test.rb +17 -0
- data/test/new_relic/transaction_sample/segment_test.rb +389 -0
- data/test/new_relic/transaction_sample/summary_segment_test.rb +31 -0
- data/test/new_relic/transaction_sample_subtest_test.rb +56 -0
- data/test/new_relic/transaction_sample_test.rb +164 -0
- data/test/new_relic/version_number_test.rb +89 -0
- data/test/test_contexts.rb +29 -0
- data/test/test_helper.rb +154 -0
- data/ui/helpers/developer_mode_helper.rb +357 -0
- data/ui/helpers/google_pie_chart.rb +48 -0
- data/ui/views/layouts/newrelic_default.rhtml +47 -0
- data/ui/views/newrelic/_explain_plans.rhtml +27 -0
- data/ui/views/newrelic/_sample.rhtml +20 -0
- data/ui/views/newrelic/_segment.rhtml +28 -0
- data/ui/views/newrelic/_segment_limit_message.rhtml +1 -0
- data/ui/views/newrelic/_segment_row.rhtml +12 -0
- data/ui/views/newrelic/_show_sample_detail.rhtml +24 -0
- data/ui/views/newrelic/_show_sample_sql.rhtml +24 -0
- data/ui/views/newrelic/_show_sample_summary.rhtml +3 -0
- data/ui/views/newrelic/_sql_row.rhtml +16 -0
- data/ui/views/newrelic/_stack_trace.rhtml +15 -0
- data/ui/views/newrelic/_table.rhtml +12 -0
- data/ui/views/newrelic/explain_sql.rhtml +43 -0
- data/ui/views/newrelic/file/images/arrow-close.png +0 -0
- data/ui/views/newrelic/file/images/arrow-open.png +0 -0
- data/ui/views/newrelic/file/images/blue_bar.gif +0 -0
- data/ui/views/newrelic/file/images/file_icon.png +0 -0
- data/ui/views/newrelic/file/images/gray_bar.gif +0 -0
- data/ui/views/newrelic/file/images/new-relic-rpm-desktop.gif +0 -0
- data/ui/views/newrelic/file/images/new_relic_rpm_desktop.gif +0 -0
- data/ui/views/newrelic/file/images/textmate.png +0 -0
- data/ui/views/newrelic/file/javascript/jquery-1.4.2.js +6240 -0
- data/ui/views/newrelic/file/javascript/transaction_sample.js +120 -0
- data/ui/views/newrelic/file/stylesheets/style.css +490 -0
- data/ui/views/newrelic/index.rhtml +71 -0
- data/ui/views/newrelic/sample_not_found.rhtml +2 -0
- data/ui/views/newrelic/show_sample.rhtml +80 -0
- data/ui/views/newrelic/show_source.rhtml +3 -0
- data/ui/views/newrelic/threads.rhtml +53 -0
- data/vendor/gems/dependency_detection-0.0.1.build/LICENSE +5 -0
- data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection/version.rb +3 -0
- data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb +62 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/metric_parser.rb +1 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/action_mailer.rb +14 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/active_merchant.rb +31 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/active_record.rb +33 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/apdex.rb +89 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/background_transaction.rb +7 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/client.rb +46 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/controller.rb +67 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/controller_cpu.rb +43 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/controller_ext.rb +17 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/database.rb +48 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/database_pool.rb +24 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/dot_net.rb +28 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/dot_net_parser.rb +17 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/errors.rb +11 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/external.rb +55 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/frontend.rb +40 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/gc.rb +20 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/hibernate_session.rb +7 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/java.rb +31 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/java_parser.rb +17 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/jsp.rb +34 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/jsp_tag.rb +7 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/mem_cache.rb +55 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/metric_parser.rb +122 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/orm.rb +27 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/other_transaction.rb +40 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/servlet.rb +7 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/servlet_context_listener.rb +7 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/servlet_filter.rb +7 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/solr.rb +27 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/solr_request_handler.rb +15 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/spring.rb +54 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/spring_controller.rb +6 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/spring_view.rb +6 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/struts_action.rb +20 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/struts_result.rb +20 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/version.rb +5 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/view.rb +70 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/web_frontend.rb +18 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/web_service.rb +14 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/web_transaction.rb +133 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser.rb +64 -0
- metadata +398 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
require 'new_relic/control'
|
|
2
|
+
require 'new_relic/data_serialization'
|
|
3
|
+
# = New Relic Ruby Agent
|
|
4
|
+
#
|
|
5
|
+
# New Relic is a performance monitoring application for applications
|
|
6
|
+
# running in production. For more information on New Relic please visit
|
|
7
|
+
# http://www.newrelic.com.
|
|
8
|
+
#
|
|
9
|
+
# The New Relic Ruby Agent can be installed in Rails applications to
|
|
10
|
+
# gather runtime performance metrics, traces, and errors for display
|
|
11
|
+
# in a Developer Mode middleware (mapped to /newrelic in your application
|
|
12
|
+
# server) or for monitoring and analysis at http://rpm.newrelic.com
|
|
13
|
+
# with just about any Ruby application.
|
|
14
|
+
#
|
|
15
|
+
# == Getting Started
|
|
16
|
+
# For instructions on installation and setup, see
|
|
17
|
+
# the README[link:./files/README_rdoc.html] file.
|
|
18
|
+
#
|
|
19
|
+
# == Using with Rack/Metal
|
|
20
|
+
#
|
|
21
|
+
# To instrument Rack middlwares or Metal apps, refer to the docs in
|
|
22
|
+
# NewRelic::Agent::Instrumentation::Rack.
|
|
23
|
+
#
|
|
24
|
+
# == Ruby Agent API
|
|
25
|
+
#
|
|
26
|
+
# For details on the Ruby Agent API, refer to NewRelic::Agent.
|
|
27
|
+
#
|
|
28
|
+
# == Customizing the Ruby Agent
|
|
29
|
+
#
|
|
30
|
+
# For detailed information on customizing the Ruby Agent
|
|
31
|
+
# please visit our {support and documentation site}[http://support.newrelic.com].
|
|
32
|
+
#
|
|
33
|
+
module NewRelic
|
|
34
|
+
# == Ruby Agent APIs
|
|
35
|
+
# This module contains the public API methods for the Ruby Agent.
|
|
36
|
+
#
|
|
37
|
+
# For adding custom instrumentation to method invocations, refer to
|
|
38
|
+
# the docs in the class NewRelic::Agent::MethodTracer.
|
|
39
|
+
#
|
|
40
|
+
# For information on how to customize the controller
|
|
41
|
+
# instrumentation, or to instrument something other than Rails so
|
|
42
|
+
# that high level dispatcher actions or background tasks show up as
|
|
43
|
+
# first class operations in New Relic, refer to
|
|
44
|
+
# NewRelic::Agent::Instrumentation::ControllerInstrumentation and
|
|
45
|
+
# NewRelic::Agent::Instrumentation::ControllerInstrumentation::ClassMethods.
|
|
46
|
+
#
|
|
47
|
+
# Methods in this module as well as documented methods in
|
|
48
|
+
# NewRelic::Agent::MethodTracer and
|
|
49
|
+
# NewRelic::Agent::Instrumentation::ControllerInstrumentation are
|
|
50
|
+
# available to applications. When the agent is not enabled the
|
|
51
|
+
# method implementations are stubbed into no-ops to reduce overhead.
|
|
52
|
+
#
|
|
53
|
+
# Methods and classes in other parts of the agent are not guaranteed
|
|
54
|
+
# to be available between releases.
|
|
55
|
+
#
|
|
56
|
+
# Refer to the online docs at support.newrelic.com to see how to
|
|
57
|
+
# access the data collected by custom instrumentation, or e-mail
|
|
58
|
+
# support at New Relic for help.
|
|
59
|
+
module Agent
|
|
60
|
+
extend self
|
|
61
|
+
|
|
62
|
+
require 'new_relic/version'
|
|
63
|
+
require 'new_relic/local_environment'
|
|
64
|
+
require 'new_relic/stats'
|
|
65
|
+
require 'new_relic/metrics'
|
|
66
|
+
require 'new_relic/metric_spec'
|
|
67
|
+
require 'new_relic/metric_data'
|
|
68
|
+
require 'new_relic/collection_helper'
|
|
69
|
+
require 'new_relic/transaction_analysis'
|
|
70
|
+
require 'new_relic/transaction_sample'
|
|
71
|
+
require 'new_relic/url_rule'
|
|
72
|
+
require 'new_relic/noticed_error'
|
|
73
|
+
require 'new_relic/timer_lib'
|
|
74
|
+
|
|
75
|
+
require 'new_relic/agent'
|
|
76
|
+
require 'new_relic/agent/chained_call'
|
|
77
|
+
require 'new_relic/agent/browser_monitoring'
|
|
78
|
+
require 'new_relic/agent/agent'
|
|
79
|
+
require 'new_relic/agent/shim_agent'
|
|
80
|
+
require 'new_relic/agent/method_tracer'
|
|
81
|
+
require 'new_relic/agent/worker_loop'
|
|
82
|
+
require 'new_relic/agent/stats_engine'
|
|
83
|
+
require 'new_relic/agent/transaction_sampler'
|
|
84
|
+
require 'new_relic/agent/sql_sampler'
|
|
85
|
+
require 'new_relic/agent/error_collector'
|
|
86
|
+
require 'new_relic/agent/busy_calculator'
|
|
87
|
+
require 'new_relic/agent/sampler'
|
|
88
|
+
require 'new_relic/agent/database'
|
|
89
|
+
|
|
90
|
+
require 'new_relic/agent/instrumentation/controller_instrumentation'
|
|
91
|
+
|
|
92
|
+
require 'new_relic/agent/samplers/cpu_sampler'
|
|
93
|
+
require 'new_relic/agent/samplers/memory_sampler'
|
|
94
|
+
require 'new_relic/agent/samplers/object_sampler'
|
|
95
|
+
require 'new_relic/agent/samplers/delayed_job_lock_sampler'
|
|
96
|
+
require 'set'
|
|
97
|
+
require 'thread'
|
|
98
|
+
require 'resolv'
|
|
99
|
+
|
|
100
|
+
# An exception that is thrown by the server if the agent license is invalid.
|
|
101
|
+
class LicenseException < StandardError; end
|
|
102
|
+
|
|
103
|
+
# An exception that forces an agent to stop reporting until its mongrel is restarted.
|
|
104
|
+
class ForceDisconnectException < StandardError; end
|
|
105
|
+
|
|
106
|
+
# An exception that forces an agent to restart.
|
|
107
|
+
class ForceRestartException < StandardError; end
|
|
108
|
+
|
|
109
|
+
# Used to blow out of a periodic task without logging a an error, such as for routine
|
|
110
|
+
# failures.
|
|
111
|
+
class ServerConnectionException < StandardError; end
|
|
112
|
+
|
|
113
|
+
# Used for when a transaction trace or error report has too much
|
|
114
|
+
# data, so we reset the queue to clear the extra-large item
|
|
115
|
+
class PostTooBigException < ServerConnectionException; end
|
|
116
|
+
|
|
117
|
+
# Reserved for future use. Meant to represent a problem on the server side.
|
|
118
|
+
class ServerError < StandardError; end
|
|
119
|
+
|
|
120
|
+
class BackgroundLoadingError < StandardError; end
|
|
121
|
+
|
|
122
|
+
@agent = nil
|
|
123
|
+
|
|
124
|
+
# The singleton Agent instance. Used internally.
|
|
125
|
+
def agent #:nodoc:
|
|
126
|
+
raise "Plugin not initialized!" if @agent.nil?
|
|
127
|
+
@agent
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def agent=(new_instance)#:nodoc:
|
|
131
|
+
@agent = new_instance
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
alias instance agent #:nodoc:
|
|
135
|
+
|
|
136
|
+
# Get or create a statistics gatherer that will aggregate numerical data
|
|
137
|
+
# under a metric name.
|
|
138
|
+
#
|
|
139
|
+
# +metric_name+ should follow a slash separated path convention. Application
|
|
140
|
+
# specific metrics should begin with "Custom/".
|
|
141
|
+
#
|
|
142
|
+
# Return a NewRelic::Stats that accepts data
|
|
143
|
+
# via calls to add_data_point(value).
|
|
144
|
+
def get_stats(metric_name, use_scope=false)
|
|
145
|
+
agent.stats_engine.get_stats(metric_name, use_scope)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
alias get_stats_no_scope get_stats
|
|
149
|
+
|
|
150
|
+
# Get the logger for the agent. Available after the agent has initialized.
|
|
151
|
+
# This sends output to the agent log file. If the agent has not initialized
|
|
152
|
+
# a standard output logger is returned.
|
|
153
|
+
def logger
|
|
154
|
+
control = NewRelic::Control.instance(false)
|
|
155
|
+
if control
|
|
156
|
+
control.log
|
|
157
|
+
else
|
|
158
|
+
require 'logger'
|
|
159
|
+
@stdoutlog ||= Logger.new $stdout
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Call this to manually start the Agent in situations where the Agent does
|
|
164
|
+
# not auto-start.
|
|
165
|
+
#
|
|
166
|
+
# When the app environment loads, so does the Agent. However, the
|
|
167
|
+
# Agent will only connect to the service if a web front-end is found. If
|
|
168
|
+
# you want to selectively monitor ruby processes that don't use
|
|
169
|
+
# web plugins, then call this method in your code and the Agent
|
|
170
|
+
# will fire up and start reporting to the service.
|
|
171
|
+
#
|
|
172
|
+
# Options are passed in as overrides for values in the
|
|
173
|
+
# newrelic.yml, such as app_name. In addition, the option +log+
|
|
174
|
+
# will take a logger that will be used instead of the standard
|
|
175
|
+
# file logger. The setting for the newrelic.yml section to use
|
|
176
|
+
# (ie, RAILS_ENV) can be overridden with an :env argument.
|
|
177
|
+
#
|
|
178
|
+
def manual_start(options={})
|
|
179
|
+
raise "Options must be a hash" unless Hash === options
|
|
180
|
+
NewRelic::Control.instance.init_plugin({ :agent_enabled => true, :sync_startup => true }.merge(options))
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# Register this method as a callback for processes that fork
|
|
184
|
+
# jobs.
|
|
185
|
+
#
|
|
186
|
+
# If the master/parent connects to the agent prior to forking the
|
|
187
|
+
# agent in the forked process will use that agent_run. Otherwise
|
|
188
|
+
# the forked process will establish a new connection with the
|
|
189
|
+
# server.
|
|
190
|
+
#
|
|
191
|
+
# Use this especially when you fork the process to run background
|
|
192
|
+
# jobs or other work. If you are doing this with a web dispatcher
|
|
193
|
+
# that forks worker processes then you will need to force the
|
|
194
|
+
# agent to reconnect, which it won't do by default. Passenger and
|
|
195
|
+
# Unicorn are already handled, nothing special needed for them.
|
|
196
|
+
#
|
|
197
|
+
# Options:
|
|
198
|
+
# * <tt>:force_reconnect => true</tt> to force the spawned process to
|
|
199
|
+
# establish a new connection, such as when forking a long running process.
|
|
200
|
+
# The default is false--it will only connect to the server if the parent
|
|
201
|
+
# had not connected.
|
|
202
|
+
# * <tt>:keep_retrying => false</tt> if we try to initiate a new
|
|
203
|
+
# connection, this tells me to only try it once so this method returns
|
|
204
|
+
# quickly if there is some kind of latency with the server.
|
|
205
|
+
def after_fork(options={})
|
|
206
|
+
agent.after_fork(options)
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
# Clear out any unsent metric data. See NewRelic::Agent::Agent#reset_stats
|
|
210
|
+
def reset_stats
|
|
211
|
+
agent.reset_stats
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Shutdown the agent. Call this before exiting. Sends any queued data
|
|
215
|
+
# and kills the background thread.
|
|
216
|
+
def shutdown(options={})
|
|
217
|
+
agent.shutdown(options)
|
|
218
|
+
end
|
|
219
|
+
|
|
220
|
+
# a method used to serialize short-running processes to disk, so
|
|
221
|
+
# we don't incur the overhead of reporting to the server for every
|
|
222
|
+
# fork/invocation of a small job.
|
|
223
|
+
#
|
|
224
|
+
# Functionally, this loads the data from the file into the agent
|
|
225
|
+
# (to avoid losing data by overwriting) and then serializes the
|
|
226
|
+
# agent data to the file again. See also #load_data
|
|
227
|
+
def save_data
|
|
228
|
+
NewRelic::DataSerialization.read_and_write_to_file do |old_data|
|
|
229
|
+
agent.merge_data_from(old_data)
|
|
230
|
+
agent.serialize
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
# used to load data from the disk during the harvest cycle to send
|
|
235
|
+
# it. This method also clears the file so data should never be
|
|
236
|
+
# sent more than once.
|
|
237
|
+
|
|
238
|
+
# Note that only one transaction trace will be sent even if many
|
|
239
|
+
# are serialized, since the slowest is sent.
|
|
240
|
+
#
|
|
241
|
+
# See also the complement to this method, #save_data - used when a
|
|
242
|
+
# process is shutting down
|
|
243
|
+
def load_data
|
|
244
|
+
if !NewRelic::Control.instance['disable_serialization']
|
|
245
|
+
NewRelic::DataSerialization.read_and_write_to_file do |old_data|
|
|
246
|
+
agent.merge_data_from(old_data)
|
|
247
|
+
nil # return nil so nothing is written to the file
|
|
248
|
+
end
|
|
249
|
+
NewRelic::DataSerialization.update_last_sent!
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
{
|
|
253
|
+
:metrics => agent.stats_engine.metrics.length,
|
|
254
|
+
:traces => agent.unsent_traces_size,
|
|
255
|
+
:errors => agent.unsent_errors_size
|
|
256
|
+
}
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# Add instrumentation files to the agent. The argument should be
|
|
260
|
+
# a glob matching ruby scripts which will be executed at the time
|
|
261
|
+
# instrumentation is loaded. Since instrumentation is not loaded
|
|
262
|
+
# when the agent is not running it's better to use this method to
|
|
263
|
+
# register instrumentation than just loading the files directly,
|
|
264
|
+
# although that probably also works.
|
|
265
|
+
def add_instrumentation(file_pattern)
|
|
266
|
+
NewRelic::Control.instance.add_instrumentation file_pattern
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# This method sets the block sent to this method as a sql
|
|
270
|
+
# obfuscator. The block will be called with a single String SQL
|
|
271
|
+
# statement to obfuscate. The method must return the obfuscated
|
|
272
|
+
# String SQL. If chaining of obfuscators is required, use type =
|
|
273
|
+
# :before or :after
|
|
274
|
+
#
|
|
275
|
+
# type = :before, :replace, :after
|
|
276
|
+
#
|
|
277
|
+
# Example:
|
|
278
|
+
#
|
|
279
|
+
# NewRelic::Agent.set_sql_obfuscator(:replace) do |sql|
|
|
280
|
+
# my_obfuscator(sql)
|
|
281
|
+
# end
|
|
282
|
+
#
|
|
283
|
+
def set_sql_obfuscator(type = :replace, &block)
|
|
284
|
+
NewRelic::Agent::Database.set_sql_obfuscator(type, &block)
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
# This method sets the state of sql recording in the transaction
|
|
289
|
+
# sampler feature. Within the given block, no sql will be recorded
|
|
290
|
+
#
|
|
291
|
+
# usage:
|
|
292
|
+
#
|
|
293
|
+
# NewRelic::Agent.disable_sql_recording do
|
|
294
|
+
# ...
|
|
295
|
+
# end
|
|
296
|
+
#
|
|
297
|
+
def disable_sql_recording
|
|
298
|
+
state = agent.set_record_sql(false)
|
|
299
|
+
begin
|
|
300
|
+
yield
|
|
301
|
+
ensure
|
|
302
|
+
agent.set_record_sql(state)
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# This method disables the recording of transaction traces in the given
|
|
307
|
+
# block. See also #disable_all_tracing
|
|
308
|
+
def disable_transaction_tracing
|
|
309
|
+
state = agent.set_record_tt(false)
|
|
310
|
+
begin
|
|
311
|
+
yield
|
|
312
|
+
ensure
|
|
313
|
+
agent.set_record_tt(state)
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
# Cancel the collection of the current transaction in progress, if
|
|
318
|
+
# any. Only affects the transaction started on this thread once
|
|
319
|
+
# it has started and before it has completed.
|
|
320
|
+
def abort_transaction!
|
|
321
|
+
NewRelic::Agent::Instrumentation::MetricFrame.abort_transaction!
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
# Yield to the block without collecting any metrics or traces in
|
|
325
|
+
# any of the subsequent calls. If executed recursively, will keep
|
|
326
|
+
# track of the first entry point and turn on tracing again after
|
|
327
|
+
# leaving that block. This uses the thread local
|
|
328
|
+
# +newrelic_untrace+
|
|
329
|
+
def disable_all_tracing
|
|
330
|
+
agent.push_trace_execution_flag(false)
|
|
331
|
+
yield
|
|
332
|
+
ensure
|
|
333
|
+
agent.pop_trace_execution_flag
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
# Check to see if we are capturing metrics currently on this thread.
|
|
337
|
+
def is_execution_traced?
|
|
338
|
+
Thread.current[:newrelic_untraced].nil? || Thread.current[:newrelic_untraced].last != false
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# helper method to check the thread local to determine whether the
|
|
342
|
+
# transaction in progress is traced or not
|
|
343
|
+
def is_transaction_traced?
|
|
344
|
+
Thread::current[:record_tt] != false
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
# helper method to check the thread local to determine whether sql
|
|
348
|
+
# is being recorded or not
|
|
349
|
+
def is_sql_recorded?
|
|
350
|
+
Thread::current[:record_sql] != false
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
# Set a filter to be applied to errors that the Ruby Agent will
|
|
354
|
+
# track. The block should evalute to the exception to track
|
|
355
|
+
# (which could be different from the original exception) or nil to
|
|
356
|
+
# ignore this exception.
|
|
357
|
+
#
|
|
358
|
+
# The block is yielded to with the exception to filter.
|
|
359
|
+
#
|
|
360
|
+
# Return the new block or the existing filter Proc if no block is passed.
|
|
361
|
+
#
|
|
362
|
+
def ignore_error_filter(&block)
|
|
363
|
+
agent.error_collector.ignore_error_filter(&block)
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
# Record the given error. It will be passed through the
|
|
367
|
+
# #ignore_error_filter if there is one.
|
|
368
|
+
#
|
|
369
|
+
# * <tt>exception</tt> is the exception which will be recorded. May also be
|
|
370
|
+
# an error message.
|
|
371
|
+
# Options:
|
|
372
|
+
# * <tt>:uri</tt> => The request path, minus any request params or query string.
|
|
373
|
+
# * <tt>:referer</tt> => The URI of the referer
|
|
374
|
+
# * <tt>:metric</tt> => The metric name associated with the transaction
|
|
375
|
+
# * <tt>:request_params</tt> => Request parameters, already filtered if necessary
|
|
376
|
+
# * <tt>:custom_params</tt> => Custom parameters
|
|
377
|
+
#
|
|
378
|
+
# Anything left over is treated as custom params.
|
|
379
|
+
#
|
|
380
|
+
def notice_error(exception, options={})
|
|
381
|
+
NewRelic::Agent::Instrumentation::MetricFrame.notice_error(exception, options)
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
# Add parameters to the current transaction trace (and traced error if any)
|
|
385
|
+
# on the call stack.
|
|
386
|
+
#
|
|
387
|
+
def add_custom_parameters(params)
|
|
388
|
+
NewRelic::Agent::Instrumentation::MetricFrame.add_custom_parameters(params)
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
# The #add_request_parameters method is aliased to #add_custom_parameters
|
|
392
|
+
# and is now deprecated.
|
|
393
|
+
alias add_request_parameters add_custom_parameters #:nodoc:
|
|
394
|
+
|
|
395
|
+
# Yield to a block that is run with a database metric name
|
|
396
|
+
# context. This means the Database instrumentation will use this
|
|
397
|
+
# for the metric name if it does not otherwise know about a model.
|
|
398
|
+
# This is re-entrant.
|
|
399
|
+
#
|
|
400
|
+
# * <tt>model</tt> is the DB model class
|
|
401
|
+
# * <tt>method</tt> is the name of the finder method or other
|
|
402
|
+
# method to identify the operation with.
|
|
403
|
+
def with_database_metric_name(model, method, &block)
|
|
404
|
+
if frame = NewRelic::Agent::Instrumentation::MetricFrame.current
|
|
405
|
+
frame.with_database_metric_name(model, method, &block)
|
|
406
|
+
else
|
|
407
|
+
yield
|
|
408
|
+
end
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
# Record a web transaction from an external source. This will
|
|
412
|
+
# process the response time, error, and score an apdex value.
|
|
413
|
+
#
|
|
414
|
+
# First argument is a float value, time in seconds. Option
|
|
415
|
+
# keys are strings.
|
|
416
|
+
#
|
|
417
|
+
# == Identifying the transaction
|
|
418
|
+
# * <tt>'uri' => uri</tt> to record the value for a given web request.
|
|
419
|
+
# If not provided, just record the aggregate dispatcher and apdex scores.
|
|
420
|
+
# * <tt>'metric' => metric_name</tt> to record with a general metric name
|
|
421
|
+
# like +OtherTransaction/Background/Class/method+. Ignored if +uri+ is
|
|
422
|
+
# provided.
|
|
423
|
+
#
|
|
424
|
+
# == Error options
|
|
425
|
+
# Provide one of the following:
|
|
426
|
+
# * <tt>'is_error' => true</tt> if an unknown error occurred
|
|
427
|
+
# * <tt>'error_message' => msg</tt> if an error message is available
|
|
428
|
+
# * <tt>'exception' => exception</tt> if a ruby exception is recorded
|
|
429
|
+
#
|
|
430
|
+
# == Misc options
|
|
431
|
+
# Additional information captured in errors
|
|
432
|
+
# * <tt>'referer' => referer_url</tt>
|
|
433
|
+
# * <tt>'request_params' => hash</tt> to record a set of name/value pairs as the
|
|
434
|
+
# request parameters.
|
|
435
|
+
# * <tt>'custom_params' => hash</tt> to record extra information in traced errors
|
|
436
|
+
#
|
|
437
|
+
def record_transaction(response_sec, options = {})
|
|
438
|
+
agent.record_transaction(response_sec, options)
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
# Returns a Javascript string which should be injected into the very top of the response body
|
|
442
|
+
#
|
|
443
|
+
def browser_timing_header
|
|
444
|
+
agent.browser_timing_header
|
|
445
|
+
end
|
|
446
|
+
|
|
447
|
+
# Returns a Javascript string which should be injected into the very bottom of the response body
|
|
448
|
+
#
|
|
449
|
+
def browser_timing_footer
|
|
450
|
+
agent.browser_timing_footer
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
end
|
|
454
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
require 'new_relic/control'
|
|
2
|
+
|
|
3
|
+
module NewRelic
|
|
4
|
+
module CollectionHelper
|
|
5
|
+
DEFAULT_TRUNCATION_SIZE=16 * 1024
|
|
6
|
+
DEFAULT_ARRAY_TRUNCATION_SIZE=128
|
|
7
|
+
# Transform parameter hash into a hash whose values are strictly
|
|
8
|
+
# strings
|
|
9
|
+
def normalize_params(params)
|
|
10
|
+
case params
|
|
11
|
+
when Symbol, FalseClass, TrueClass, nil
|
|
12
|
+
params
|
|
13
|
+
when Numeric
|
|
14
|
+
truncate(params.to_s)
|
|
15
|
+
when String
|
|
16
|
+
truncate(params)
|
|
17
|
+
when Hash
|
|
18
|
+
new_params = {}
|
|
19
|
+
params.each do | key, value |
|
|
20
|
+
new_params[truncate(normalize_params(key),64)] = normalize_params(value)
|
|
21
|
+
end
|
|
22
|
+
new_params
|
|
23
|
+
when Array
|
|
24
|
+
params.first(DEFAULT_ARRAY_TRUNCATION_SIZE).map{|item| normalize_params(item)}
|
|
25
|
+
else
|
|
26
|
+
truncate(flatten(params))
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Return an array of strings (backtrace), cleaned up for readability
|
|
31
|
+
# Return nil if there is no backtrace
|
|
32
|
+
|
|
33
|
+
def strip_nr_from_backtrace(backtrace)
|
|
34
|
+
if backtrace && !NewRelic::Control.instance.disable_backtrace_cleanup?
|
|
35
|
+
# this is for 1.9.1, where strings no longer have Enumerable
|
|
36
|
+
backtrace = backtrace.split("\n") if String === backtrace
|
|
37
|
+
backtrace = backtrace.map &:to_s
|
|
38
|
+
backtrace = backtrace.reject do |line|
|
|
39
|
+
line.include?(NewRelic::Control.newrelic_root) or
|
|
40
|
+
line =~ /^newrelic_rpm\s/
|
|
41
|
+
end
|
|
42
|
+
# rename methods back to their original state
|
|
43
|
+
backtrace = backtrace.collect {|line| line.gsub(/_without_(newrelic|trace)/, "")}
|
|
44
|
+
end
|
|
45
|
+
backtrace
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
# Convert any kind of object to a short string.
|
|
51
|
+
def flatten(object)
|
|
52
|
+
s = case object
|
|
53
|
+
when nil then ''
|
|
54
|
+
when object.instance_of?(String) then object
|
|
55
|
+
when String then String.new(object) # convert string subclasses to strings
|
|
56
|
+
else "#<#{object.class.to_s}>"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
def truncate(string, len=DEFAULT_TRUNCATION_SIZE)
|
|
60
|
+
case string
|
|
61
|
+
when Symbol then string
|
|
62
|
+
when nil then ""
|
|
63
|
+
when String
|
|
64
|
+
real_string = flatten(string)
|
|
65
|
+
if real_string.size > len
|
|
66
|
+
real_string = real_string.slice(0...len)
|
|
67
|
+
real_string << "..."
|
|
68
|
+
end
|
|
69
|
+
real_string
|
|
70
|
+
else
|
|
71
|
+
truncate(flatten(string), len)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
require 'optparse'
|
|
2
|
+
|
|
3
|
+
# Run the command given by the first argument. Right
|
|
4
|
+
# now all we have is deployments. We hope to have other
|
|
5
|
+
# kinds of events here later.
|
|
6
|
+
$LOAD_PATH << "#{File.dirname(__FILE__)}/.."
|
|
7
|
+
module NewRelic
|
|
8
|
+
class Command
|
|
9
|
+
attr_accessor :leftover
|
|
10
|
+
# Capture a failure to execute the command.
|
|
11
|
+
class CommandFailure < StandardError
|
|
12
|
+
attr_reader :options
|
|
13
|
+
def initialize message, opt_parser=nil
|
|
14
|
+
super message
|
|
15
|
+
@options = opt_parser
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def info(message)
|
|
20
|
+
STDOUT.puts message
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def err(message)
|
|
24
|
+
STDERR.puts message
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def initialize(command_line_args)
|
|
28
|
+
if Hash === command_line_args
|
|
29
|
+
# command line args is an options hash
|
|
30
|
+
command_line_args.each do | key, value |
|
|
31
|
+
instance_variable_set "@#{key}", value.to_s if value
|
|
32
|
+
end
|
|
33
|
+
else
|
|
34
|
+
# parse command line args. Throw an exception on a bad arg.
|
|
35
|
+
@options = options do | opts |
|
|
36
|
+
opts.on("-h", "Show this help") { raise CommandFailure, opts.to_s }
|
|
37
|
+
end
|
|
38
|
+
@leftover = @options.parse(command_line_args)
|
|
39
|
+
end
|
|
40
|
+
rescue OptionParser::ParseError => e
|
|
41
|
+
raise CommandFailure.new e.message, @options
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
@commands = []
|
|
45
|
+
def self.inherited(subclass)
|
|
46
|
+
@commands << subclass
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
cmds = File.expand_path(File.join(File.dirname(__FILE__), 'commands', '*.rb'))
|
|
50
|
+
Dir[cmds].each{|command| require command }
|
|
51
|
+
|
|
52
|
+
def self.run
|
|
53
|
+
|
|
54
|
+
@command_names = @commands.map{ |c| c.command }
|
|
55
|
+
|
|
56
|
+
extra = []
|
|
57
|
+
options = ARGV.options do |opts|
|
|
58
|
+
script_name = File.basename($0)
|
|
59
|
+
if script_name =~ /newrelic_cmd$/
|
|
60
|
+
$stdout.puts "warning: the 'newrelic_cmd' script has been renamed 'newrelic'"
|
|
61
|
+
script_name = 'newrelic'
|
|
62
|
+
end
|
|
63
|
+
opts.banner = "Usage: #{script_name} [ #{ @command_names.join(" | ")} ] [options]"
|
|
64
|
+
opts.separator "use '#{script_name} <command> -h' to see detailed command options"
|
|
65
|
+
opts
|
|
66
|
+
end
|
|
67
|
+
extra = options.order!
|
|
68
|
+
command = extra.shift
|
|
69
|
+
# just make it a little easier on them
|
|
70
|
+
command = 'deployments' if command =~ /deploy/
|
|
71
|
+
if command.nil?
|
|
72
|
+
STDERR.puts options
|
|
73
|
+
elsif !@command_names.include?(command)
|
|
74
|
+
STDERR.puts "Unrecognized command: #{command}"
|
|
75
|
+
STDERR.puts options
|
|
76
|
+
else
|
|
77
|
+
command_class = @commands.find{ |c| c.command == command}
|
|
78
|
+
command_class.new(extra).run
|
|
79
|
+
end
|
|
80
|
+
rescue OptionParser::InvalidOption => e
|
|
81
|
+
raise NewRelic::Command::CommandFailure, e.message
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
end
|