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,201 @@
|
|
|
1
|
+
require 'new_relic/transaction_sample'
|
|
2
|
+
module NewRelic
|
|
3
|
+
class TransactionSample
|
|
4
|
+
class Segment
|
|
5
|
+
attr_reader :entry_timestamp
|
|
6
|
+
# The exit timestamp will be relative except for the outermost sample which will
|
|
7
|
+
# have a timestamp.
|
|
8
|
+
attr_reader :exit_timestamp
|
|
9
|
+
attr_reader :parent_segment
|
|
10
|
+
attr_reader :metric_name
|
|
11
|
+
attr_reader :segment_id
|
|
12
|
+
|
|
13
|
+
def initialize(timestamp, metric_name, segment_id)
|
|
14
|
+
@entry_timestamp = timestamp
|
|
15
|
+
@metric_name = metric_name || '<unknown>'
|
|
16
|
+
@segment_id = segment_id || object_id
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# sets the final timestamp on a segment to indicate the exit
|
|
20
|
+
# point of the segment
|
|
21
|
+
def end_trace(timestamp)
|
|
22
|
+
@exit_timestamp = timestamp
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def add_called_segment(s)
|
|
26
|
+
@called_segments ||= []
|
|
27
|
+
@called_segments << s
|
|
28
|
+
s.parent_segment = self
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def to_s
|
|
32
|
+
to_debug_str(0)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def to_json(options={})
|
|
36
|
+
hash = {
|
|
37
|
+
:entry_timestamp => @entry_timestamp,
|
|
38
|
+
:exit_timestamp => @exit_timestamp,
|
|
39
|
+
:metric_name => @metric_name,
|
|
40
|
+
:segment_id => @segment_id,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
hash[:called_segments] = called_segments if !called_segments.empty?
|
|
44
|
+
hash[:params] = @params if @params && !@params.empty?
|
|
45
|
+
|
|
46
|
+
hash.to_json
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def path_string
|
|
50
|
+
"#{metric_name}[#{called_segments.collect {|segment| segment.path_string }.join('')}]"
|
|
51
|
+
end
|
|
52
|
+
def to_s_compact
|
|
53
|
+
str = ""
|
|
54
|
+
str << metric_name
|
|
55
|
+
if called_segments.any?
|
|
56
|
+
str << "{#{called_segments.map { | cs | cs.to_s_compact }.join(",")}}"
|
|
57
|
+
end
|
|
58
|
+
str
|
|
59
|
+
end
|
|
60
|
+
def to_debug_str(depth)
|
|
61
|
+
tab = " " * depth
|
|
62
|
+
s = tab.clone
|
|
63
|
+
s << ">> #{'%3i ms' % (@entry_timestamp*1000)} [#{self.class.name.split("::").last}] #{metric_name} \n"
|
|
64
|
+
unless params.empty?
|
|
65
|
+
params.each do |k,v|
|
|
66
|
+
s << "#{tab} -#{'%-16s' % k}: #{v.to_s[0..80]}\n"
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
called_segments.each do |cs|
|
|
70
|
+
s << cs.to_debug_str(depth + 1)
|
|
71
|
+
end
|
|
72
|
+
s << tab + "<< "
|
|
73
|
+
s << case @exit_timestamp
|
|
74
|
+
when nil then ' n/a'
|
|
75
|
+
when Numeric then '%3i ms' % (@exit_timestamp*1000)
|
|
76
|
+
else @exit_timestamp.to_s
|
|
77
|
+
end
|
|
78
|
+
s << " #{metric_name}\n"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def called_segments
|
|
82
|
+
@called_segments || []
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# return the total duration of this segment
|
|
86
|
+
def duration
|
|
87
|
+
(@exit_timestamp - @entry_timestamp).to_f
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# return the duration of this segment without
|
|
91
|
+
# including the time in the called segments
|
|
92
|
+
def exclusive_duration
|
|
93
|
+
d = duration
|
|
94
|
+
|
|
95
|
+
called_segments.each do |segment|
|
|
96
|
+
d -= segment.duration
|
|
97
|
+
end
|
|
98
|
+
d
|
|
99
|
+
end
|
|
100
|
+
def count_segments
|
|
101
|
+
count = 1
|
|
102
|
+
called_segments.each { | seg | count += seg.count_segments }
|
|
103
|
+
count
|
|
104
|
+
end
|
|
105
|
+
# Walk through the tree and truncate the segments in a
|
|
106
|
+
# depth-first manner
|
|
107
|
+
def truncate(max)
|
|
108
|
+
return 1 unless @called_segments
|
|
109
|
+
total, self.called_segments = truncate_each_child(max - 1)
|
|
110
|
+
total+1
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def truncate_each_child(max)
|
|
114
|
+
total = 0
|
|
115
|
+
accumulator = []
|
|
116
|
+
called_segments.each { | s |
|
|
117
|
+
if total == max
|
|
118
|
+
true
|
|
119
|
+
else
|
|
120
|
+
total += s.truncate(max - total)
|
|
121
|
+
accumulator << s
|
|
122
|
+
end
|
|
123
|
+
}
|
|
124
|
+
total
|
|
125
|
+
[total, accumulator]
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def []=(key, value)
|
|
129
|
+
# only create a parameters field if a parameter is set; this will save
|
|
130
|
+
# bandwidth etc as most segments have no parameters
|
|
131
|
+
params[key] = value
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def [](key)
|
|
135
|
+
params[key]
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def params
|
|
139
|
+
@params ||= {}
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# call the provided block for this segment and each
|
|
143
|
+
# of the called segments
|
|
144
|
+
def each_segment(&block)
|
|
145
|
+
block.call self
|
|
146
|
+
|
|
147
|
+
if @called_segments
|
|
148
|
+
@called_segments.each do |segment|
|
|
149
|
+
segment.each_segment(&block)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# call the provided block for this segment and each
|
|
155
|
+
# of the called segments while keeping track of nested segments
|
|
156
|
+
def each_segment_with_nest_tracking(&block)
|
|
157
|
+
summary = block.call self
|
|
158
|
+
summary.current_nest_count += 1 if summary
|
|
159
|
+
|
|
160
|
+
if @called_segments
|
|
161
|
+
@called_segments.each do |segment|
|
|
162
|
+
segment.each_segment_with_nest_tracking(&block)
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
summary.current_nest_count -= 1 if summary
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def find_segment(id)
|
|
170
|
+
return self if @segment_id == id
|
|
171
|
+
called_segments.each do |segment|
|
|
172
|
+
found = segment.find_segment(id)
|
|
173
|
+
return found if found
|
|
174
|
+
end
|
|
175
|
+
nil
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def explain_sql
|
|
179
|
+
NewRelic::Agent::Database.explain_sql(params[:sql],
|
|
180
|
+
params[:connection_config])
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def obfuscated_sql
|
|
184
|
+
NewRelic::Agent::Database.obfuscate_sql(params[:sql])
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def params=(p)
|
|
188
|
+
@params = p
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def called_segments=(segments)
|
|
192
|
+
@called_segments = segments
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
protected
|
|
196
|
+
def parent_segment=(s)
|
|
197
|
+
@parent_segment = s
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'new_relic/transaction_sample'
|
|
2
|
+
require 'new_relic/transaction_sample/segment'
|
|
3
|
+
module NewRelic
|
|
4
|
+
class TransactionSample
|
|
5
|
+
class SummarySegment < Segment
|
|
6
|
+
def initialize(segment)
|
|
7
|
+
super segment.entry_timestamp, segment.metric_name, nil
|
|
8
|
+
|
|
9
|
+
add_segments segment.called_segments
|
|
10
|
+
|
|
11
|
+
end_trace segment.exit_timestamp
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def add_segments(segments)
|
|
15
|
+
segments.collect do |segment|
|
|
16
|
+
SummarySegment.new(segment)
|
|
17
|
+
end.each {|segment| add_called_segment(segment)}
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
require 'new_relic/transaction_sample/segment'
|
|
2
|
+
require 'new_relic/transaction_sample/summary_segment'
|
|
3
|
+
require 'new_relic/transaction_sample/fake_segment'
|
|
4
|
+
require 'new_relic/transaction_sample/composite_segment'
|
|
5
|
+
module NewRelic
|
|
6
|
+
# the number of segments that need to exist before we roll them up
|
|
7
|
+
# into one segment with multiple executions
|
|
8
|
+
COLLAPSE_SEGMENTS_THRESHOLD = 2
|
|
9
|
+
|
|
10
|
+
class TransactionSample
|
|
11
|
+
|
|
12
|
+
attr_accessor :params, :root_segment
|
|
13
|
+
attr_accessor :profile
|
|
14
|
+
attr_reader :root_segment
|
|
15
|
+
attr_reader :params
|
|
16
|
+
attr_reader :sample_id
|
|
17
|
+
|
|
18
|
+
@@start_time = Time.now
|
|
19
|
+
|
|
20
|
+
include TransactionAnalysis
|
|
21
|
+
|
|
22
|
+
def initialize(time = Time.now.to_f, sample_id = nil)
|
|
23
|
+
@sample_id = sample_id || object_id
|
|
24
|
+
@start_time = time
|
|
25
|
+
@root_segment = create_segment 0.0, "ROOT"
|
|
26
|
+
@params = {}
|
|
27
|
+
@params[:request_params] = {}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def count_segments
|
|
31
|
+
@root_segment.count_segments - 1 # don't count the root segment
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Truncates the transaction sample to a maximum length determined
|
|
35
|
+
# by the passed-in parameter. Operates recursively on the entire
|
|
36
|
+
# tree of transaction segments in a depth-first manner
|
|
37
|
+
def truncate(max)
|
|
38
|
+
count = count_segments
|
|
39
|
+
return if count < max
|
|
40
|
+
@root_segment.truncate(max + 1)
|
|
41
|
+
|
|
42
|
+
ensure_segment_count_set(count)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# makes sure that the parameter cache for segment count is set to
|
|
46
|
+
# the correct value
|
|
47
|
+
def ensure_segment_count_set(count)
|
|
48
|
+
params[:segment_count] ||= count
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# offset from start of app
|
|
52
|
+
def timestamp
|
|
53
|
+
@start_time - @@start_time.to_f
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Used in the server only
|
|
57
|
+
def to_json(options = {}) #:nodoc:
|
|
58
|
+
map = {:sample_id => @sample_id,
|
|
59
|
+
:start_time => @start_time,
|
|
60
|
+
:root_segment => @root_segment}
|
|
61
|
+
if @params && !@params.empty?
|
|
62
|
+
map[:params] = @params
|
|
63
|
+
end
|
|
64
|
+
map.to_json
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def start_time
|
|
68
|
+
Time.at(@start_time)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def path_string
|
|
72
|
+
@root_segment.path_string
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def create_segment(relative_timestamp, metric_name, segment_id = nil)
|
|
76
|
+
raise TypeError.new("Frozen Transaction Sample") if frozen?
|
|
77
|
+
NewRelic::TransactionSample::Segment.new(relative_timestamp, metric_name, segment_id)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def duration
|
|
81
|
+
root_segment.duration
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Iterates recursively over each segment in the entire transaction
|
|
85
|
+
# sample tree
|
|
86
|
+
def each_segment(&block)
|
|
87
|
+
@root_segment.each_segment(&block)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
# Iterates recursively over each segment in the entire transaction
|
|
91
|
+
# sample tree while keeping track of nested segments
|
|
92
|
+
def each_segment_with_nest_tracking(&block)
|
|
93
|
+
@root_segment.each_segment_with_nest_tracking(&block)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def to_s_compact
|
|
97
|
+
@root_segment.to_s_compact
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Searches the tree recursively for the segment with the given
|
|
101
|
+
# id. note that this is an internal id, not an ActiveRecord id
|
|
102
|
+
def find_segment(id)
|
|
103
|
+
@root_segment.find_segment(id)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def to_s
|
|
107
|
+
s = "Transaction Sample collected at #{start_time}\n"
|
|
108
|
+
s << " {\n"
|
|
109
|
+
s << " Path: #{params[:path]} \n"
|
|
110
|
+
|
|
111
|
+
params.each do |k,v|
|
|
112
|
+
next if k == :path
|
|
113
|
+
s << " #{k}: " <<
|
|
114
|
+
case v
|
|
115
|
+
when Enumerable then v.map(&:to_s).sort.join("; ")
|
|
116
|
+
when String then v
|
|
117
|
+
when Float then '%6.3s' % v
|
|
118
|
+
when nil then ''
|
|
119
|
+
else
|
|
120
|
+
raise "unexpected value type for #{k}: '#{v}' (#{v.class})"
|
|
121
|
+
end << "\n"
|
|
122
|
+
end
|
|
123
|
+
s << " }\n\n"
|
|
124
|
+
s << @root_segment.to_debug_str(0)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# return a new transaction sample that treats segments
|
|
128
|
+
# with the given regular expression in their name as if they
|
|
129
|
+
# were never called at all. This allows us to strip out segments
|
|
130
|
+
# from traces captured in development environment that would not
|
|
131
|
+
# normally show up in production (like Rails/Application Code Loading)
|
|
132
|
+
def omit_segments_with(regex)
|
|
133
|
+
regex = Regexp.new(regex)
|
|
134
|
+
|
|
135
|
+
sample = TransactionSample.new(@start_time, sample_id)
|
|
136
|
+
|
|
137
|
+
params.each {|k,v| sample.params[k] = v}
|
|
138
|
+
|
|
139
|
+
delta = build_segment_with_omissions(sample, 0.0, @root_segment, sample.root_segment, regex)
|
|
140
|
+
sample.root_segment.end_trace(@root_segment.exit_timestamp - delta)
|
|
141
|
+
sample.profile = self.profile
|
|
142
|
+
sample
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Return a new transaction sample that can be sent to the New
|
|
146
|
+
# Relic service. This involves potentially one or more of the
|
|
147
|
+
# following options
|
|
148
|
+
#
|
|
149
|
+
# :explain_sql : run EXPLAIN on all queries whose response times equal the value for this key
|
|
150
|
+
# (for example :explain_sql => 2.0 would explain everything over 2 seconds. 0.0 would explain everything.)
|
|
151
|
+
# :keep_backtraces : keep backtraces, significantly increasing size of trace (off by default)
|
|
152
|
+
# :record_sql => [ :raw | :obfuscated] : copy over the sql, obfuscating if necessary
|
|
153
|
+
def prepare_to_send(options={})
|
|
154
|
+
sample = TransactionSample.new(@start_time, sample_id)
|
|
155
|
+
|
|
156
|
+
sample.params.merge! self.params
|
|
157
|
+
|
|
158
|
+
begin
|
|
159
|
+
build_segment_for_transfer(sample, @root_segment, sample.root_segment, options)
|
|
160
|
+
ensure
|
|
161
|
+
NewRelic::Agent::Database.close_connections
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
sample.root_segment.end_trace(@root_segment.exit_timestamp)
|
|
165
|
+
sample
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
def params=(params)
|
|
169
|
+
@params = params
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
private
|
|
173
|
+
|
|
174
|
+
# This is badly in need of refactoring
|
|
175
|
+
def build_segment_with_omissions(new_sample, time_delta, source_segment, target_segment, regex)
|
|
176
|
+
source_segment.called_segments.each do |source_called_segment|
|
|
177
|
+
# if this segment's metric name matches the given regular expression, bail
|
|
178
|
+
# here and increase the amount of time that we reduce the target sample with
|
|
179
|
+
# by this omitted segment's duration.
|
|
180
|
+
do_omit = regex =~ source_called_segment.metric_name
|
|
181
|
+
|
|
182
|
+
if do_omit
|
|
183
|
+
time_delta += source_called_segment.duration
|
|
184
|
+
else
|
|
185
|
+
target_called_segment = new_sample.create_segment(
|
|
186
|
+
source_called_segment.entry_timestamp - time_delta,
|
|
187
|
+
source_called_segment.metric_name,
|
|
188
|
+
source_called_segment.segment_id)
|
|
189
|
+
|
|
190
|
+
target_segment.add_called_segment target_called_segment
|
|
191
|
+
source_called_segment.params.each do |k,v|
|
|
192
|
+
target_called_segment[k]=v
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
time_delta = build_segment_with_omissions(
|
|
196
|
+
new_sample, time_delta, source_called_segment, target_called_segment, regex)
|
|
197
|
+
target_called_segment.end_trace(source_called_segment.exit_timestamp - time_delta)
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
return time_delta
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
# see prepare_to_send for what we do with options
|
|
205
|
+
#
|
|
206
|
+
# This is badly in need of refactoring
|
|
207
|
+
def build_segment_for_transfer(new_sample, source_segment, target_segment, options)
|
|
208
|
+
source_segment.called_segments.each do |source_called_segment|
|
|
209
|
+
target_called_segment = new_sample.create_segment(
|
|
210
|
+
source_called_segment.entry_timestamp,
|
|
211
|
+
source_called_segment.metric_name,
|
|
212
|
+
source_called_segment.segment_id)
|
|
213
|
+
|
|
214
|
+
target_segment.add_called_segment target_called_segment
|
|
215
|
+
source_called_segment.params.each do |k,v|
|
|
216
|
+
case k
|
|
217
|
+
when :backtrace
|
|
218
|
+
target_called_segment[k]=v if options[:keep_backtraces]
|
|
219
|
+
when :sql
|
|
220
|
+
# run an EXPLAIN on this sql if specified.
|
|
221
|
+
if options[:record_sql] && options[:record_sql] &&
|
|
222
|
+
options[:explain_sql] &&
|
|
223
|
+
source_called_segment.duration > options[:explain_sql].to_f
|
|
224
|
+
target_called_segment[:explain_plan] = source_called_segment.explain_sql
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
target_called_segment[:sql] = case options[:record_sql]
|
|
228
|
+
when :raw then v
|
|
229
|
+
when :obfuscated then NewRelic::Agent::Database.obfuscate_sql(v)
|
|
230
|
+
else raise "Invalid value for record_sql: #{options[:record_sql]}"
|
|
231
|
+
end if options[:record_sql]
|
|
232
|
+
when :connection_config
|
|
233
|
+
# don't copy it
|
|
234
|
+
else
|
|
235
|
+
target_called_segment[k]=v
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
build_segment_for_transfer(new_sample, source_called_segment, target_called_segment, options)
|
|
240
|
+
target_called_segment.end_trace(source_called_segment.exit_timestamp)
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
end
|
|
245
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Represents url mapping rules stored on the server. These rules should be applied
|
|
2
|
+
# to URLs which are not normalized into controller class/action by Rails routes.
|
|
3
|
+
# Insantiated strictly by Marshal.
|
|
4
|
+
class NewRelic::UrlRule
|
|
5
|
+
attr_reader :match_expression, :replacement, :eval_order, :terminate_chain
|
|
6
|
+
|
|
7
|
+
def apply url
|
|
8
|
+
return nil
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
class RuleSet
|
|
12
|
+
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
#!/usr/bin/ruby
|
|
2
|
+
module NewRelic
|
|
3
|
+
module VERSION #:nodoc:
|
|
4
|
+
MAJOR = 3
|
|
5
|
+
MINOR = 2
|
|
6
|
+
TINY = 0
|
|
7
|
+
BUILD = 2 #'0' # Set to nil for a release, 'beta1', 'alpha', etc for prerelease builds
|
|
8
|
+
STRING = [MAJOR, MINOR, TINY, BUILD].compact.join('.')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# Helper class for managing version comparisons
|
|
12
|
+
class VersionNumber
|
|
13
|
+
attr_reader :parts
|
|
14
|
+
include Comparable
|
|
15
|
+
def initialize(version_string)
|
|
16
|
+
version_string ||= '1.0.0'
|
|
17
|
+
@parts = version_string.split('.').map{|n| n =~ /^\d+$/ ? n.to_i : n}
|
|
18
|
+
end
|
|
19
|
+
def major_version; @parts[0]; end
|
|
20
|
+
def minor_version; @parts[1]; end
|
|
21
|
+
def tiny_version; @parts[2]; end
|
|
22
|
+
|
|
23
|
+
def <=>(other)
|
|
24
|
+
other = self.class.new(other) if other.is_a? String
|
|
25
|
+
self.class.compare(self.parts, other.parts)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def to_s
|
|
29
|
+
@parts.join(".")
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def hash
|
|
33
|
+
@parts.hash
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def eql? other
|
|
37
|
+
(self <=> other) == 0
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
def self.compare(parts1, parts2)
|
|
42
|
+
a, b = parts1.first, parts2.first
|
|
43
|
+
case
|
|
44
|
+
when a.nil? && b.nil? then 0
|
|
45
|
+
when a.nil? then b.is_a?(Fixnum) ? -1 : 1
|
|
46
|
+
when b.nil? then -compare(parts2, parts1)
|
|
47
|
+
when a.to_s == b.to_s then compare(parts1[1..-1], parts2[1..-1])
|
|
48
|
+
when a.is_a?(String) then b.is_a?(Fixnum) ? -1 : (a <=> b)
|
|
49
|
+
when b.is_a?(String) then -compare(parts2, parts1)
|
|
50
|
+
else # they are both fixnums, not nil
|
|
51
|
+
a <=> b
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
data/lib/newrelic_rpm.rb
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# == New Relic Initialization
|
|
2
|
+
#
|
|
3
|
+
# When installed as a gem, you can activate the New Relic agent one of the following ways:
|
|
4
|
+
#
|
|
5
|
+
# For Rails, add:
|
|
6
|
+
# config.gem 'newrelic_rpm'
|
|
7
|
+
# to your initialization sequence.
|
|
8
|
+
#
|
|
9
|
+
# For merb, do
|
|
10
|
+
# dependency 'newrelic_rpm'
|
|
11
|
+
# in the Merb config/init.rb
|
|
12
|
+
#
|
|
13
|
+
# For Sinatra, do
|
|
14
|
+
# require 'newrelic_rpm'
|
|
15
|
+
# after requiring 'sinatra'.
|
|
16
|
+
#
|
|
17
|
+
# For other frameworks, or to manage the agent manually, invoke NewRelic::Agent#manual_start
|
|
18
|
+
# directly.
|
|
19
|
+
#
|
|
20
|
+
require 'new_relic/control'
|
|
21
|
+
if defined?(Merb) && defined?(Merb::BootLoader)
|
|
22
|
+
module NewRelic
|
|
23
|
+
class MerbBootLoader < Merb::BootLoader
|
|
24
|
+
after Merb::BootLoader::ChooseAdapter
|
|
25
|
+
def self.run
|
|
26
|
+
NewRelic::Control.instance.init_plugin
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
elsif defined? Rails
|
|
31
|
+
if Rails.respond_to?(:version) && Rails.version =~ /^3/
|
|
32
|
+
module NewRelic
|
|
33
|
+
class Railtie < Rails::Railtie
|
|
34
|
+
|
|
35
|
+
initializer "newrelic_rpm.start_plugin" do |app|
|
|
36
|
+
NewRelic::Control.instance.init_plugin(:config => app.config)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
else
|
|
41
|
+
# After verison 2.0 of Rails we can access the configuration directly.
|
|
42
|
+
# We need it to add dev mode routes after initialization finished.
|
|
43
|
+
config = nil
|
|
44
|
+
config = Rails.configuration if Rails.respond_to?(:configuration)
|
|
45
|
+
NewRelic::Control.instance.init_plugin :config => config
|
|
46
|
+
end
|
|
47
|
+
else
|
|
48
|
+
NewRelic::Control.instance.init_plugin
|
|
49
|
+
end
|
data/lib/tasks/all.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# run unit tests for the NewRelic Agent
|
|
2
|
+
begin
|
|
3
|
+
require 'rake/test_task'
|
|
4
|
+
rescue LoadError => e
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
if defined? Rake::TestTask
|
|
8
|
+
namespace :test do
|
|
9
|
+
AGENT_HOME = File.expand_path(File.join(File.dirname(__FILE__), "..",".."))
|
|
10
|
+
Rake::TestTask.new(:newrelic) do |t|
|
|
11
|
+
t.libs << "#{AGENT_HOME}/test"
|
|
12
|
+
t.libs << "#{AGENT_HOME}/lib"
|
|
13
|
+
t.pattern = "#{AGENT_HOME}/test/**/*_test.rb"
|
|
14
|
+
t.verbose = true
|
|
15
|
+
end
|
|
16
|
+
Rake::Task['test:newrelic'].comment = "Run the unit tests for the Agent"
|
|
17
|
+
task :newrelic => :environment
|
|
18
|
+
end
|
|
19
|
+
end
|