newrelic_rpm 3.8.1.221 → 3.9.0.229
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/.gitignore +1 -0
- data/.yardopts +2 -0
- data/CHANGELOG +95 -0
- data/README.md +9 -3
- data/Rakefile +6 -0
- data/lib/new_relic/agent.rb +37 -52
- data/lib/new_relic/agent/agent.rb +32 -64
- data/lib/new_relic/agent/agent_logger.rb +3 -2
- data/lib/new_relic/agent/audit_logger.rb +2 -1
- data/lib/new_relic/agent/busy_calculator.rb +10 -8
- data/lib/new_relic/agent/configuration.rb +0 -13
- data/lib/new_relic/agent/configuration/default_source.rb +27 -20
- data/lib/new_relic/agent/configuration/manager.rb +101 -27
- data/lib/new_relic/agent/cross_app_monitor.rb +43 -50
- data/lib/new_relic/agent/cross_app_tracing.rb +13 -12
- data/lib/new_relic/agent/error_collector.rb +31 -35
- data/lib/new_relic/agent/harvester.rb +5 -1
- data/lib/new_relic/agent/hostname.rb +17 -0
- data/lib/new_relic/agent/http_clients/curb_wrappers.rb +1 -1
- data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +1 -1
- data/lib/new_relic/agent/http_clients/uri_util.rb +13 -0
- data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +18 -32
- data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +15 -15
- data/lib/new_relic/agent/instrumentation/active_merchant.rb +1 -1
- data/lib/new_relic/agent/instrumentation/active_record.rb +6 -4
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +3 -2
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +18 -20
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +79 -93
- data/lib/new_relic/agent/instrumentation/curb.rb +3 -3
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +5 -4
- data/lib/new_relic/agent/instrumentation/middleware_proxy.rb +96 -0
- data/lib/new_relic/agent/instrumentation/middleware_tracing.rb +69 -0
- data/lib/new_relic/agent/instrumentation/net.rb +1 -1
- data/lib/new_relic/agent/instrumentation/queue_time.rb +21 -13
- data/lib/new_relic/agent/instrumentation/rack.rb +85 -74
- data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +3 -1
- data/lib/new_relic/agent/instrumentation/rails_middleware.rb +39 -0
- data/lib/new_relic/agent/instrumentation/rubyprof.rb +3 -3
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +28 -5
- data/lib/new_relic/agent/instrumentation/sinatra.rb +4 -4
- data/lib/new_relic/agent/instrumentation/typhoeus.rb +4 -2
- data/lib/new_relic/agent/javascript_instrumentor.rb +34 -30
- data/lib/new_relic/agent/memory_logger.rb +12 -12
- data/lib/new_relic/agent/method_tracer.rb +34 -74
- data/lib/new_relic/agent/new_relic_service.rb +1 -1
- data/lib/new_relic/agent/pipe_channel_manager.rb +3 -3
- data/lib/new_relic/agent/request_sampler.rb +10 -11
- data/lib/new_relic/agent/samplers/vm_sampler.rb +6 -6
- data/lib/new_relic/agent/shim_agent.rb +2 -1
- data/lib/new_relic/agent/sql_sampler.rb +52 -27
- data/lib/new_relic/agent/stats.rb +24 -10
- data/lib/new_relic/agent/stats_engine/gc_profiler.rb +5 -17
- data/lib/new_relic/agent/stats_engine/metric_stats.rb +106 -58
- data/lib/new_relic/agent/stats_engine/stats_hash.rb +20 -24
- data/lib/new_relic/agent/supported_versions.rb +3 -1
- data/lib/new_relic/agent/threading/agent_thread.rb +42 -11
- data/lib/new_relic/agent/threading/backtrace_service.rb +3 -7
- data/lib/new_relic/agent/threading/thread_profile.rb +2 -2
- data/lib/new_relic/agent/traced_method_stack.rb +28 -18
- data/lib/new_relic/agent/transaction.rb +249 -196
- data/lib/new_relic/agent/transaction_metrics.rb +57 -0
- data/lib/new_relic/agent/transaction_sample_builder.rb +10 -7
- data/lib/new_relic/agent/transaction_sampler.rb +81 -45
- data/lib/new_relic/agent/transaction_state.rb +38 -49
- data/lib/new_relic/agent/vm/monotonic_gc_profiler.rb +15 -18
- data/lib/new_relic/agent/vm/rubinius_vm.rb +4 -2
- data/lib/new_relic/cli/commands/deployments.rb +3 -2
- data/lib/new_relic/control/frameworks/ruby.rb +2 -3
- data/lib/new_relic/control/frameworks/sinatra.rb +0 -7
- data/lib/new_relic/control/instance_methods.rb +3 -5
- data/lib/new_relic/json_wrapper.rb +2 -0
- data/lib/new_relic/language_support.rb +1 -1
- data/lib/new_relic/local_environment.rb +0 -16
- data/lib/new_relic/metric_spec.rb +10 -38
- data/lib/new_relic/noticed_error.rb +16 -11
- data/lib/new_relic/rack/agent_hooks.rb +4 -10
- data/lib/new_relic/rack/agent_middleware.rb +31 -0
- data/lib/new_relic/rack/browser_monitoring.rb +7 -13
- data/lib/new_relic/rack/developer_mode.rb +16 -59
- data/lib/new_relic/rack/error_collector.rb +16 -54
- data/lib/new_relic/recipes.rb +8 -101
- data/lib/new_relic/recipes/capistrano3.rb +66 -0
- data/lib/new_relic/recipes/capistrano_legacy.rb +98 -0
- data/lib/new_relic/transaction_sample.rb +6 -54
- data/lib/new_relic/transaction_sample/composite_segment.rb +1 -1
- data/lib/new_relic/transaction_sample/segment.rb +12 -4
- data/lib/new_relic/transaction_sample/summary_segment.rb +1 -1
- data/lib/new_relic/version.rb +2 -2
- data/lib/newrelic_rpm.rb +1 -1
- data/lib/sequel/extensions/newrelic_instrumentation.rb +19 -19
- data/lib/tasks/tests.rake +20 -1
- data/lib/tasks/versions.html.erb +0 -4
- data/lib/tasks/versions.rake +4 -3
- data/newrelic.yml +4 -12
- data/newrelic_rpm.gemspec +1 -1
- data/test/agent_helper.rb +146 -44
- data/test/config/newrelic.yml +0 -1
- data/test/environments/norails/Gemfile +1 -1
- data/test/environments/rails21/Gemfile +1 -1
- data/test/environments/rails22/Gemfile +1 -1
- data/test/environments/rails23/Gemfile +1 -1
- data/test/environments/rails30/Gemfile +1 -1
- data/test/environments/rails31/Gemfile +1 -1
- data/test/environments/rails32/Gemfile +1 -1
- data/test/environments/rails40/Gemfile +1 -1
- data/test/environments/rails41/Gemfile +1 -1
- data/test/multiverse/lib/multiverse/runner.rb +13 -1
- data/test/multiverse/lib/multiverse/suite.rb +26 -9
- data/test/multiverse/suites/active_record/config/newrelic.yml +0 -1
- data/test/multiverse/suites/activemerchant/Envfile +18 -1
- data/test/multiverse/suites/agent_only/audit_log_test.rb +4 -3
- data/test/multiverse/suites/agent_only/collector_exception_handling_test.rb +35 -0
- data/test/multiverse/suites/agent_only/config/newrelic.yml +0 -1
- data/test/multiverse/suites/agent_only/cross_application_tracing_test.rb +1 -0
- data/test/multiverse/suites/agent_only/encoding_handling_test.rb +3 -2
- data/test/multiverse/suites/agent_only/exclusive_time_test.rb +178 -0
- data/test/multiverse/suites/agent_only/logging_test.rb +10 -6
- data/test/multiverse/suites/agent_only/marshaling_test.rb +11 -9
- data/test/multiverse/suites/agent_only/script/loading.rb +1 -1
- data/test/multiverse/suites/agent_only/service_timeout_test.rb +5 -1
- data/test/multiverse/suites/agent_only/transaction_ignoring_test.rb +2 -1
- data/test/multiverse/suites/agent_only/xray_sessions_test.rb +9 -9
- data/test/multiverse/suites/capistrano/Capfile +26 -0
- data/test/multiverse/suites/capistrano/Envfile +18 -0
- data/test/multiverse/suites/capistrano/config/deploy.rb +10 -0
- data/test/multiverse/suites/capistrano/config/deploy/production.rb +9 -0
- data/test/multiverse/suites/capistrano/config/newrelic.yml +21 -0
- data/test/multiverse/suites/capistrano/deployment_test.rb +47 -0
- data/test/multiverse/suites/capistrano2/Capfile +4 -0
- data/test/multiverse/suites/capistrano2/Envfile +4 -0
- data/test/multiverse/suites/capistrano2/config/deploy.rb +19 -0
- data/test/multiverse/suites/capistrano2/config/newrelic.yml +21 -0
- data/test/multiverse/suites/capistrano2/deployment_test.rb +38 -0
- data/test/multiverse/suites/curb/Envfile +10 -1
- data/test/multiverse/suites/curb/config/newrelic.yml +0 -1
- data/test/multiverse/suites/datamapper/config/newrelic.yml +0 -1
- data/test/multiverse/suites/deferred_instrumentation/config/newrelic.yml +0 -1
- data/test/multiverse/suites/excon/config/newrelic.yml +0 -1
- data/test/multiverse/suites/httpclient/config/newrelic.yml +0 -1
- data/test/multiverse/suites/mongo/config/newrelic.yml +0 -1
- data/test/multiverse/suites/net_http/config/newrelic.yml +0 -1
- data/test/multiverse/suites/padrino/config/newrelic.yml +0 -1
- data/test/multiverse/suites/rack/Envfile +25 -0
- data/test/multiverse/suites/rack/example_app.rb +50 -0
- data/test/multiverse/suites/rack/nested_non_rack_app_test.rb +66 -0
- data/test/multiverse/suites/rack/rack_auto_instrumentation_test.rb +143 -0
- data/test/multiverse/suites/rack/rack_unsupported_version_test.rb +45 -0
- data/test/multiverse/suites/rack/url_map_test.rb +120 -0
- data/test/multiverse/suites/rails/Envfile +10 -0
- data/test/multiverse/suites/rails/app.rb +28 -63
- data/test/multiverse/suites/rails/bad_instrumentation_test.rb +2 -4
- data/test/multiverse/suites/rails/config/newrelic.yml +1 -2
- data/test/multiverse/suites/rails/dummy.txt +1 -0
- data/test/multiverse/suites/rails/error_tracing_test.rb +46 -31
- data/test/multiverse/suites/rails/gc_instrumentation_test.rb +0 -1
- data/test/multiverse/suites/rails/ignore_test.rb +9 -3
- data/test/multiverse/suites/rails/middleware_instrumentation_test.rb +41 -0
- data/test/multiverse/suites/rails/middlewares.rb +19 -0
- data/test/multiverse/suites/rails/parameter_capture_test.rb +169 -0
- data/test/multiverse/suites/rails/queue_time_test.rb +14 -4
- data/test/multiverse/suites/rails/rails2_app/app/controllers/application.rb +7 -0
- data/test/multiverse/suites/rails/rails2_app/config/boot.rb +127 -0
- data/test/multiverse/suites/rails/rails2_app/config/database.yml +18 -0
- data/test/multiverse/suites/rails/rails2_app/config/environment.rb +16 -0
- data/test/multiverse/suites/rails/rails2_app/config/environments/development.rb +10 -0
- data/test/multiverse/suites/rails/rails2_app/config/initializers/load_newrelic_rpm.rb +9 -0
- data/test/multiverse/suites/rails/rails2_app/config/preinitializer.rb +25 -0
- data/test/multiverse/suites/rails/rails2_app/config/routes.rb +18 -0
- data/test/multiverse/suites/rails/rails2_app/db/schema.rb +5 -0
- data/test/multiverse/suites/rails/rails3_app/app_rails3_plus.rb +76 -0
- data/test/multiverse/suites/rails/request_statistics_test.rb +2 -4
- data/test/multiverse/suites/rails/transaction_ignoring_test.rb +3 -5
- data/test/multiverse/suites/rails/view_instrumentation_test.rb +73 -42
- data/test/multiverse/suites/resque/config/newrelic.yml +0 -1
- data/test/multiverse/suites/sequel/config/newrelic.yml +0 -1
- data/test/multiverse/suites/sidekiq/Envfile +4 -0
- data/test/multiverse/suites/sidekiq/after_suite.rb +7 -0
- data/test/multiverse/suites/sidekiq/config/newrelic.yml +0 -1
- data/test/multiverse/suites/sidekiq/sidekiq_instrumentation_test.rb +55 -34
- data/test/multiverse/suites/sidekiq/sidekiq_server.rb +30 -0
- data/test/multiverse/suites/sidekiq/test_worker.rb +60 -0
- data/test/multiverse/suites/sinatra/config/newrelic.yml +0 -1
- data/test/multiverse/suites/sinatra/ignoring_test.rb +33 -11
- data/test/multiverse/suites/sinatra/sinatra_metric_explosion_test.rb +3 -1
- data/test/multiverse/suites/typhoeus/Envfile +9 -0
- data/test/multiverse/suites/typhoeus/config/newrelic.yml +0 -1
- data/test/multiverse/suites/typhoeus/typhoeus_test.rb +10 -0
- data/test/multiverse/test/suite_examples/one/a/config/newrelic.yml +0 -1
- data/test/multiverse/test/suite_examples/one/b/config/newrelic.yml +0 -1
- data/test/new_relic/agent/agent/connect_test.rb +3 -10
- data/test/new_relic/agent/agent_logger_test.rb +24 -6
- data/test/new_relic/agent/agent_test.rb +7 -8
- data/test/new_relic/agent/agent_test_controller.rb +2 -2
- data/test/new_relic/agent/audit_logger_test.rb +5 -1
- data/test/new_relic/agent/busy_calculator_test.rb +1 -1
- data/test/new_relic/agent/configuration/manager_test.rb +68 -69
- data/test/new_relic/agent/cross_app_monitor_test.rb +32 -14
- data/test/new_relic/agent/cross_app_tracing_test.rb +2 -2
- data/test/new_relic/agent/error_collector/notice_error_test.rb +9 -33
- data/test/new_relic/agent/error_collector_test.rb +45 -14
- data/test/new_relic/agent/harvester_test.rb +9 -0
- data/test/new_relic/agent/hostname_test.rb +41 -0
- data/test/new_relic/agent/instrumentation/action_controller_subscriber_test.rb +27 -19
- data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +1 -1
- data/test/new_relic/agent/instrumentation/active_record_test.rb +3 -3
- data/test/new_relic/agent/instrumentation/controller_instrumentation_test.rb +95 -14
- data/test/new_relic/agent/instrumentation/middleware_proxy_test.rb +189 -0
- data/test/new_relic/agent/instrumentation/net_instrumentation_test.rb +2 -2
- data/test/new_relic/agent/instrumentation/queue_time_test.rb +18 -1
- data/test/new_relic/agent/instrumentation/rack_test.rb +10 -1
- data/test/new_relic/agent/instrumentation/sinatra_test.rb +3 -1
- data/test/new_relic/agent/javascript_instrumentor_test.rb +28 -41
- data/test/new_relic/agent/memory_logger_test.rb +14 -0
- data/test/new_relic/agent/method_interrobang_test.rb +1 -1
- data/test/new_relic/agent/method_tracer/class_methods/add_method_tracer_test.rb +1 -30
- data/test/new_relic/agent/method_tracer/instance_methods/trace_execution_scoped_test.rb +5 -21
- data/test/new_relic/agent/method_tracer_test.rb +5 -4
- data/test/new_relic/agent/mock_scope_listener.rb +2 -2
- data/test/new_relic/agent/obfuscator_test.rb +1 -1
- data/test/new_relic/agent/pipe_channel_manager_test.rb +17 -5
- data/test/new_relic/agent/request_sampler_test.rb +16 -16
- data/test/new_relic/agent/rpm_agent_test.rb +23 -29
- data/test/new_relic/agent/sql_sampler_test.rb +39 -31
- data/test/new_relic/agent/stats_engine/metric_stats_test.rb +189 -117
- data/test/new_relic/agent/stats_engine_test.rb +1 -1
- data/test/new_relic/agent/stats_hash_test.rb +28 -1
- data/test/new_relic/agent/stats_test.rb +1 -12
- data/test/new_relic/agent/threading/agent_thread_test.rb +23 -9
- data/test/new_relic/agent/threading/backtrace_service_test.rb +33 -32
- data/test/new_relic/agent/threading/fake_thread.rb +4 -8
- data/test/new_relic/agent/threading/threaded_test_case.rb +4 -14
- data/test/new_relic/agent/traced_method_stack_test.rb +43 -27
- data/test/new_relic/agent/transaction_interrobang_test.rb +1 -1
- data/test/new_relic/agent/transaction_metrics_test.rb +113 -0
- data/test/new_relic/agent/transaction_sample_builder_test.rb +1 -61
- data/test/new_relic/agent/transaction_sampler_test.rb +176 -228
- data/test/new_relic/agent/transaction_state_test.rb +62 -26
- data/test/new_relic/agent/transaction_test.rb +198 -80
- data/test/new_relic/agent/vm/monotonic_gc_profiler_test.rb +4 -4
- data/test/new_relic/agent/vm/rubinius_vm_test.rb +68 -0
- data/test/new_relic/agent_test.rb +31 -27
- data/test/new_relic/cli/commands/deployments_test.rb +7 -2
- data/test/new_relic/control/instance_methods_test.rb +4 -4
- data/test/new_relic/control_test.rb +28 -22
- data/test/new_relic/dependency_detection_test.rb +14 -0
- data/test/new_relic/fake_external_server.rb +1 -0
- data/test/new_relic/fake_rpm_site.rb +35 -0
- data/test/new_relic/http_client_test_cases.rb +12 -3
- data/test/new_relic/json_wrapper_test.rb +5 -0
- data/test/new_relic/language_support_test.rb +7 -0
- data/test/new_relic/license_test.rb +11 -5
- data/test/new_relic/local_environment_test.rb +0 -18
- data/test/new_relic/metric_data_test.rb +2 -2
- data/test/new_relic/metric_spec_test.rb +4 -23
- data/test/new_relic/multiverse_helpers.rb +1 -3
- data/test/new_relic/noticed_error_test.rb +6 -22
- data/test/new_relic/rack/agent_hooks_test.rb +5 -1
- data/test/new_relic/rack/agent_middleware_test.rb +32 -0
- data/test/new_relic/rack/browser_monitoring_test.rb +14 -1
- data/test/new_relic/rack/developer_mode_helper_test.rb +0 -8
- data/test/new_relic/rack/developer_mode_test.rb +1 -1
- data/test/new_relic/rack/error_collector_test.rb +6 -30
- data/test/new_relic/transaction_sample/fake_segment_test.rb +2 -2
- data/test/new_relic/transaction_sample/segment_test.rb +47 -47
- data/test/new_relic/transaction_sample_test.rb +9 -8
- data/test/performance/lib/performance/instrumentation/stackprof.rb +11 -8
- data/test/performance/script/runner +13 -0
- data/test/performance/suites/config.rb +5 -2
- data/test/performance/suites/rack_middleware.rb +84 -0
- data/test/performance/suites/rum_autoinsertion.rb +1 -1
- data/test/performance/suites/thread_profiling.rb +1 -1
- data/test/test_helper.rb +12 -10
- data/ui/helpers/developer_mode_helper.rb +3 -43
- data/ui/views/layouts/newrelic_default.rhtml +2 -2
- data/ui/views/newrelic/_sample.rhtml +2 -2
- data/ui/views/newrelic/_sql_row.rhtml +11 -11
- data/ui/views/newrelic/index.rhtml +21 -22
- data/vendor/gems/dependency_detection-0.0.1.build/lib/dependency_detection.rb +15 -10
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser.rb +2 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/middleware.rb +34 -0
- data/vendor/gems/metric_parser-0.1.0.pre1/lib/new_relic/metric_parser/nested.rb +24 -0
- metadata +108 -31
- metadata.gz.sig +0 -0
- data/lib/new_relic/rack/transaction_reset.rb +0 -20
- data/test/multiverse/suites/rails/mongrel_queue_depth_test.rb +0 -42
- data/test/new_relic/rack/transaction_reset_test.rb +0 -35
- data/ui/views/newrelic/show_source.rhtml +0 -3
@@ -19,25 +19,22 @@ module NewRelic
|
|
19
19
|
@lock = Mutex.new
|
20
20
|
end
|
21
21
|
|
22
|
-
class ProfilerNotEnabledError < StandardError
|
23
|
-
def initialize
|
24
|
-
super("total_time is not available if GC::Profiler isn't enabled")
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
22
|
def total_time_s
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
23
|
+
if NewRelic::LanguageSupport.gc_profiler_enabled?
|
24
|
+
# There's a race here if the next two lines don't execute as an atomic
|
25
|
+
# unit - we may end up double-counting some GC time in that scenario.
|
26
|
+
# Locking around them guarantees atomicity of the read/increment/reset
|
27
|
+
# sequence.
|
28
|
+
@lock.synchronize do
|
29
|
+
# The Ruby 1.9.x docs claim that GC::Profiler.total_time returns
|
30
|
+
# a value in milliseconds. They are incorrect - both 1.9.x and 2.x
|
31
|
+
# return values in seconds.
|
32
|
+
@total_time_s += ::GC::Profiler.total_time
|
33
|
+
::GC::Profiler.clear
|
34
|
+
end
|
35
|
+
else
|
36
|
+
NewRelic::Agent.logger.log_once(:warn, :gc_profiler_disabled,
|
37
|
+
"Tried to measure GC time, but GC::Profiler was not enabled.")
|
41
38
|
end
|
42
39
|
|
43
40
|
@total_time_s
|
@@ -18,8 +18,10 @@ module NewRelic
|
|
18
18
|
snap.gc_runs = GC.count
|
19
19
|
|
20
20
|
gc_stats = GC.stat[:gc]
|
21
|
-
|
22
|
-
|
21
|
+
if gc_stats
|
22
|
+
snap.major_gc_count = gc_stats[:full][:count] if gc_stats[:full]
|
23
|
+
snap.minor_gc_count = gc_stats[:young][:count] if gc_stats[:young]
|
24
|
+
end
|
23
25
|
|
24
26
|
snap.thread_count = Thread.list.size
|
25
27
|
end
|
@@ -8,6 +8,7 @@
|
|
8
8
|
require 'yaml'
|
9
9
|
require 'net/http'
|
10
10
|
require 'rexml/document'
|
11
|
+
require 'new_relic/agent/hostname'
|
11
12
|
|
12
13
|
# We need to use the Control object but we don't want to load
|
13
14
|
# the rails/merb environment. The defined? clause is so that
|
@@ -43,7 +44,7 @@ class NewRelic::Cli::Deployments < NewRelic::Cli::Command
|
|
43
44
|
|
44
45
|
def load_yaml_from_env(env)
|
45
46
|
yaml = NewRelic::Agent::Configuration::YamlSource.new(NewRelic::Agent.config[:config_path], env)
|
46
|
-
NewRelic::Agent.config.replace_or_add_config(yaml
|
47
|
+
NewRelic::Agent.config.replace_or_add_config(yaml)
|
47
48
|
end
|
48
49
|
|
49
50
|
def setup_logging(env)
|
@@ -59,7 +60,7 @@ class NewRelic::Cli::Deployments < NewRelic::Cli::Command
|
|
59
60
|
create_params = {}
|
60
61
|
{
|
61
62
|
:application_id => @appname,
|
62
|
-
:host =>
|
63
|
+
:host => NewRelic::Agent::Hostname.get,
|
63
64
|
:description => @description,
|
64
65
|
:user => @user,
|
65
66
|
:revision => @revision,
|
@@ -7,9 +7,9 @@ module NewRelic
|
|
7
7
|
module Frameworks
|
8
8
|
# A control used when no framework is detected - the default.
|
9
9
|
class Ruby < NewRelic::Control
|
10
|
-
|
11
10
|
def env
|
12
|
-
@env ||= ENV['
|
11
|
+
@env ||= ENV['NEW_RELIC_ENV'] || ENV['RUBY_ENV'] ||
|
12
|
+
ENV['RAILS_ENV'] || ENV['RACK_ENV'] || 'development'
|
13
13
|
end
|
14
14
|
|
15
15
|
def root
|
@@ -18,7 +18,6 @@ module NewRelic
|
|
18
18
|
|
19
19
|
def init_config(options={})
|
20
20
|
end
|
21
|
-
|
22
21
|
end
|
23
22
|
end
|
24
23
|
end
|
@@ -2,22 +2,15 @@
|
|
2
2
|
# This file is distributed under New Relic's license terms.
|
3
3
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
4
|
|
5
|
-
|
6
5
|
require 'new_relic/control/frameworks/ruby'
|
7
6
|
module NewRelic
|
8
7
|
class Control
|
9
8
|
module Frameworks
|
10
9
|
# Contains basic control logic for Sinatra
|
11
10
|
class Sinatra < NewRelic::Control::Frameworks::Ruby
|
12
|
-
|
13
|
-
def env
|
14
|
-
@env ||= ENV['RACK_ENV'] || ENV['RAILS_ENV'] || 'development'
|
15
|
-
end
|
16
|
-
|
17
11
|
def init_config(options={})
|
18
12
|
super
|
19
13
|
end
|
20
|
-
|
21
14
|
end
|
22
15
|
end
|
23
16
|
end
|
@@ -70,6 +70,7 @@ module NewRelic
|
|
70
70
|
Module.send :include, NewRelic::Agent::MethodTracer
|
71
71
|
init_config(options)
|
72
72
|
NewRelic::Agent.agent = NewRelic::Agent::Agent.instance
|
73
|
+
NewRelic::Agent.agent.start_service_if_needed
|
73
74
|
if Agent.config[:agent_enabled] && !NewRelic::Agent.instance.started?
|
74
75
|
start_agent
|
75
76
|
install_instrumentation
|
@@ -80,13 +81,10 @@ module NewRelic
|
|
80
81
|
|
81
82
|
def configure_agent(env, options)
|
82
83
|
manual = Agent::Configuration::ManualSource.new(options)
|
83
|
-
Agent.config.replace_or_add_config(manual
|
84
|
+
Agent.config.replace_or_add_config(manual)
|
84
85
|
|
85
86
|
config_file_path = @config_file_override || Agent.config[:config_path]
|
86
|
-
Agent.config.replace_or_add_config(Agent::Configuration::YamlSource.new(config_file_path, env)
|
87
|
-
|
88
|
-
Agent.config.remove_config(manual)
|
89
|
-
Agent.config.replace_or_add_config(Agent::Configuration::ManualSource.new(options), 1)
|
87
|
+
Agent.config.replace_or_add_config(Agent::Configuration::YamlSource.new(config_file_path, env))
|
90
88
|
end
|
91
89
|
|
92
90
|
# Install the real agent into the Agent module, and issue the start command.
|
@@ -55,22 +55,6 @@ module NewRelic
|
|
55
55
|
return nil
|
56
56
|
end
|
57
57
|
|
58
|
-
# Sets the @mongrel instance variable if we can find a Mongrel::HttpServer
|
59
|
-
def mongrel
|
60
|
-
return @mongrel if @looked_for_mongrel
|
61
|
-
@looked_for_mongrel = true
|
62
|
-
if defined?(::Mongrel) && defined?(::Mongrel::HttpServer)
|
63
|
-
@mongrel = find_class_in_object_space(::Mongrel::HttpServer)
|
64
|
-
end
|
65
|
-
@mongrel
|
66
|
-
end
|
67
|
-
|
68
|
-
# Setter for testing
|
69
|
-
def mongrel=(m)
|
70
|
-
@looked_for_mongrel = true
|
71
|
-
@mongrel = m
|
72
|
-
end
|
73
|
-
|
74
58
|
private
|
75
59
|
|
76
60
|
def discover_dispatcher
|
@@ -2,65 +2,37 @@
|
|
2
2
|
# This file is distributed under New Relic's license terms.
|
3
3
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
4
|
|
5
|
-
require 'new_relic/agent/internal_agent_error'
|
6
|
-
|
7
5
|
# this struct uniquely defines a metric, optionally inside
|
8
6
|
# the call scope of another metric
|
9
7
|
class NewRelic::MetricSpec
|
10
|
-
|
11
|
-
attr_accessor :scope
|
8
|
+
attr_reader :name, :scope
|
12
9
|
|
13
10
|
# the maximum length of a metric name or metric scope
|
14
11
|
MAX_LENGTH = 255
|
15
12
|
LENGTH_RANGE = (0...MAX_LENGTH)
|
16
|
-
|
17
|
-
# jruby) for sending responses to ruby agents from the java collector.
|
18
|
-
#
|
19
|
-
def initialize(metric_name = '', metric_scope = nil)
|
20
|
-
self.name = (metric_name || '') && metric_name.to_s[LENGTH_RANGE]
|
21
|
-
if metric_scope
|
22
|
-
self.scope = metric_scope && metric_scope.to_s[LENGTH_RANGE]
|
23
|
-
else
|
24
|
-
self.scope = ''
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
class InvalidScopeSettingError < NewRelic::Agent::InternalAgentError
|
29
|
-
def initialize(name, scope)
|
30
|
-
super("Attempted to set scope for #{name} to #{scope.inspect}, ignoring.")
|
31
|
-
end
|
32
|
-
end
|
13
|
+
EMPTY_SCOPE = ''.freeze
|
33
14
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
15
|
+
def initialize(metric_name='', metric_scope=nil)
|
16
|
+
@name = metric_name.to_s[LENGTH_RANGE]
|
17
|
+
if metric_scope
|
18
|
+
@scope = metric_scope.to_s[LENGTH_RANGE]
|
37
19
|
else
|
38
|
-
@scope =
|
20
|
+
@scope = EMPTY_SCOPE
|
39
21
|
end
|
40
22
|
end
|
41
23
|
|
42
|
-
# truncates the name and scope to the MAX_LENGTH
|
43
|
-
def truncate!
|
44
|
-
self.name = name[LENGTH_RANGE] if name && name.size > MAX_LENGTH
|
45
|
-
self.scope = scope[LENGTH_RANGE] if scope && scope.size > MAX_LENGTH
|
46
|
-
end
|
47
|
-
|
48
24
|
def ==(o)
|
49
25
|
self.eql?(o)
|
50
26
|
end
|
51
27
|
|
52
28
|
def eql? o
|
53
|
-
|
54
|
-
name.eql?(o.name) &&
|
55
|
-
# coerce scope to a string and compare
|
56
|
-
scope.to_s == o.scope.to_s
|
29
|
+
@name == o.name && @scope == o.scope
|
57
30
|
end
|
58
31
|
|
59
32
|
def hash
|
60
|
-
|
61
|
-
h ^= scope.hash unless scope.nil?
|
62
|
-
h
|
33
|
+
@name.hash ^ @scope.hash
|
63
34
|
end
|
35
|
+
|
64
36
|
# return a new metric spec if the given regex
|
65
37
|
# matches the name or scope.
|
66
38
|
def sub(pattern, replacement, apply_to_scope = true)
|
@@ -7,9 +7,8 @@ require 'new_relic/helper'
|
|
7
7
|
# This class encapsulates an error that was noticed by New Relic in a managed app.
|
8
8
|
class NewRelic::NoticedError
|
9
9
|
extend NewRelic::CollectionHelper
|
10
|
-
attr_accessor :path, :timestamp, :params, :message,
|
11
|
-
|
12
|
-
attr_reader :exception_id
|
10
|
+
attr_accessor :path, :timestamp, :params, :message, :exception_class_name
|
11
|
+
attr_reader :exception_id, :is_internal
|
13
12
|
|
14
13
|
STRIPPED_EXCEPTION_REPLACEMENT_MESSAGE = "Message removed by New Relic 'strip_exception_messages' setting"
|
15
14
|
|
@@ -19,7 +18,12 @@ class NewRelic::NoticedError
|
|
19
18
|
@params = NewRelic::NoticedError.normalize_params(data)
|
20
19
|
|
21
20
|
@exception_class_name = exception.is_a?(Exception) ? exception.class.name : 'Error'
|
22
|
-
|
21
|
+
|
22
|
+
# It's critical that we not hold onto the exception class constant in this
|
23
|
+
# class. These objects get serialized for Resque to a process that might
|
24
|
+
# not have the original exception class loaded, so do all processing now
|
25
|
+
# while we have the actual exception!
|
26
|
+
@is_internal = (exception.class < NewRelic::Agent::InternalAgentError)
|
23
27
|
|
24
28
|
if exception.nil?
|
25
29
|
@message = '<no message>'
|
@@ -43,7 +47,8 @@ class NewRelic::NoticedError
|
|
43
47
|
@message = @message[0..4095] if @message.length > 4096
|
44
48
|
|
45
49
|
# replace error message if enabled
|
46
|
-
if NewRelic::Agent.config[:'strip_exception_messages.enabled'] &&
|
50
|
+
if NewRelic::Agent.config[:'strip_exception_messages.enabled'] &&
|
51
|
+
!self.class.passes_message_whitelist(exception.class)
|
47
52
|
@message = STRIPPED_EXCEPTION_REPLACEMENT_MESSAGE
|
48
53
|
end
|
49
54
|
|
@@ -57,12 +62,6 @@ class NewRelic::NoticedError
|
|
57
62
|
exception_class_name
|
58
63
|
end
|
59
64
|
|
60
|
-
def whitelisted?
|
61
|
-
NewRelic::Agent.config.stripped_exceptions_whitelist.find do |klass|
|
62
|
-
exception_class_constant <= klass
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
65
|
def ==(other)
|
67
66
|
if other.respond_to?(:exception_id)
|
68
67
|
exception_id == other.exception_id
|
@@ -71,6 +70,12 @@ class NewRelic::NoticedError
|
|
71
70
|
end
|
72
71
|
end
|
73
72
|
|
73
|
+
def self.passes_message_whitelist(exception_class)
|
74
|
+
NewRelic::Agent.config.stripped_exceptions_whitelist.any? do |klass|
|
75
|
+
exception_class <= klass
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
74
79
|
include NewRelic::Coerce
|
75
80
|
|
76
81
|
def to_collector_array(encoder=nil)
|
@@ -3,7 +3,8 @@
|
|
3
3
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
4
|
|
5
5
|
require 'new_relic/agent/event_listener'
|
6
|
-
require 'new_relic/rack/
|
6
|
+
require 'new_relic/rack/agent_middleware'
|
7
|
+
require 'new_relic/agent/instrumentation/middleware_proxy'
|
7
8
|
|
8
9
|
module NewRelic::Rack
|
9
10
|
# This middleware is used by the agent internally, and is usually injected
|
@@ -12,13 +13,7 @@ module NewRelic::Rack
|
|
12
13
|
#
|
13
14
|
# @api public
|
14
15
|
#
|
15
|
-
class AgentHooks
|
16
|
-
def initialize(app, options = {})
|
17
|
-
@app = app
|
18
|
-
end
|
19
|
-
|
20
|
-
include TransactionReset
|
21
|
-
|
16
|
+
class AgentHooks < AgentMiddleware
|
22
17
|
FIRED_FORMATS = {
|
23
18
|
:before_call => "newrelic.agent_hooks_before_fired",
|
24
19
|
:after_call => "newrelic.agent_hooks_after_fired"
|
@@ -26,8 +21,7 @@ module NewRelic::Rack
|
|
26
21
|
|
27
22
|
# method required by Rack interface
|
28
23
|
# [status, headers, response]
|
29
|
-
def
|
30
|
-
ensure_transaction_reset(env)
|
24
|
+
def traced_call(env)
|
31
25
|
notify(:before_call, env)
|
32
26
|
result = @app.call(env)
|
33
27
|
notify(:after_call, env, result)
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
# This file is distributed under New Relic's license terms.
|
3
|
+
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
|
+
|
5
|
+
require 'new_relic/agent/transaction_state'
|
6
|
+
require 'new_relic/agent/instrumentation/controller_instrumentation'
|
7
|
+
require 'new_relic/agent/instrumentation/middleware_tracing'
|
8
|
+
|
9
|
+
module NewRelic
|
10
|
+
module Rack
|
11
|
+
class AgentMiddleware
|
12
|
+
include Agent::Instrumentation::MiddlewareTracing
|
13
|
+
|
14
|
+
attr_reader :transaction_options, :category, :target
|
15
|
+
|
16
|
+
def initialize(app, options={})
|
17
|
+
@app = app
|
18
|
+
@category = :middleware
|
19
|
+
@target = self
|
20
|
+
@transaction_options = {
|
21
|
+
:transaction_name => build_transaction_name
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def build_transaction_name
|
26
|
+
prefix = ::NewRelic::Agent::Instrumentation::ControllerInstrumentation::TransactionNamer.prefix_for_category(nil, @category)
|
27
|
+
"#{prefix}#{self.class.name}/call"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -3,7 +3,8 @@
|
|
3
3
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
4
|
|
5
5
|
require 'rack'
|
6
|
-
require 'new_relic/rack/
|
6
|
+
require 'new_relic/rack/agent_middleware'
|
7
|
+
require 'new_relic/agent/instrumentation/middleware_proxy'
|
7
8
|
|
8
9
|
module NewRelic::Rack
|
9
10
|
# This middleware is used by the agent for the Real user monitoring (RUM)
|
@@ -13,17 +14,8 @@ module NewRelic::Rack
|
|
13
14
|
#
|
14
15
|
# @api public
|
15
16
|
#
|
16
|
-
class BrowserMonitoring
|
17
|
-
|
18
|
-
def initialize(app, options = {})
|
19
|
-
@app = app
|
20
|
-
end
|
21
|
-
|
22
|
-
include TransactionReset
|
23
|
-
|
24
|
-
# method required by Rack interface
|
25
|
-
def call(env)
|
26
|
-
ensure_transaction_reset(env)
|
17
|
+
class BrowserMonitoring < AgentMiddleware
|
18
|
+
def traced_call(env)
|
27
19
|
result = @app.call(env) # [status, headers, response]
|
28
20
|
|
29
21
|
if (NewRelic::Agent.browser_timing_header != "") && should_instrument?(env, result[0], result[1])
|
@@ -89,6 +81,9 @@ module NewRelic::Rack
|
|
89
81
|
end
|
90
82
|
|
91
83
|
source
|
84
|
+
rescue => e
|
85
|
+
NewRelic::Agent.logger.debug "Skipping RUM instrumentation on exception.", e
|
86
|
+
nil
|
92
87
|
end
|
93
88
|
|
94
89
|
def gather_source(response)
|
@@ -134,5 +129,4 @@ module NewRelic::Rack
|
|
134
129
|
end
|
135
130
|
end
|
136
131
|
end
|
137
|
-
|
138
132
|
end
|
@@ -8,7 +8,8 @@ require 'rack/response'
|
|
8
8
|
require 'rack/file'
|
9
9
|
require 'new_relic/collection_helper'
|
10
10
|
require 'new_relic/metric_parser/metric_parser'
|
11
|
-
require 'new_relic/rack/
|
11
|
+
require 'new_relic/rack/agent_middleware'
|
12
|
+
require 'new_relic/agent/instrumentation/middleware_proxy'
|
12
13
|
|
13
14
|
module NewRelic
|
14
15
|
module Rack
|
@@ -26,22 +27,24 @@ module NewRelic
|
|
26
27
|
#
|
27
28
|
# @api public
|
28
29
|
#
|
29
|
-
class DeveloperMode
|
30
|
+
class DeveloperMode < AgentMiddleware
|
30
31
|
|
31
|
-
VIEW_PATH
|
32
|
+
VIEW_PATH = File.expand_path('../../../../ui/views/' , __FILE__)
|
32
33
|
HELPER_PATH = File.expand_path('../../../../ui/helpers/', __FILE__)
|
33
34
|
require File.join(HELPER_PATH, 'developer_mode_helper.rb')
|
34
35
|
|
35
36
|
|
36
37
|
include NewRelic::DeveloperModeHelper
|
37
|
-
include TransactionReset
|
38
38
|
|
39
|
-
|
40
|
-
|
39
|
+
class << self
|
40
|
+
attr_writer :profiling_enabled
|
41
41
|
end
|
42
42
|
|
43
|
-
def
|
44
|
-
|
43
|
+
def self.profiling_enabled?
|
44
|
+
@profiling_enabled
|
45
|
+
end
|
46
|
+
|
47
|
+
def traced_call(env)
|
45
48
|
return @app.call(env) unless /^\/newrelic/ =~ ::Rack::Request.new(env).path_info
|
46
49
|
dup._call(env)
|
47
50
|
end
|
@@ -70,8 +73,6 @@ module NewRelic
|
|
70
73
|
show_sample_data
|
71
74
|
when /explain_sql/
|
72
75
|
explain_sql
|
73
|
-
when /show_source/
|
74
|
-
show_source
|
75
76
|
when /^\/newrelic\/?$/
|
76
77
|
index
|
77
78
|
else
|
@@ -121,14 +122,9 @@ module NewRelic
|
|
121
122
|
render(:explain_sql)
|
122
123
|
end
|
123
124
|
|
124
|
-
PROFILE_CONFIG = { :'profiling.enabled' => true }
|
125
|
-
|
126
125
|
def profile
|
127
|
-
|
128
|
-
|
129
|
-
else
|
130
|
-
NewRelic::Agent.config.remove_config(PROFILE_CONFIG) if NewRelic::Agent.config[:'profiling.enabled']
|
131
|
-
end
|
126
|
+
should_be_on = (params['start'] == 'true')
|
127
|
+
NewRelic::Rack::DeveloperMode.profiling_enabled = should_be_on
|
132
128
|
|
133
129
|
index
|
134
130
|
end
|
@@ -201,44 +197,6 @@ module NewRelic
|
|
201
197
|
@segment
|
202
198
|
end
|
203
199
|
|
204
|
-
|
205
|
-
# show the selected source file with the highlighted selected line
|
206
|
-
def show_source
|
207
|
-
@filename = params['file']
|
208
|
-
line_number = params['line'].to_i
|
209
|
-
|
210
|
-
if !File.readable?(@filename)
|
211
|
-
@source="<p>Unable to read #{@filename}.</p>"
|
212
|
-
return
|
213
|
-
end
|
214
|
-
begin
|
215
|
-
file = File.new(@filename, 'r')
|
216
|
-
rescue => e
|
217
|
-
@source="<p>Unable to access the source file #{@filename} (#{e.message}).</p>"
|
218
|
-
return
|
219
|
-
end
|
220
|
-
@source = ""
|
221
|
-
|
222
|
-
@source << "<pre>"
|
223
|
-
file.each_line do |line|
|
224
|
-
# place an anchor 6 lines above the selected line (if the line # < 6)
|
225
|
-
if file.lineno == line_number - 6
|
226
|
-
@source << "</pre><pre id = 'selected_line'>"
|
227
|
-
@source << line.rstrip
|
228
|
-
@source << "</pre><pre>"
|
229
|
-
|
230
|
-
# highlight the selected line
|
231
|
-
elsif file.lineno == line_number
|
232
|
-
@source << "</pre><pre class = 'selected_source_line'>"
|
233
|
-
@source << line.rstrip
|
234
|
-
@source << "</pre><pre>"
|
235
|
-
else
|
236
|
-
@source << line
|
237
|
-
end
|
238
|
-
end
|
239
|
-
render(:show_source)
|
240
|
-
end
|
241
|
-
|
242
200
|
def show_sample_data
|
243
201
|
get_sample
|
244
202
|
|
@@ -247,7 +205,7 @@ module NewRelic
|
|
247
205
|
@request_params = @sample.params['request_params'] || {}
|
248
206
|
@custom_params = @sample.params['custom_params'] || {}
|
249
207
|
|
250
|
-
controller_metric = @sample.
|
208
|
+
controller_metric = @sample.transaction_name
|
251
209
|
|
252
210
|
metric_parser = NewRelic::MetricParser::MetricParser.for_metric_named controller_metric
|
253
211
|
@sample_controller_name = metric_parser.controller_name
|
@@ -269,8 +227,7 @@ module NewRelic
|
|
269
227
|
sample.params[:path] != nil
|
270
228
|
end
|
271
229
|
|
272
|
-
return @samples = @samples.
|
273
|
-
x.omit_segments_with('(Rails/Application Code Loading)|(Database/.*/.+ Columns)').duration} if params['h']
|
230
|
+
return @samples = @samples.sort_by(&:duration).reverse if params['h']
|
274
231
|
return @samples = @samples.sort{|x,y| x.params[:uri] <=> y.params[:uri]} if params['u']
|
275
232
|
@samples = @samples.reverse
|
276
233
|
end
|
@@ -281,7 +238,7 @@ module NewRelic
|
|
281
238
|
sample_id = id.to_i
|
282
239
|
@samples.each do |s|
|
283
240
|
if s.sample_id == sample_id
|
284
|
-
@sample =
|
241
|
+
@sample = s
|
285
242
|
return
|
286
243
|
end
|
287
244
|
end
|