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,50 @@
|
|
|
1
|
+
# A Sampler is used to capture meaningful metrics in a background thread
|
|
2
|
+
# periodically. They will either be invoked once a minute just before the
|
|
3
|
+
# data is sent to the agent (default) or every 10 seconds, when #use_harvest_sampler?
|
|
4
|
+
# returns false.
|
|
5
|
+
#
|
|
6
|
+
# Samplers can be added to New Relic by subclassing NewRelic::Agent::Sampler.
|
|
7
|
+
# Instances are created when the agent is enabled and installed. Subclasses
|
|
8
|
+
# are registered for instantiation automatically.
|
|
9
|
+
module NewRelic
|
|
10
|
+
module Agent
|
|
11
|
+
class Sampler
|
|
12
|
+
|
|
13
|
+
# Exception denotes a sampler is not available and it will not be registered.
|
|
14
|
+
class Unsupported < StandardError; end
|
|
15
|
+
|
|
16
|
+
attr_accessor :stats_engine
|
|
17
|
+
attr_reader :id
|
|
18
|
+
@sampler_classes = []
|
|
19
|
+
|
|
20
|
+
def self.inherited(subclass)
|
|
21
|
+
@sampler_classes << subclass
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Override with check. Called before instantiating.
|
|
25
|
+
def self.supported_on_this_platform?
|
|
26
|
+
true
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Override to use the periodic sampler instead of running the sampler on the
|
|
30
|
+
# minute during harvests.
|
|
31
|
+
def self.use_harvest_sampler?
|
|
32
|
+
true
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.sampler_classes
|
|
36
|
+
@sampler_classes
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def initialize(id)
|
|
40
|
+
@id = id
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def poll
|
|
44
|
+
raise "Implement in the subclass"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'new_relic/agent/sampler'
|
|
2
|
+
|
|
3
|
+
module NewRelic
|
|
4
|
+
module Agent
|
|
5
|
+
module Samplers
|
|
6
|
+
class CpuSampler < NewRelic::Agent::Sampler
|
|
7
|
+
attr_reader :last_time
|
|
8
|
+
def initialize
|
|
9
|
+
super :cpu
|
|
10
|
+
poll
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def user_util_stats
|
|
14
|
+
stats_engine.get_stats_no_scope("CPU/User/Utilization")
|
|
15
|
+
end
|
|
16
|
+
def system_util_stats
|
|
17
|
+
stats_engine.get_stats_no_scope("CPU/System/Utilization")
|
|
18
|
+
end
|
|
19
|
+
def usertime_stats
|
|
20
|
+
stats_engine.get_stats_no_scope("CPU/User Time")
|
|
21
|
+
end
|
|
22
|
+
def systemtime_stats
|
|
23
|
+
stats_engine.get_stats_no_scope("CPU/System Time")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.supported_on_this_platform?
|
|
27
|
+
# Process.times on JRuby reports wall clock elapsed time,
|
|
28
|
+
# not actual cpu time used, so we cannot use this sampler there.
|
|
29
|
+
not defined?(JRuby)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def poll
|
|
33
|
+
now = Time.now
|
|
34
|
+
t = Process.times
|
|
35
|
+
if @last_time
|
|
36
|
+
elapsed = now - @last_time
|
|
37
|
+
return if elapsed < 1 # Causing some kind of math underflow
|
|
38
|
+
num_processors = NewRelic::Control.instance.local_env.processors || 1
|
|
39
|
+
usertime = t.utime - @last_utime
|
|
40
|
+
systemtime = t.stime - @last_stime
|
|
41
|
+
|
|
42
|
+
systemtime_stats.record_data_point(systemtime) if systemtime >= 0
|
|
43
|
+
usertime_stats.record_data_point(usertime) if usertime >= 0
|
|
44
|
+
|
|
45
|
+
# Calculate the true utilization by taking cpu times and dividing by
|
|
46
|
+
# elapsed time X num_processors.
|
|
47
|
+
user_util_stats.record_data_point usertime / (elapsed * num_processors)
|
|
48
|
+
system_util_stats.record_data_point systemtime / (elapsed * num_processors)
|
|
49
|
+
end
|
|
50
|
+
@last_utime = t.utime
|
|
51
|
+
@last_stime = t.stime
|
|
52
|
+
@last_time = now
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require 'new_relic/agent/sampler'
|
|
2
|
+
require 'new_relic/delayed_job_injection'
|
|
3
|
+
|
|
4
|
+
module NewRelic
|
|
5
|
+
module Agent
|
|
6
|
+
module Samplers
|
|
7
|
+
class DelayedJobLockSampler < NewRelic::Agent::Sampler
|
|
8
|
+
def initialize
|
|
9
|
+
super :delayed_job_lock
|
|
10
|
+
raise Unsupported, "DJ instrumentation disabled" if NewRelic::Control.instance['disable_dj']
|
|
11
|
+
raise Unsupported, "No DJ worker present" unless NewRelic::DelayedJobInjection.worker_name
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def stats
|
|
15
|
+
stats_engine.get_stats("Custom/DJ Locked Jobs", false)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def local_env
|
|
19
|
+
NewRelic::Control.instance.local_env
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def worker_name
|
|
23
|
+
local_env.dispatcher_instance_id
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def locked_jobs
|
|
27
|
+
Delayed::Job.count(:conditions => {:locked_by => NewRelic::DelayedJobInjection.worker_name})
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.supported_on_this_platform?
|
|
31
|
+
defined?(Delayed::Job)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def poll
|
|
35
|
+
stats.record_data_point locked_jobs
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
require 'new_relic/agent/sampler'
|
|
2
|
+
|
|
3
|
+
module NewRelic
|
|
4
|
+
module Agent
|
|
5
|
+
module Samplers
|
|
6
|
+
|
|
7
|
+
class MemorySampler < NewRelic::Agent::Sampler
|
|
8
|
+
attr_accessor :sampler
|
|
9
|
+
|
|
10
|
+
def initialize
|
|
11
|
+
super :memory
|
|
12
|
+
# macos, linux, solaris
|
|
13
|
+
if defined? JRuby
|
|
14
|
+
@sampler = JavaHeapSampler.new
|
|
15
|
+
elsif platform =~ /linux/
|
|
16
|
+
@sampler = ProcStatus.new
|
|
17
|
+
if !@sampler.can_run?
|
|
18
|
+
NewRelic::Agent.instance.warn.debug "Error attempting to use /proc/#{$$}/status file for reading memory. Using ps command instead."
|
|
19
|
+
@sampler = ShellPS.new("ps -o rsz")
|
|
20
|
+
else
|
|
21
|
+
NewRelic::Agent.instance.log.debug "Using /proc/#{$$}/status for reading process memory."
|
|
22
|
+
end
|
|
23
|
+
elsif platform =~ /darwin9/ # 10.5
|
|
24
|
+
@sampler = ShellPS.new("ps -o rsz")
|
|
25
|
+
elsif platform =~ /darwin1[01]/ # 10.6 & 10.7
|
|
26
|
+
@sampler = ShellPS.new("ps -o rss")
|
|
27
|
+
elsif platform =~ /freebsd/
|
|
28
|
+
@sampler = ShellPS.new("ps -o rss")
|
|
29
|
+
elsif platform =~ /solaris/
|
|
30
|
+
@sampler = ShellPS.new("/usr/bin/ps -o rss -p")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
raise Unsupported, "Unsupported platform for getting memory: #{platform}" if @sampler.nil?
|
|
34
|
+
raise Unsupported, "Unable to run #{@sampler}" unless @sampler.can_run?
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.supported_on_this_platform?
|
|
38
|
+
defined?(JRuby) or platform =~ /linux|darwin9|darwin10|freebsd|solaris/
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.platform
|
|
42
|
+
if RUBY_PLATFORM =~ /java/
|
|
43
|
+
%x[uname -s].downcase
|
|
44
|
+
else
|
|
45
|
+
RUBY_PLATFORM.downcase
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
def platform
|
|
49
|
+
NewRelic::Agent::Samplers::MemorySampler.platform
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def stats
|
|
53
|
+
stats_engine.get_stats("Memory/Physical", false)
|
|
54
|
+
end
|
|
55
|
+
def poll
|
|
56
|
+
sample = @sampler.get_sample
|
|
57
|
+
stats.record_data_point sample if sample
|
|
58
|
+
stats
|
|
59
|
+
end
|
|
60
|
+
class Base
|
|
61
|
+
def can_run?
|
|
62
|
+
return false if @broken
|
|
63
|
+
m = get_memory rescue nil
|
|
64
|
+
m && m > 0
|
|
65
|
+
end
|
|
66
|
+
def get_sample
|
|
67
|
+
return nil if @broken
|
|
68
|
+
begin
|
|
69
|
+
m = get_memory
|
|
70
|
+
if m.nil?
|
|
71
|
+
NewRelic::Agent.instance.log.error "Unable to get the resident memory for process #{$$}. Disabling memory sampler."
|
|
72
|
+
@broken = true
|
|
73
|
+
end
|
|
74
|
+
return m
|
|
75
|
+
rescue => e
|
|
76
|
+
NewRelic::Agent.instance.log.error "Unable to get the resident memory for process #{$$}. (#{e})"
|
|
77
|
+
NewRelic::Agent.instance.log.debug e.backtrace.join("\n ")
|
|
78
|
+
NewRelic::Agent.instance.log.error "Disabling memory sampler."
|
|
79
|
+
@broken = true
|
|
80
|
+
return nil
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
class JavaHeapSampler < Base
|
|
86
|
+
|
|
87
|
+
def get_memory
|
|
88
|
+
raise "Can't sample Java heap unless running in JRuby" unless defined? JRuby
|
|
89
|
+
java.lang.Runtime.getRuntime.totalMemory / (1024 * 1024).to_f rescue nil
|
|
90
|
+
end
|
|
91
|
+
def to_s
|
|
92
|
+
"JRuby Java heap sampler"
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
class ShellPS < Base
|
|
97
|
+
def initialize(command)
|
|
98
|
+
super()
|
|
99
|
+
@command = command
|
|
100
|
+
end
|
|
101
|
+
# Returns the amount of resident memory this process is using in MB
|
|
102
|
+
#
|
|
103
|
+
def get_memory
|
|
104
|
+
process = $$
|
|
105
|
+
memory = `#{@command} #{process}`.split("\n")[1].to_f / 1024.0 rescue nil
|
|
106
|
+
# if for some reason the ps command doesn't work on the resident os,
|
|
107
|
+
# then don't execute it any more.
|
|
108
|
+
raise "Faulty command: `#{@command} #{process}`" if memory.nil? || memory <= 0
|
|
109
|
+
memory
|
|
110
|
+
end
|
|
111
|
+
def to_s
|
|
112
|
+
"shell command sampler: #{@command}"
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# ProcStatus
|
|
117
|
+
#
|
|
118
|
+
# A class that samples memory by reading the file /proc/$$/status, which is specific to linux
|
|
119
|
+
#
|
|
120
|
+
class ProcStatus < Base
|
|
121
|
+
|
|
122
|
+
# Returns the amount of resident memory this process is using in MB
|
|
123
|
+
#
|
|
124
|
+
def get_memory
|
|
125
|
+
File.open(proc_status_file, "r") do |f|
|
|
126
|
+
while !f.eof?
|
|
127
|
+
if f.readline =~ /RSS:\s*(\d+) kB/i
|
|
128
|
+
return $1.to_f / 1024.0
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
raise "Unable to find RSS in #{proc_status_file}"
|
|
133
|
+
end
|
|
134
|
+
def proc_status_file
|
|
135
|
+
"/proc/#{$$}/status"
|
|
136
|
+
end
|
|
137
|
+
def to_s
|
|
138
|
+
"proc status file sampler: #{proc_status_file}"
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'new_relic/agent/sampler'
|
|
2
|
+
|
|
3
|
+
module NewRelic
|
|
4
|
+
module Agent
|
|
5
|
+
module Samplers
|
|
6
|
+
class ObjectSampler < NewRelic::Agent::Sampler
|
|
7
|
+
|
|
8
|
+
def initialize
|
|
9
|
+
super :objects
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def stats
|
|
13
|
+
stats_engine.get_stats_no_scope("GC/objects")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def self.supported_on_this_platform?
|
|
17
|
+
defined?(ObjectSpace) && ObjectSpace.respond_to?(:live_objects)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def poll
|
|
21
|
+
stats.record_data_point(ObjectSpace.live_objects)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# This agent is loaded by the plug when the plug-in is disabled
|
|
2
|
+
# It recreates just enough of the API to not break any clients that
|
|
3
|
+
# invoke the Agent.
|
|
4
|
+
module NewRelic
|
|
5
|
+
module Agent
|
|
6
|
+
class ShimAgent < NewRelic::Agent::Agent
|
|
7
|
+
def self.instance
|
|
8
|
+
@instance ||= self.new
|
|
9
|
+
end
|
|
10
|
+
def initialize
|
|
11
|
+
super
|
|
12
|
+
@stats_engine.extend NewRelic::Agent::StatsEngine::Shim
|
|
13
|
+
@stats_engine.extend NewRelic::Agent::StatsEngine::Transactions::Shim
|
|
14
|
+
@transaction_sampler.extend NewRelic::Agent::TransactionSampler::Shim
|
|
15
|
+
@sql_sampler.extend NewRelic::Agent::SqlSampler::Shim
|
|
16
|
+
@error_collector.extend NewRelic::Agent::ErrorCollector::Shim
|
|
17
|
+
end
|
|
18
|
+
def after_fork *args; end
|
|
19
|
+
def start *args; end
|
|
20
|
+
def shutdown *args; end
|
|
21
|
+
def serialize; end
|
|
22
|
+
def merge_data_from *args; end
|
|
23
|
+
def push_trace_execution_flag *args; end
|
|
24
|
+
def pop_trace_execution_flag *args; end
|
|
25
|
+
def browser_timing_header; "" end
|
|
26
|
+
def browser_timing_footer; "" end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
require 'new_relic/agent'
|
|
2
|
+
require 'new_relic/control'
|
|
3
|
+
module NewRelic
|
|
4
|
+
module Agent
|
|
5
|
+
|
|
6
|
+
class SqlSampler
|
|
7
|
+
|
|
8
|
+
# Module defining methods stubbed out when the agent is disabled
|
|
9
|
+
module Shim #:nodoc:
|
|
10
|
+
def notice_scope_empty(*args); end
|
|
11
|
+
def notice_first_scope_push(*args); end
|
|
12
|
+
def notice_transaction(*args); end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
attr_reader :disabled
|
|
16
|
+
|
|
17
|
+
# this is for unit tests only
|
|
18
|
+
attr_reader :sql_traces
|
|
19
|
+
|
|
20
|
+
def initialize
|
|
21
|
+
configure!
|
|
22
|
+
@sql_traces = {}
|
|
23
|
+
clear_transaction_data
|
|
24
|
+
|
|
25
|
+
# This lock is used to synchronize access to the @last_sample
|
|
26
|
+
# and related variables. It can become necessary on JRuby or
|
|
27
|
+
# any 'honest-to-god'-multithreaded system
|
|
28
|
+
@samples_lock = Mutex.new
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def configure!
|
|
32
|
+
@explain_threshold = config.fetch('explain_threshold', 0.5).to_f
|
|
33
|
+
@explain_enabled = config.fetch('explain_enabled', true)
|
|
34
|
+
@stack_trace_threshold = config.fetch('stack_trace_threshold',
|
|
35
|
+
0.5).to_f
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def config
|
|
39
|
+
control = NewRelic::Control.instance
|
|
40
|
+
control.fetch('slow_sql',
|
|
41
|
+
control.fetch('transaction_tracer', {}))
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Enable the sql sampler - this also registers it with
|
|
45
|
+
# the statistics engine.
|
|
46
|
+
def enable
|
|
47
|
+
@disabled = false
|
|
48
|
+
NewRelic::Agent.instance.stats_engine.sql_sampler = self
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Disable the sql sampler - this also deregisters it
|
|
52
|
+
# with the statistics engine.
|
|
53
|
+
def disable
|
|
54
|
+
@disabled = true
|
|
55
|
+
NewRelic::Agent.instance.stats_engine.remove_sql_sampler(self)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def enabled?
|
|
59
|
+
!@disabled
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def notice_transaction(path, uri=nil, params={})
|
|
63
|
+
transaction_data.set_transaction_info(path, uri, params) if !disabled && transaction_data
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def notice_first_scope_push(time)
|
|
67
|
+
create_transaction_data
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def create_transaction_data
|
|
71
|
+
Thread.current[:new_relic_sql_data] = TransactionSqlData.new
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def transaction_data
|
|
75
|
+
Thread.current[:new_relic_sql_data]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def clear_transaction_data
|
|
79
|
+
Thread.current[:new_relic_sql_data] = nil
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# This is called when we are done with the transaction.
|
|
83
|
+
def notice_scope_empty(time=Time.now)
|
|
84
|
+
data = transaction_data
|
|
85
|
+
clear_transaction_data
|
|
86
|
+
|
|
87
|
+
if data.sql_data.count > 0
|
|
88
|
+
@samples_lock.synchronize do
|
|
89
|
+
NewRelic::Agent.instance.log.debug "Harvesting #{data.sql_data.count} slow transaction sql statement(s)"
|
|
90
|
+
#FIXME get tx name and uri
|
|
91
|
+
harvest_slow_sql data
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# this should always be called under the @samples_lock
|
|
97
|
+
def harvest_slow_sql(transaction_sql_data)
|
|
98
|
+
transaction_sql_data.sql_data.each do |sql_item|
|
|
99
|
+
normalized_sql = sql_item.normalize
|
|
100
|
+
sql_trace = @sql_traces[normalized_sql]
|
|
101
|
+
if sql_trace
|
|
102
|
+
sql_trace.aggregate(sql_item, transaction_sql_data.path,
|
|
103
|
+
transaction_sql_data.uri)
|
|
104
|
+
else
|
|
105
|
+
@sql_traces[normalized_sql] = SqlTrace.new(normalized_sql,
|
|
106
|
+
sql_item, transaction_sql_data.path, transaction_sql_data.uri)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def notice_sql(sql, metric_name, config, duration)
|
|
113
|
+
return unless transaction_data
|
|
114
|
+
if NewRelic::Agent.is_sql_recorded?
|
|
115
|
+
if duration > @explain_threshold
|
|
116
|
+
backtrace = caller.join("\n")
|
|
117
|
+
transaction_data.sql_data << SlowSql.new(sql, metric_name, config,
|
|
118
|
+
duration, backtrace)
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def merge(sql_traces)
|
|
124
|
+
@samples_lock.synchronize do
|
|
125
|
+
#FIXME we need to merge the sql_traces array back into the @sql_traces hash
|
|
126
|
+
# @sql_traces.merge! sql_traces
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def harvest
|
|
131
|
+
return [] if disabled
|
|
132
|
+
result = []
|
|
133
|
+
@samples_lock.synchronize do
|
|
134
|
+
result = @sql_traces.values
|
|
135
|
+
@sql_traces = {}
|
|
136
|
+
end
|
|
137
|
+
slowest = result.sort{|a,b| b.max_call_time <=> a.max_call_time}[0,10]
|
|
138
|
+
slowest.each {|trace| trace.prepare_to_send }
|
|
139
|
+
slowest
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# reset samples without rebooting the web server
|
|
143
|
+
def reset!
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
class TransactionSqlData
|
|
148
|
+
attr_reader :path
|
|
149
|
+
attr_reader :uri
|
|
150
|
+
attr_reader :params
|
|
151
|
+
attr_reader :sql_data
|
|
152
|
+
|
|
153
|
+
def initialize
|
|
154
|
+
@sql_data = []
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
def set_transaction_info(path, uri, params)
|
|
158
|
+
@path = path
|
|
159
|
+
@uri = uri
|
|
160
|
+
@params = params
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
class SlowSql
|
|
165
|
+
attr_reader :sql
|
|
166
|
+
attr_reader :metric_name
|
|
167
|
+
attr_reader :duration
|
|
168
|
+
attr_reader :backtrace
|
|
169
|
+
|
|
170
|
+
def initialize(sql, metric_name, config, duration, backtrace = nil)
|
|
171
|
+
@sql = sql
|
|
172
|
+
@metric_name = metric_name
|
|
173
|
+
@config = config
|
|
174
|
+
@duration = duration
|
|
175
|
+
@backtrace = backtrace
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
def obfuscate
|
|
179
|
+
NewRelic::Agent::Database.obfuscate_sql(@sql)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def normalize
|
|
183
|
+
NewRelic::Agent::Database::Obfuscator.instance \
|
|
184
|
+
.default_sql_obfuscator(@sql).gsub(/\?\s*\,\s*/, '').gsub(/\s/, '')
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def explain
|
|
188
|
+
NewRelic::Agent::Database.explain_sql(@sql, @config)
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
class SqlTrace < MethodTraceStats
|
|
193
|
+
attr_reader :path
|
|
194
|
+
attr_reader :url
|
|
195
|
+
attr_reader :sql_id
|
|
196
|
+
attr_reader :sql
|
|
197
|
+
attr_reader :database_metric_name
|
|
198
|
+
attr_reader :params
|
|
199
|
+
|
|
200
|
+
def initialize(normalized_query, slow_sql, path, uri)
|
|
201
|
+
super()
|
|
202
|
+
@params = {} #FIXME
|
|
203
|
+
@sql_id = consistent_hash(normalized_query)
|
|
204
|
+
set_primary slow_sql, path, uri
|
|
205
|
+
record_data_point slow_sql.duration
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def set_primary(slow_sql, path, uri)
|
|
209
|
+
@slow_sql = slow_sql
|
|
210
|
+
@sql = slow_sql.sql
|
|
211
|
+
@database_metric_name = slow_sql.metric_name
|
|
212
|
+
@path = path
|
|
213
|
+
@url = uri
|
|
214
|
+
# FIXME
|
|
215
|
+
@params[:backtrace] = slow_sql.backtrace if slow_sql.backtrace
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
def aggregate(slow_sql, path, uri)
|
|
219
|
+
if slow_sql.duration > max_call_time
|
|
220
|
+
set_primary slow_sql, path, uri
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
record_data_point slow_sql.duration
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
def prepare_to_send
|
|
227
|
+
begin
|
|
228
|
+
params[:explain_plan] = @slow_sql.explain if need_to_explain?
|
|
229
|
+
ensure
|
|
230
|
+
NewRelic::Agent::Database.close_connections
|
|
231
|
+
end
|
|
232
|
+
@sql = @slow_sql.obfuscate if need_to_obfuscate?
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
def agent_config
|
|
236
|
+
control = NewRelic::Control.instance
|
|
237
|
+
control.fetch('slow_sql',
|
|
238
|
+
control.fetch('transaction_tracer', {}))
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def need_to_obfuscate?
|
|
242
|
+
agent_config['record_sql'] == 'obfuscated'
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
def need_to_explain?
|
|
246
|
+
agent_config['explain_enabled']
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def to_json(*a)
|
|
250
|
+
[@path, @url, @sql_id, @sql, @database_metric_name, @call_count, @total_call_time, @min_call_time, @max_call_time, @params].to_json(*a)
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
private
|
|
254
|
+
|
|
255
|
+
def consistent_hash(string)
|
|
256
|
+
if NewRelic::LanguageSupport.using_version?('1.9.2')
|
|
257
|
+
# String#hash is salted differently on every VM start in 1.9
|
|
258
|
+
# modulo ensures sql_id fits in an INT(11)
|
|
259
|
+
require 'digest/md5'
|
|
260
|
+
Digest::MD5.hexdigest(string).hex.modulo(2**31-1)
|
|
261
|
+
else
|
|
262
|
+
string.hash
|
|
263
|
+
end
|
|
264
|
+
end
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
end
|