newrelic_rpm 3.10.0.279 → 3.11.0.283
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/CHANGELOG +61 -0
- data/lib/new_relic/agent.rb +14 -8
- data/lib/new_relic/agent/agent.rb +43 -28
- data/lib/new_relic/agent/agent_logger.rb +21 -20
- data/lib/new_relic/agent/configuration/default_source.rb +31 -1
- data/lib/new_relic/agent/database.rb +2 -1
- data/lib/new_relic/agent/datastores.rb +177 -0
- data/lib/new_relic/agent/datastores/metric_helper.rb +85 -0
- data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +11 -20
- data/lib/new_relic/agent/deprecator.rb +18 -0
- data/lib/new_relic/agent/instrumentation/active_record.rb +20 -35
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +116 -57
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +11 -20
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +104 -172
- data/lib/new_relic/agent/instrumentation/memcache.rb +104 -52
- data/lib/new_relic/agent/instrumentation/metric_frame.rb +9 -0
- data/lib/new_relic/agent/instrumentation/middleware_proxy.rb +15 -2
- data/lib/new_relic/agent/instrumentation/mongo.rb +5 -18
- data/lib/new_relic/agent/instrumentation/sequel_helper.rb +36 -0
- data/lib/new_relic/agent/new_relic_service.rb +4 -0
- data/lib/new_relic/agent/stats_engine/metric_stats.rb +2 -17
- data/lib/new_relic/agent/threading/backtrace_service.rb +28 -5
- data/lib/new_relic/agent/transaction.rb +63 -34
- data/lib/new_relic/agent/transaction_event_aggregator.rb +0 -4
- data/lib/new_relic/agent/transaction_sampler.rb +11 -5
- data/lib/new_relic/rack/error_collector.rb +0 -1
- data/lib/new_relic/version.rb +1 -1
- data/lib/sequel/extensions/newrelic_instrumentation.rb +28 -56
- data/lib/sequel/plugins/newrelic_instrumentation.rb +28 -45
- data/newrelic_rpm.gemspec +0 -7
- data/test/agent_helper.rb +35 -16
- data/test/environments/rails31/Gemfile +1 -0
- data/test/environments/rails32/Gemfile +1 -0
- data/test/helpers/mongo_metric_builder.rb +2 -3
- data/test/multiverse/lib/multiverse/output_collector.rb +24 -9
- data/test/multiverse/lib/multiverse/suite.rb +5 -0
- data/test/multiverse/suites/active_record/Envfile +6 -4
- data/test/multiverse/suites/active_record/active_record_test.rb +32 -73
- data/test/multiverse/suites/active_record/ar_method_aliasing.rb +0 -1
- data/test/multiverse/suites/activemerchant/activemerchant_test.rb +0 -3
- data/test/multiverse/suites/agent_only/agent_run_id_handling_test.rb +0 -1
- data/test/multiverse/suites/agent_only/audit_log_test.rb +0 -1
- data/test/multiverse/suites/agent_only/collector_exception_handling_test.rb +0 -2
- data/test/multiverse/suites/agent_only/cross_application_tracing_test.rb +0 -1
- data/test/multiverse/suites/agent_only/custom_analytics_events_test.rb +0 -2
- data/test/multiverse/suites/agent_only/custom_queue_time_test.rb +0 -1
- data/test/multiverse/suites/agent_only/encoding_handling_test.rb +0 -2
- data/test/multiverse/suites/agent_only/exclusive_time_test.rb +0 -2
- data/test/multiverse/suites/agent_only/harvest_timestamps_test.rb +0 -1
- data/test/multiverse/suites/agent_only/http_response_code_test.rb +0 -1
- data/test/multiverse/suites/agent_only/keepalive_test.rb +0 -1
- data/test/multiverse/suites/agent_only/key_transactions_test.rb +54 -9
- data/test/multiverse/suites/agent_only/labels_test.rb +0 -2
- data/test/multiverse/suites/agent_only/logging_test.rb +0 -1
- data/test/multiverse/suites/agent_only/marshaling_test.rb +0 -1
- data/test/multiverse/suites/agent_only/pipe_manager_test.rb +0 -2
- data/test/multiverse/suites/agent_only/rename_rule_test.rb +5 -7
- data/test/multiverse/suites/agent_only/rum_instrumentation_test.rb +0 -1
- data/test/multiverse/suites/agent_only/set_transaction_name_test.rb +0 -2
- data/test/multiverse/suites/agent_only/ssl_test.rb +0 -2
- data/test/multiverse/suites/agent_only/synthetics_test.rb +0 -1
- data/test/multiverse/suites/agent_only/testing_app.rb +21 -0
- data/test/multiverse/suites/agent_only/thread_profiling_test.rb +1 -2
- data/test/multiverse/suites/agent_only/transaction_ignoring_test.rb +0 -2
- data/test/multiverse/suites/agent_only/utilization_data_collection_test.rb +0 -1
- data/test/multiverse/suites/agent_only/xray_sessions_test.rb +69 -34
- data/test/multiverse/suites/capistrano/deployment_test.rb +0 -1
- data/test/multiverse/suites/capistrano2/deployment_test.rb +0 -1
- data/test/multiverse/suites/config_file_loading/config_file_loading_test.rb +0 -2
- data/test/multiverse/suites/curb/curb_test.rb +0 -2
- data/test/multiverse/suites/datamapper/Envfile +26 -3
- data/test/multiverse/suites/datamapper/config/newrelic.yml +1 -0
- data/test/multiverse/suites/datamapper/datamapper_test.rb +271 -37
- data/test/multiverse/suites/deferred_instrumentation/sinatra_test.rb +0 -1
- data/test/multiverse/suites/delayed_job/Envfile +31 -8
- data/test/multiverse/suites/delayed_job/delayed_job_sampler_test.rb +0 -3
- data/test/multiverse/suites/delayed_job/unsupported_backend_test.rb +0 -3
- data/test/multiverse/suites/excon/excon_test.rb +0 -2
- data/test/multiverse/suites/grape/grape_test.rb +0 -3
- data/test/multiverse/suites/grape/grape_versioning_test.rb +0 -3
- data/test/multiverse/suites/grape/unsupported_version_test.rb +0 -3
- data/test/multiverse/suites/high_security/high_security_test.rb +0 -1
- data/test/multiverse/suites/httpclient/httpclient_test.rb +0 -2
- data/test/multiverse/suites/json/json_test.rb +0 -1
- data/test/multiverse/suites/marshalling/marshalling_test.rb +0 -1
- data/test/multiverse/suites/memcached/Envfile +52 -0
- data/test/multiverse/suites/memcached/dalli_test.rb +89 -0
- data/test/multiverse/suites/memcached/memcache_client_test.rb +25 -0
- data/test/multiverse/suites/memcached/memcache_test_cases.rb +302 -0
- data/test/multiverse/suites/memcached/memcached_test.rb +159 -0
- data/test/multiverse/suites/mongo/helpers/mongo_operation_tests.rb +26 -17
- data/test/multiverse/suites/mongo/mongo_connection_test.rb +0 -1
- data/test/multiverse/suites/mongo/mongo_instrumentation_test.rb +0 -1
- data/test/multiverse/suites/mongo/mongo_unsupported_version_test.rb +0 -1
- data/test/multiverse/suites/net_http/net_http_test.rb +0 -2
- data/test/multiverse/suites/padrino/padrino_test.rb +0 -3
- data/test/multiverse/suites/rack/http_response_code_test.rb +0 -1
- data/test/multiverse/suites/rack/nested_non_rack_app_test.rb +1 -1
- data/test/multiverse/suites/rack/rack_auto_instrumentation_test.rb +12 -12
- data/test/multiverse/suites/rack/rack_cascade_test.rb +0 -1
- data/test/multiverse/suites/rack/rack_env_mutation_test.rb +0 -1
- data/test/multiverse/suites/rack/rack_parameter_filtering_test.rb +0 -1
- data/test/multiverse/suites/rack/rack_unsupported_version_test.rb +0 -2
- data/test/multiverse/suites/rack/url_map_test.rb +3 -2
- data/test/multiverse/suites/rails/Envfile +3 -0
- data/test/multiverse/suites/rails/activejob_test.rb +0 -1
- data/test/multiverse/suites/rails/app.rb +0 -1
- data/test/multiverse/suites/rails/parameter_capture_test.rb +13 -0
- data/test/multiverse/suites/rails/rails3_app/app_rails3_plus.rb +5 -0
- data/test/multiverse/suites/rails/transaction_ignoring_test.rb +0 -2
- data/test/multiverse/suites/resque/instrumentation_test.rb +0 -2
- data/test/multiverse/suites/resque/resque_marshalling_test.rb +0 -1
- data/test/multiverse/suites/sequel/sequel_extension_test.rb +135 -0
- data/test/multiverse/suites/sequel/sequel_helpers.rb +62 -0
- data/test/multiverse/suites/sequel/sequel_plugin_test.rb +230 -0
- data/test/multiverse/suites/sidekiq/sidekiq_instrumentation_test.rb +0 -2
- data/test/multiverse/suites/sinatra/ignoring_test.rb +0 -2
- data/test/multiverse/suites/sinatra/nested_middleware_test.rb +0 -2
- data/test/multiverse/suites/sinatra/sinatra_classic_test.rb +0 -1
- data/test/multiverse/suites/sinatra/sinatra_error_tracing_test.rb +0 -2
- data/test/multiverse/suites/sinatra/sinatra_metric_explosion_test.rb +14 -12
- data/test/multiverse/suites/sinatra/sinatra_modular_test.rb +0 -1
- data/test/multiverse/suites/sinatra/sinatra_routes_test.rb +0 -2
- data/test/multiverse/suites/sinatra/sinatra_test_cases.rb +0 -2
- data/test/multiverse/suites/typhoeus/typhoeus_test.rb +0 -2
- data/test/multiverse/suites/yajl/yajl_test.rb +0 -1
- data/test/new_relic/agent/agent/start_test.rb +2 -2
- data/test/new_relic/agent/agent_logger_test.rb +6 -3
- data/test/new_relic/agent/datastores/metric_helper_test.rb +61 -0
- data/test/new_relic/agent/datastores/mongo/metric_translator_test.rb +20 -21
- data/test/new_relic/agent/datastores_test.rb +195 -0
- data/test/new_relic/agent/deprecator_test.rb +52 -0
- data/test/new_relic/agent/instrumentation/action_view_subscriber_test.rb +20 -26
- data/test/new_relic/agent/instrumentation/active_record_helper_test.rb +58 -53
- data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +7 -20
- data/test/new_relic/agent/instrumentation/middleware_proxy_test.rb +19 -0
- data/test/new_relic/agent/instrumentation/sequel_helper_test.rb +36 -0
- data/test/new_relic/agent/instrumentation/task_instrumentation_test.rb +1 -0
- data/test/new_relic/agent/method_tracer_test.rb +3 -4
- data/test/new_relic/agent/pipe_channel_manager_test.rb +1 -1
- data/test/new_relic/agent/threading/backtrace_service_test.rb +29 -4
- data/test/new_relic/agent/transaction_event_aggregator_test.rb +0 -4
- data/test/new_relic/agent/transaction_test.rb +100 -2
- data/test/new_relic/agent_test.rb +3 -3
- data/test/new_relic/http_client_test_cases.rb +0 -1
- data/test/new_relic/multiverse_helpers.rb +7 -0
- data/test/new_relic/transaction_ignoring_test_cases.rb +0 -2
- data/test/new_relic/transaction_sample_test.rb +11 -2
- data/test/performance/README.md +37 -17
- data/test/performance/lib/performance.rb +1 -0
- data/test/performance/lib/performance/baseline_compare_reporter.rb +11 -7
- data/test/performance/lib/performance/console_reporter.rb +29 -5
- data/test/performance/lib/performance/formatting_helpers.rb +22 -0
- data/test/performance/lib/performance/instrumentation/stackprof.rb +11 -1
- data/test/performance/lib/performance/result.rb +17 -6
- data/test/performance/lib/performance/runner.rb +7 -3
- data/test/performance/lib/performance/test_case.rb +89 -21
- data/test/performance/script/runner +13 -1
- data/test/performance/suites/active_record.rb +47 -0
- data/test/performance/suites/config.rb +4 -48
- data/test/performance/suites/marshalling.rb +20 -30
- data/test/performance/suites/queue_time.rb +1 -1
- data/test/performance/suites/rack_middleware.rb +1 -1
- data/test/performance/suites/rum_autoinsertion.rb +1 -1
- data/test/performance/suites/sql_obfuscation.rb +2 -2
- data/test/performance/suites/startup.rb +1 -1
- data/test/performance/suites/stats_hash.rb +7 -11
- data/test/performance/suites/thread_profiling.rb +20 -25
- data/test/performance/suites/trace_execution_scoped.rb +2 -2
- data/test/performance/suites/transaction_tracing.rb +4 -2
- data/test/test_helper.rb +5 -1
- metadata +53 -100
- data.tar.gz.sig +0 -0
- data/gem-public_cert.pem +0 -20
- data/lib/new_relic/agent/datastores/mongo/metric_generator.rb +0 -33
- data/test/multiverse/suites/sequel/sequel_instrumentation_test.rb +0 -289
- data/test/new_relic/agent/datastores/mongo/metric_generator_test.rb +0 -69
- data/test/new_relic/agent/memcache_instrumentation_test.rb +0 -155
- metadata.gz.sig +0 -2
@@ -2,6 +2,8 @@
|
|
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/deprecator'
|
6
|
+
|
5
7
|
module NewRelic
|
6
8
|
module Agent
|
7
9
|
module Instrumentation
|
@@ -17,11 +19,18 @@ module NewRelic
|
|
17
19
|
|
18
20
|
# @deprecated
|
19
21
|
def self.recording_web_transaction?
|
22
|
+
NewRelic::Agent::Deprecator.deprecate(
|
23
|
+
"NewRelic::Agent::Instrumentation::MetricFrame.recording_web_transaction?",
|
24
|
+
"NewRelic::Agent::Transaction.recording_web_transaction?")
|
25
|
+
|
20
26
|
Transaction.recording_web_transaction?
|
21
27
|
end
|
22
28
|
|
23
29
|
# @deprecated
|
24
30
|
def self.abort_transaction!
|
31
|
+
NewRelic::Agent::Deprecator.deprecate(
|
32
|
+
"NewRelic::Agent::Instrumentation::MetricFrame.abort_transaction!",
|
33
|
+
"NewRelic::Agent::Transaction.abort_transaction!")
|
25
34
|
Transaction.abort_transaction!
|
26
35
|
end
|
27
36
|
end
|
@@ -15,6 +15,9 @@ module NewRelic
|
|
15
15
|
class MiddlewareProxy
|
16
16
|
include MiddlewareTracing
|
17
17
|
|
18
|
+
ANONYMOUS_CLASS = "AnonymousClass".freeze unless defined?(ANONYMOUS_CLASS)
|
19
|
+
OBJECT_CLASS_NAME = "Object".freeze unless defined?(OBJECT_CLASS_NAME)
|
20
|
+
|
18
21
|
# This class is used to wrap classes that are passed to
|
19
22
|
# Rack::Builder#use without synchronously instantiating those classes.
|
20
23
|
# A MiddlewareProxy::Generator responds to new, like a Class would, and
|
@@ -84,12 +87,22 @@ module NewRelic
|
|
84
87
|
# to a singleton instance of the the subclass. We need to ensure that we
|
85
88
|
# capture the correct name in both cases.
|
86
89
|
def determine_class_name
|
90
|
+
clazz = class_for_target
|
91
|
+
|
92
|
+
name = clazz.name
|
93
|
+
name = clazz.superclass.name if name.nil? || name == ""
|
94
|
+
name = ANONYMOUS_CLASS if name.nil? || name == OBJECT_CLASS_NAME
|
95
|
+
name
|
96
|
+
end
|
97
|
+
|
98
|
+
def class_for_target
|
87
99
|
if @target.is_a?(Class)
|
88
|
-
@target
|
100
|
+
@target
|
89
101
|
else
|
90
|
-
@target.class
|
102
|
+
@target.class
|
91
103
|
end
|
92
104
|
end
|
105
|
+
|
93
106
|
end
|
94
107
|
end
|
95
108
|
end
|
@@ -20,7 +20,7 @@ DependencyDetection.defer do
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def install_mongo_instrumentation
|
23
|
-
require 'new_relic/agent/datastores/mongo/
|
23
|
+
require 'new_relic/agent/datastores/mongo/metric_translator'
|
24
24
|
require 'new_relic/agent/datastores/mongo/statement_formatter'
|
25
25
|
|
26
26
|
hook_instrument_methods
|
@@ -39,19 +39,6 @@ DependencyDetection.defer do
|
|
39
39
|
target_class.class_eval do
|
40
40
|
include NewRelic::Agent::MethodTracer
|
41
41
|
|
42
|
-
def new_relic_instance_metric_builder
|
43
|
-
Proc.new do
|
44
|
-
if @pool
|
45
|
-
host, port = @pool.host, @pool.port
|
46
|
-
elsif @connection && (primary = @connection.primary)
|
47
|
-
host, port = primary[0], primary[1]
|
48
|
-
end
|
49
|
-
|
50
|
-
database_name = @db.name if @db
|
51
|
-
NewRelic::Agent::Datastores::Mongo::MetricGenerator.generate_instance_metric_for(host, port, database_name)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
42
|
# It's key that this method eats all exceptions, as it rests between the
|
56
43
|
# Mongo operation the user called and us returning them the data. Be safe!
|
57
44
|
def new_relic_notice_statement(t0, payload, name)
|
@@ -65,13 +52,13 @@ DependencyDetection.defer do
|
|
65
52
|
|
66
53
|
def new_relic_generate_metrics(operation, payload = nil)
|
67
54
|
payload ||= { :collection => self.name, :database => self.db.name }
|
68
|
-
NewRelic::Agent::Datastores::Mongo::
|
55
|
+
NewRelic::Agent::Datastores::Mongo::MetricTranslator.metrics_for(operation, payload)
|
69
56
|
end
|
70
57
|
|
71
58
|
def instrument_with_new_relic_trace(name, payload = {}, &block)
|
72
59
|
metrics = new_relic_generate_metrics(name, payload)
|
73
60
|
|
74
|
-
trace_execution_scoped(metrics
|
61
|
+
trace_execution_scoped(metrics) do
|
75
62
|
t0 = Time.now
|
76
63
|
|
77
64
|
result = NewRelic::Agent.disable_all_tracing do
|
@@ -92,7 +79,7 @@ DependencyDetection.defer do
|
|
92
79
|
::Mongo::Collection.class_eval do
|
93
80
|
def save_with_new_relic_trace(doc, opts = {}, &block)
|
94
81
|
metrics = new_relic_generate_metrics(:save)
|
95
|
-
trace_execution_scoped(metrics
|
82
|
+
trace_execution_scoped(metrics) do
|
96
83
|
t0 = Time.now
|
97
84
|
|
98
85
|
result = NewRelic::Agent.disable_all_tracing do
|
@@ -113,7 +100,7 @@ DependencyDetection.defer do
|
|
113
100
|
::Mongo::Collection.class_eval do
|
114
101
|
def ensure_index_with_new_relic_trace(spec, opts = {}, &block)
|
115
102
|
metrics = new_relic_generate_metrics(:ensureIndex)
|
116
|
-
trace_execution_scoped(metrics
|
103
|
+
trace_execution_scoped(metrics) do
|
117
104
|
t0 = Time.now
|
118
105
|
|
119
106
|
result = NewRelic::Agent.disable_all_tracing do
|
@@ -0,0 +1,36 @@
|
|
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
|
+
module NewRelic
|
6
|
+
module Agent
|
7
|
+
module Instrumentation
|
8
|
+
module SequelHelper
|
9
|
+
extend self
|
10
|
+
|
11
|
+
# Fallback if the product cannot be determined
|
12
|
+
DEFAULT_PRODUCT_NAME = "Sequel".freeze
|
13
|
+
|
14
|
+
# A Sequel adapter is called an "adapter_scheme" and can be accessed from
|
15
|
+
# the database:
|
16
|
+
#
|
17
|
+
# DB.adapter_scheme
|
18
|
+
PRODUCT_NAMES = {
|
19
|
+
:ibmdb => "IBMDB2",
|
20
|
+
:firebird => "Firebird",
|
21
|
+
:informix => "Informix",
|
22
|
+
:jdbc => "JDBC",
|
23
|
+
:mysql => "MySQL",
|
24
|
+
:mysql2 => "MySQL",
|
25
|
+
:oracle => "Oracle",
|
26
|
+
:postgres => "Postgres",
|
27
|
+
:sqlite => "SQLite"
|
28
|
+
}.freeze
|
29
|
+
|
30
|
+
def product_name_from_adapter(adapter)
|
31
|
+
PRODUCT_NAMES.fetch(adapter, DEFAULT_PRODUCT_NAME)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -301,6 +301,10 @@ module NewRelic
|
|
301
301
|
http_class = Net::HTTP::Proxy(proxy_server.name, proxy_server.port,
|
302
302
|
proxy_server.user, proxy_server.password)
|
303
303
|
|
304
|
+
if proxy_server.name
|
305
|
+
::NewRelic::Agent.logger.debug("Using proxy server #{proxy_server.name}:#{proxy_server.port}")
|
306
|
+
end
|
307
|
+
|
304
308
|
conn = http_class.new((@collector.ip || @collector.name), @collector.port)
|
305
309
|
setup_connection_for_ssl(conn) if Agent.config[:ssl]
|
306
310
|
setup_connection_timeouts(conn)
|
@@ -150,14 +150,6 @@ module NewRelic
|
|
150
150
|
stats
|
151
151
|
end
|
152
152
|
|
153
|
-
# Returns a stat if one exists, otherwise returns nil.
|
154
|
-
def lookup_stats(metric_name, scope_name = '')
|
155
|
-
spec = NewRelic::MetricSpec.new(metric_name, scope_name)
|
156
|
-
with_stats_lock do
|
157
|
-
@stats_hash.has_key?(spec) ? @stats_hash[spec] : nil
|
158
|
-
end
|
159
|
-
end
|
160
|
-
|
161
153
|
# Helper for recording a straight value into the count
|
162
154
|
def tl_record_supportability_metric_count(metric, value)
|
163
155
|
real_name = "Supportability/#{metric}"
|
@@ -233,16 +225,9 @@ module NewRelic
|
|
233
225
|
NewRelic::Agent::BusyCalculator.reset
|
234
226
|
end
|
235
227
|
|
236
|
-
# Returns all of the metric names of all the stats in the engine.
|
237
228
|
# For use by test code only.
|
238
|
-
def
|
239
|
-
with_stats_lock
|
240
|
-
@stats_hash.keys.map { |spec| spec.to_s }
|
241
|
-
end
|
242
|
-
end
|
243
|
-
|
244
|
-
def metric_specs
|
245
|
-
with_stats_lock { @stats_hash.keys }
|
229
|
+
def to_h
|
230
|
+
with_stats_lock { Hash[@stats_hash] }
|
246
231
|
end
|
247
232
|
end
|
248
233
|
end
|
@@ -9,7 +9,14 @@ module NewRelic
|
|
9
9
|
ALL_TRANSACTIONS = "**ALL**".freeze
|
10
10
|
|
11
11
|
def self.is_supported?
|
12
|
-
RUBY_VERSION >= "1.9.2"
|
12
|
+
RUBY_VERSION >= "1.9.2" && !is_resque?
|
13
|
+
end
|
14
|
+
|
15
|
+
# Because of Resque's forking, we don't poll thread backtraces for it.
|
16
|
+
# To accomplish that would require starting a new backtracing thread in
|
17
|
+
# each forked worker, and merging profiles across the pipe channel.
|
18
|
+
def self.is_resque?
|
19
|
+
NewRelic::Agent.config[:dispatcher] == :resque
|
13
20
|
end
|
14
21
|
|
15
22
|
attr_reader :worker_loop, :buffer, :effective_polling_period,
|
@@ -45,6 +52,11 @@ module NewRelic
|
|
45
52
|
end
|
46
53
|
|
47
54
|
def subscribe(transaction_name, command_arguments={})
|
55
|
+
if self.class.is_resque?
|
56
|
+
NewRelic::Agent.logger.info("Backtracing threads on Resque is not supported, so not subscribing transaction '#{transaction_name}'")
|
57
|
+
return
|
58
|
+
end
|
59
|
+
|
48
60
|
if !self.class.is_supported?
|
49
61
|
NewRelic::Agent.logger.debug("Backtracing not supported, so not subscribing transaction '#{transaction_name}'")
|
50
62
|
return
|
@@ -104,10 +116,11 @@ module NewRelic
|
|
104
116
|
start = payload[:start_timestamp]
|
105
117
|
duration = payload[:duration]
|
106
118
|
thread = payload[:thread] || Thread.current
|
119
|
+
bucket = payload[:bucket]
|
107
120
|
@lock.synchronize do
|
108
121
|
backtraces = @buffer.delete(thread)
|
109
122
|
if backtraces && @profiles.has_key?(name)
|
110
|
-
aggregate_backtraces(backtraces, name, start, duration, thread)
|
123
|
+
aggregate_backtraces(backtraces, name, start, duration, bucket, thread)
|
111
124
|
end
|
112
125
|
end
|
113
126
|
end
|
@@ -115,11 +128,11 @@ module NewRelic
|
|
115
128
|
# Internals
|
116
129
|
|
117
130
|
# This method is expected to be called with @lock held.
|
118
|
-
def aggregate_backtraces(backtraces, name, start, duration, thread)
|
131
|
+
def aggregate_backtraces(backtraces, name, start, duration, bucket, thread)
|
119
132
|
end_time = start + duration
|
120
133
|
backtraces.each do |(timestamp, backtrace)|
|
121
134
|
if timestamp >= start && timestamp < end_time
|
122
|
-
@profiles[name].aggregate(backtrace,
|
135
|
+
@profiles[name].aggregate(backtrace, bucket, thread)
|
123
136
|
end
|
124
137
|
end
|
125
138
|
end
|
@@ -169,7 +182,7 @@ module NewRelic
|
|
169
182
|
|
170
183
|
# This method is expected to be called with @lock held.
|
171
184
|
def should_buffer?(bucket)
|
172
|
-
bucket
|
185
|
+
allowed_bucket?(bucket) && watching_for_transaction?
|
173
186
|
end
|
174
187
|
|
175
188
|
# This method is expected to be called with @lock held.
|
@@ -180,6 +193,16 @@ module NewRelic
|
|
180
193
|
)
|
181
194
|
end
|
182
195
|
|
196
|
+
# This method is expected to be called with @lock held
|
197
|
+
def watching_for_transaction?
|
198
|
+
@profiles.size > 1 ||
|
199
|
+
(@profiles.size == 1 && @profiles[ALL_TRANSACTIONS].nil?)
|
200
|
+
end
|
201
|
+
|
202
|
+
def allowed_bucket?(bucket)
|
203
|
+
bucket == :request || bucket == :background
|
204
|
+
end
|
205
|
+
|
183
206
|
MAX_BUFFER_LENGTH = 500
|
184
207
|
|
185
208
|
# This method is expected to be called with @lock held.
|
@@ -56,10 +56,6 @@ module NewRelic
|
|
56
56
|
# as a Rack::Request or an ActionController::AbstractRequest.
|
57
57
|
attr_accessor :request
|
58
58
|
|
59
|
-
# This is the name of the model currently assigned to database
|
60
|
-
# measurements, overriding the default.
|
61
|
-
attr_reader :database_metric_name
|
62
|
-
|
63
59
|
attr_reader :guid,
|
64
60
|
:metrics,
|
65
61
|
:gc_start_snapshot,
|
@@ -302,6 +298,24 @@ module NewRelic
|
|
302
298
|
@ignore_enduser = false
|
303
299
|
end
|
304
300
|
|
301
|
+
# This transaction-local hash may be used as temprory storage by
|
302
|
+
# instrumentation that needs to pass data from one instrumentation point
|
303
|
+
# to another.
|
304
|
+
#
|
305
|
+
# For example, if both A and B are instrumented, and A calls B
|
306
|
+
# but some piece of state needed by the instrumentation at B is only
|
307
|
+
# available at A, the instrumentation at A may write into the hash, call
|
308
|
+
# through, and then remove the key afterwards, allowing the
|
309
|
+
# instrumentation at B to read the value in between.
|
310
|
+
#
|
311
|
+
# Keys should be symbols, and care should be taken to not generate key
|
312
|
+
# names dynamically, and to ensure that keys are removed upon return from
|
313
|
+
# the method that creates them.
|
314
|
+
#
|
315
|
+
def instrumentation_state
|
316
|
+
@instrumentation_state ||= {}
|
317
|
+
end
|
318
|
+
|
305
319
|
def noticed_error_ids
|
306
320
|
@noticed_error_ids ||= []
|
307
321
|
end
|
@@ -534,6 +548,7 @@ module NewRelic
|
|
534
548
|
duration = end_time.to_f - start_time.to_f
|
535
549
|
payload = {
|
536
550
|
:name => @frozen_name,
|
551
|
+
:bucket => recording_web_transaction? ? :request : :background,
|
537
552
|
:start_timestamp => start_time.to_f,
|
538
553
|
:duration => duration,
|
539
554
|
:metrics => @metrics,
|
@@ -613,9 +628,14 @@ module NewRelic
|
|
613
628
|
APDEX_F = 'F'.freeze
|
614
629
|
|
615
630
|
def append_apdex_perf_zone(duration, payload)
|
616
|
-
|
631
|
+
if recording_web_transaction?
|
632
|
+
bucket = apdex_bucket(duration, apdex_t)
|
633
|
+
elsif background_apdex_t = transaction_specific_apdex_t
|
634
|
+
bucket = apdex_bucket(duration, background_apdex_t)
|
635
|
+
end
|
636
|
+
|
637
|
+
return unless bucket
|
617
638
|
|
618
|
-
bucket = apdex_bucket(duration)
|
619
639
|
bucket_str = case bucket
|
620
640
|
when :apdex_s then APDEX_S
|
621
641
|
when :apdex_t then APDEX_T
|
@@ -708,32 +728,54 @@ module NewRelic
|
|
708
728
|
end
|
709
729
|
end
|
710
730
|
|
711
|
-
|
731
|
+
APDEX_ALL_METRIC = 'ApdexAll'.freeze
|
732
|
+
|
733
|
+
APDEX_METRIC = 'Apdex'.freeze
|
734
|
+
APDEX_OTHER_METRIC = 'ApdexOther'.freeze
|
735
|
+
|
736
|
+
APDEX_TXN_METRIC_PREFIX = 'Apdex/'.freeze
|
737
|
+
APDEX_OTHER_TXN_METRIC_PREFIX = 'ApdexOther/Transaction/'.freeze
|
712
738
|
|
713
739
|
def had_error?
|
714
|
-
|
740
|
+
@exceptions.each do |exception, _|
|
741
|
+
return true unless NewRelic::Agent.instance.error_collector.error_is_ignored?(exception)
|
742
|
+
end
|
743
|
+
false
|
715
744
|
end
|
716
745
|
|
717
|
-
def apdex_bucket(duration)
|
718
|
-
self.class.apdex_bucket(duration, had_error?,
|
746
|
+
def apdex_bucket(duration, current_apdex_t)
|
747
|
+
self.class.apdex_bucket(duration, had_error?, current_apdex_t)
|
719
748
|
end
|
720
749
|
|
721
750
|
def record_apdex(state, end_time=Time.now)
|
722
|
-
return unless
|
751
|
+
return unless state.is_execution_traced?
|
723
752
|
|
724
753
|
freeze_name_and_execute_if_not_ignored do
|
725
|
-
action_duration = end_time - start_time
|
726
754
|
total_duration = end_time - apdex_start
|
755
|
+
action_duration = end_time - start_time
|
727
756
|
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
757
|
+
if recording_web_transaction?
|
758
|
+
record_apdex_metrics(APDEX_METRIC, APDEX_TXN_METRIC_PREFIX,
|
759
|
+
total_duration, action_duration, apdex_t)
|
760
|
+
else
|
761
|
+
record_apdex_metrics(APDEX_OTHER_METRIC, APDEX_OTHER_TXN_METRIC_PREFIX,
|
762
|
+
total_duration, action_duration, transaction_specific_apdex_t)
|
763
|
+
end
|
734
764
|
end
|
735
765
|
end
|
736
766
|
|
767
|
+
def record_apdex_metrics(rollup_metric, transaction_prefix, total_duration, action_duration, current_apdex_t)
|
768
|
+
return unless current_apdex_t
|
769
|
+
|
770
|
+
apdex_bucket_global = apdex_bucket(total_duration, current_apdex_t)
|
771
|
+
apdex_bucket_txn = apdex_bucket(action_duration, current_apdex_t)
|
772
|
+
|
773
|
+
@metrics.record_unscoped(rollup_metric, apdex_bucket_global, current_apdex_t)
|
774
|
+
@metrics.record_unscoped(APDEX_ALL_METRIC, apdex_bucket_global, current_apdex_t)
|
775
|
+
txn_apdex_metric = @frozen_name.gsub(/^[^\/]+\//, transaction_prefix)
|
776
|
+
@metrics.record_unscoped(txn_apdex_metric, apdex_bucket_txn, current_apdex_t)
|
777
|
+
end
|
778
|
+
|
737
779
|
def apdex_t
|
738
780
|
transaction_specific_apdex_t || Agent.config[:apdex_t]
|
739
781
|
end
|
@@ -743,15 +785,8 @@ module NewRelic
|
|
743
785
|
Agent.config[key] && Agent.config[key][best_name]
|
744
786
|
end
|
745
787
|
|
746
|
-
# Yield to a block that is run with a database metric name context. This means
|
747
|
-
# the Database instrumentation will use this for the metric name if it does not
|
748
|
-
# otherwise know about a model. This is re-entrant.
|
749
|
-
#
|
750
|
-
# * <tt>model</tt> is the DB model class
|
751
|
-
# * <tt>method</tt> is the name of the finder method or other method to identify the operation with.
|
752
|
-
#
|
753
788
|
def with_database_metric_name(model, method)
|
754
|
-
previous =
|
789
|
+
previous = self.instrumentation_state[:datastore_override]
|
755
790
|
model_name = case model
|
756
791
|
when Class
|
757
792
|
model.name
|
@@ -760,10 +795,10 @@ module NewRelic
|
|
760
795
|
else
|
761
796
|
model.to_s
|
762
797
|
end
|
763
|
-
|
798
|
+
self.instrumentation_state[:datastore_override] = [method, model_name]
|
764
799
|
yield
|
765
800
|
ensure
|
766
|
-
|
801
|
+
self.instrumentation_state[:datastore_override] = previous
|
767
802
|
end
|
768
803
|
|
769
804
|
def custom_parameters
|
@@ -839,12 +874,6 @@ module NewRelic
|
|
839
874
|
@ignore_enduser
|
840
875
|
end
|
841
876
|
|
842
|
-
def notable_exceptions
|
843
|
-
@exceptions.keys.select do |exception|
|
844
|
-
!NewRelic::Agent.instance.error_collector.error_is_ignored?(exception)
|
845
|
-
end
|
846
|
-
end
|
847
|
-
|
848
877
|
private
|
849
878
|
|
850
879
|
def process_cpu
|