newrelic_rpm 3.16.0.318 → 3.16.1.320
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +13 -4
- data/CHANGELOG +41 -2
- data/lib/new_relic/agent/database.rb +15 -4
- data/lib/new_relic/agent/database/explain_plan_helpers.rb +2 -1
- data/lib/new_relic/agent/datastores.rb +13 -13
- data/lib/new_relic/agent/datastores/metric_helper.rb +33 -2
- data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +3 -9
- data/lib/new_relic/agent/error_collector.rb +2 -2
- data/lib/new_relic/agent/instrumentation/active_record.rb +9 -19
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +2 -6
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +49 -40
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +29 -23
- data/lib/new_relic/agent/instrumentation/grape.rb +20 -11
- data/lib/new_relic/agent/instrumentation/memcache.rb +8 -10
- data/lib/new_relic/agent/instrumentation/mongo.rb +25 -16
- data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +14 -19
- data/lib/new_relic/agent/method_tracer_helpers.rb +4 -8
- data/lib/new_relic/agent/sql_sampler.rb +14 -1
- data/lib/new_relic/agent/stats_engine/metric_stats.rb +18 -0
- data/lib/new_relic/agent/supported_versions.rb +2 -3
- data/lib/new_relic/agent/traced_method_stack.rb +7 -1
- data/lib/new_relic/agent/transaction.rb +6 -0
- data/lib/new_relic/agent/transaction/abstract_segment.rb +73 -0
- data/lib/new_relic/agent/transaction/datastore_segment.rb +49 -0
- data/lib/new_relic/agent/transaction/segment.rb +30 -0
- data/lib/new_relic/agent/transaction/tracing.rb +53 -0
- data/lib/new_relic/agent/transaction_sampler.rb +8 -1
- data/lib/new_relic/noticed_error.rb +3 -1
- data/lib/new_relic/version.rb +1 -1
- data/lib/sequel/extensions/newrelic_instrumentation.rb +22 -15
- data/lib/sequel/plugins/newrelic_instrumentation.rb +4 -3
- data/newrelic_rpm.gemspec +1 -9
- data/test/environments/lib/environments/runner.rb +6 -4
- data/test/environments/norails/Gemfile +9 -3
- data/test/environments/rails21/Gemfile +6 -3
- data/test/environments/rails22/Gemfile +5 -2
- 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 +2 -2
- data/test/environments/rails41/Gemfile +2 -2
- data/test/environments/rails42/Gemfile +2 -2
- data/test/environments/rails50/Gemfile +2 -2
- data/test/helpers/mongo_metric_builder.rb +3 -4
- data/test/multiverse/lib/multiverse/shell_utils.rb +27 -0
- data/test/multiverse/lib/multiverse/suite.rb +47 -2
- data/test/multiverse/suites/active_record/Envfile +1 -1
- data/test/multiverse/suites/delayed_job/Envfile +2 -0
- data/test/multiverse/suites/grape/grape_versioning_test.rb +55 -1
- data/test/multiverse/suites/grape/grape_versioning_test_api.rb +61 -3
- data/test/multiverse/suites/mongo/mongo_instrumentation_test.rb +18 -0
- data/test/multiverse/suites/rails/Envfile +3 -3
- data/test/multiverse/suites/rails/error_tracing_test.rb +2 -2
- data/test/multiverse/suites/sequel/Envfile +7 -0
- data/test/multiverse/suites/sequel/sequel_extension_test.rb +1 -1
- data/test/new_relic/agent/database_test.rb +9 -0
- data/test/new_relic/agent/datastores/metric_helper_test.rb +76 -43
- data/test/new_relic/agent/datastores/mongo/metric_translator_test.rb +67 -117
- data/test/new_relic/agent/datastores_test.rb +17 -0
- data/test/new_relic/agent/error_collector_test.rb +21 -5
- data/test/new_relic/agent/instrumentation/active_record_helper_test.rb +40 -45
- data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +2 -3
- data/test/new_relic/agent/instrumentation/mongodb_command_subscriber_test.rb +2 -0
- data/test/new_relic/agent/method_tracer_test.rb +54 -52
- data/test/new_relic/agent/mock_scope_listener.rb +4 -1
- data/test/new_relic/agent/sql_sampler_test.rb +15 -0
- data/test/new_relic/agent/transaction/abstract_segment_test.rb +94 -0
- data/test/new_relic/agent/transaction/datastore_segment_test.rb +99 -0
- data/test/new_relic/agent/transaction/segment_test.rb +53 -0
- data/test/new_relic/agent/transaction/tracing_test.rb +121 -0
- data/test/new_relic/agent/transaction_sampler_test.rb +13 -0
- data/test/new_relic/noticed_error_test.rb +7 -0
- data/test/performance/suites/datastores.rb +59 -0
- data/test/performance/suites/trace_execution_scoped.rb +8 -9
- metadata +13 -46
@@ -133,30 +133,36 @@ module NewRelic
|
|
133
133
|
name = self.class.name
|
134
134
|
end
|
135
135
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
136
|
+
segment = NewRelic::Agent::Transaction.start_datastore_segment DATA_MAPPER, metric_operation, name
|
137
|
+
|
138
|
+
begin
|
139
|
+
self.send("#{method_name}_without_newrelic", *args, &blk)
|
140
|
+
rescue ::DataObjects::SQLError => e
|
141
|
+
e.uri.gsub!(PASSWORD_REGEX, AMPERSAND) if e.uri.include?(PASSWORD_PARAM)
|
142
|
+
|
143
|
+
strategy = NewRelic::Agent::Database.record_sql_method(:slow_sql)
|
144
|
+
case strategy
|
145
|
+
when :obfuscated
|
146
|
+
adapter_name = if self.respond_to?(:options)
|
147
|
+
self.options[:adapter]
|
148
|
+
else
|
149
|
+
if self.repository.adapter.respond_to?(:options)
|
150
|
+
self.repository.adapter.options[:adapter]
|
151
|
+
else
|
152
|
+
# DataMapper < 0.10.0
|
153
|
+
self.repository.adapter.uri.scheme
|
154
|
+
end
|
155
|
+
end
|
156
|
+
statement = NewRelic::Agent::Database::Statement.new(e.query, :adapter => adapter_name)
|
157
|
+
obfuscated_sql = NewRelic::Agent::Database.obfuscate_sql(statement)
|
158
|
+
e.instance_variable_set(:@query, obfuscated_sql)
|
159
|
+
when :off
|
160
|
+
e.instance_variable_set(:@query, nil)
|
159
161
|
end
|
162
|
+
|
163
|
+
raise
|
164
|
+
ensure
|
165
|
+
segment.finish
|
160
166
|
end
|
161
167
|
end
|
162
168
|
end
|
@@ -11,43 +11,51 @@ module NewRelic
|
|
11
11
|
extend self
|
12
12
|
|
13
13
|
API_ENDPOINT = 'api.endpoint'.freeze
|
14
|
+
API_VERSION = 'api.version'.freeze
|
14
15
|
FORMAT_REGEX = /\(\/?\.[\:\w]*\)/.freeze # either :format (< 0.12.0) or .ext (>= 0.12.0)
|
15
16
|
VERSION_REGEX = /:version(\/|$)/.freeze
|
16
17
|
EMPTY_STRING = ''.freeze
|
17
18
|
MIN_VERSION = VersionNumber.new("0.2.0")
|
19
|
+
PIPE_STRING = '|'.freeze
|
18
20
|
|
19
|
-
def handle_transaction(endpoint, class_name)
|
21
|
+
def handle_transaction(endpoint, class_name, version)
|
20
22
|
return unless endpoint && route = endpoint.route
|
21
|
-
name_transaction(route, class_name)
|
23
|
+
name_transaction(route, class_name, version)
|
22
24
|
capture_params(endpoint)
|
23
25
|
end
|
24
26
|
|
25
|
-
def name_transaction(route, class_name)
|
26
|
-
txn_name = name_for_transaction(route, class_name)
|
27
|
+
def name_transaction(route, class_name, version)
|
28
|
+
txn_name = name_for_transaction(route, class_name, version)
|
27
29
|
node_name = "Middleware/Grape/#{class_name}/call"
|
28
30
|
Transaction.set_default_transaction_name(txn_name, :grape, node_name)
|
29
31
|
end
|
30
32
|
|
31
33
|
if defined?(Grape::VERSION) && VersionNumber.new(::Grape::VERSION) >= VersionNumber.new("0.16.0")
|
32
|
-
def name_for_transaction(route, class_name)
|
34
|
+
def name_for_transaction(route, class_name, version)
|
33
35
|
action_name = route.path.sub(FORMAT_REGEX, EMPTY_STRING)
|
34
36
|
method_name = route.request_method
|
37
|
+
version ||= route.version
|
35
38
|
|
36
|
-
|
39
|
+
# defaulting does not set rack.env['api.version'] and route.version may return Array
|
40
|
+
#
|
41
|
+
version = version.join(PIPE_STRING) if Array === version
|
42
|
+
|
43
|
+
if version
|
37
44
|
action_name = action_name.sub(VERSION_REGEX, EMPTY_STRING)
|
38
|
-
"#{class_name}-#{
|
45
|
+
"#{class_name}-#{version}#{action_name} (#{method_name})"
|
39
46
|
else
|
40
47
|
"#{class_name}#{action_name} (#{method_name})"
|
41
48
|
end
|
42
49
|
end
|
43
50
|
else
|
44
|
-
def name_for_transaction(route, class_name)
|
51
|
+
def name_for_transaction(route, class_name, version)
|
45
52
|
action_name = route.route_path.sub(FORMAT_REGEX, EMPTY_STRING)
|
46
53
|
method_name = route.route_method
|
54
|
+
version ||= route.route_version
|
47
55
|
|
48
|
-
if
|
56
|
+
if version
|
49
57
|
action_name = action_name.sub(VERSION_REGEX, EMPTY_STRING)
|
50
|
-
"#{class_name}-#{
|
58
|
+
"#{class_name}-#{version}#{action_name} (#{method_name})"
|
51
59
|
else
|
52
60
|
"#{class_name}#{action_name} (#{method_name})"
|
53
61
|
end
|
@@ -108,7 +116,8 @@ DependencyDetection.defer do
|
|
108
116
|
ensure
|
109
117
|
begin
|
110
118
|
endpoint = env[::NewRelic::Agent::Instrumentation::GrapeInstrumentation::API_ENDPOINT]
|
111
|
-
::NewRelic::Agent::Instrumentation::GrapeInstrumentation
|
119
|
+
version = env[::NewRelic::Agent::Instrumentation::GrapeInstrumentation::API_VERSION]
|
120
|
+
::NewRelic::Agent::Instrumentation::GrapeInstrumentation.handle_transaction(endpoint, self.class.name, version)
|
112
121
|
rescue => e
|
113
122
|
::NewRelic::Agent.logger.warn("Error in Grape instrumentation", e)
|
114
123
|
end
|
@@ -40,17 +40,15 @@ module NewRelic
|
|
40
40
|
alias_method method_name_without, method_name
|
41
41
|
|
42
42
|
define_method method_name do |*args, &block|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
if NewRelic::Agent.config[:capture_memcache_keys]
|
51
|
-
NewRelic::Agent.instance.transaction_sampler.notice_nosql(args.first.inspect, (Time.now - t0).to_f) rescue nil
|
52
|
-
end
|
43
|
+
segment = NewRelic::Agent::Transaction.start_datastore_segment "Memcached", method_name
|
44
|
+
begin
|
45
|
+
send method_name_without, *args, &block
|
46
|
+
ensure
|
47
|
+
if NewRelic::Agent.config[:capture_memcache_keys]
|
48
|
+
NewRelic::Agent.instance.transaction_sampler.notice_nosql(args.first.inspect,
|
49
|
+
(Time.now - segment.start_time).to_f) rescue nil
|
53
50
|
end
|
51
|
+
segment.finish
|
54
52
|
end
|
55
53
|
end
|
56
54
|
|
@@ -65,23 +65,30 @@ DependencyDetection.defer do
|
|
65
65
|
NewRelic::Agent.logger.debug("Exception during Mongo statement gathering", e)
|
66
66
|
end
|
67
67
|
|
68
|
-
def
|
69
|
-
|
70
|
-
NewRelic::Agent::Datastores::Mongo::MetricTranslator.metrics_for(operation, payload)
|
68
|
+
def new_relic_default_payload
|
69
|
+
{ :collection => self.name, :database => self.db.name }
|
71
70
|
end
|
72
71
|
|
73
|
-
def
|
74
|
-
|
72
|
+
def new_relic_start_segment name, payload
|
73
|
+
product = NewRelic::Agent::Datastores::Mongo::MetricTranslator::MONGO_PRODUCT_NAME
|
74
|
+
op_and_col = NewRelic::Agent::Datastores::Mongo::MetricTranslator.operation_and_collection_for name, payload
|
75
|
+
if op_and_col
|
76
|
+
NewRelic::Agent::Transaction.start_datastore_segment product, *op_and_col
|
77
|
+
end
|
78
|
+
end
|
75
79
|
|
76
|
-
|
77
|
-
|
80
|
+
def instrument_with_new_relic_trace(name, payload = {}, &block)
|
81
|
+
segment = new_relic_start_segment name, payload
|
78
82
|
|
83
|
+
begin
|
79
84
|
result = NewRelic::Agent.disable_all_tracing do
|
80
85
|
instrument_without_new_relic_trace(name, payload, &block)
|
81
86
|
end
|
82
87
|
|
83
|
-
new_relic_notice_statement(
|
88
|
+
new_relic_notice_statement(segment.start_time, payload, name) if segment
|
84
89
|
result
|
90
|
+
ensure
|
91
|
+
segment.finish if segment
|
85
92
|
end
|
86
93
|
end
|
87
94
|
|
@@ -93,16 +100,17 @@ DependencyDetection.defer do
|
|
93
100
|
def instrument_save
|
94
101
|
::Mongo::Collection.class_eval do
|
95
102
|
def save_with_new_relic_trace(doc, opts = {}, &block)
|
96
|
-
|
97
|
-
trace_execution_scoped(metrics) do
|
98
|
-
t0 = Time.now
|
103
|
+
segment = new_relic_start_segment :save, new_relic_default_payload
|
99
104
|
|
105
|
+
begin
|
100
106
|
result = NewRelic::Agent.disable_all_tracing do
|
101
107
|
save_without_new_relic_trace(doc, opts, &block)
|
102
108
|
end
|
103
109
|
|
104
|
-
new_relic_notice_statement(
|
110
|
+
new_relic_notice_statement(segment.start_time, doc, :save) if segment
|
105
111
|
result
|
112
|
+
ensure
|
113
|
+
segment.finish if segment
|
106
114
|
end
|
107
115
|
end
|
108
116
|
|
@@ -114,10 +122,9 @@ DependencyDetection.defer do
|
|
114
122
|
def instrument_ensure_index
|
115
123
|
::Mongo::Collection.class_eval do
|
116
124
|
def ensure_index_with_new_relic_trace(spec, opts = {}, &block)
|
117
|
-
|
118
|
-
trace_execution_scoped(metrics) do
|
119
|
-
t0 = Time.now
|
125
|
+
segment = new_relic_start_segment :ensureIndex, new_relic_default_payload
|
120
126
|
|
127
|
+
begin
|
121
128
|
result = NewRelic::Agent.disable_all_tracing do
|
122
129
|
ensure_index_without_new_relic_trace(spec, opts, &block)
|
123
130
|
end
|
@@ -131,8 +138,10 @@ DependencyDetection.defer do
|
|
131
138
|
spec.dup
|
132
139
|
end
|
133
140
|
|
134
|
-
new_relic_notice_statement(
|
141
|
+
new_relic_notice_statement(segment.start_time, spec, :ensureIndex) if segment
|
135
142
|
result
|
143
|
+
ensure
|
144
|
+
segment.finish if segment
|
136
145
|
end
|
137
146
|
end
|
138
147
|
|
@@ -7,13 +7,13 @@ module NewRelic
|
|
7
7
|
module Agent
|
8
8
|
module Instrumentation
|
9
9
|
class MongodbCommandSubscriber
|
10
|
-
|
11
10
|
MONGODB = 'MongoDB'.freeze
|
12
11
|
COLLECTION = "collection".freeze
|
13
12
|
|
14
13
|
def started(event)
|
15
14
|
begin
|
16
15
|
return unless NewRelic::Agent.tl_is_execution_traced?
|
16
|
+
segments[event.operation_id] = start_segment event
|
17
17
|
operations[event.operation_id] = event
|
18
18
|
rescue Exception => e
|
19
19
|
log_notification_error('started', e)
|
@@ -25,14 +25,9 @@ module NewRelic
|
|
25
25
|
state = NewRelic::Agent::TransactionState.tl_get
|
26
26
|
return unless state.is_execution_traced?
|
27
27
|
started_event = operations.delete(event.operation_id)
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
NewRelic::Agent.instance.stats_engine.tl_record_scoped_and_unscoped_metrics(
|
32
|
-
base, other_metrics, event.duration
|
33
|
-
)
|
34
|
-
|
35
|
-
notice_nosql_statement(state, started_event, base, event.duration)
|
28
|
+
segment = segments.delete(event.operation_id)
|
29
|
+
notice_nosql_statement(state, started_event, segment.name, event.duration)
|
30
|
+
segment.finish
|
36
31
|
rescue Exception => e
|
37
32
|
log_notification_error('completed', e)
|
38
33
|
end
|
@@ -43,6 +38,12 @@ module NewRelic
|
|
43
38
|
|
44
39
|
private
|
45
40
|
|
41
|
+
def start_segment event
|
42
|
+
NewRelic::Agent::Transaction.start_datastore_segment(
|
43
|
+
MONGODB, event.command_name, collection(event)
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
46
47
|
def collection(event)
|
47
48
|
event.command[COLLECTION] || event.command[:collection] || event.command.values.first
|
48
49
|
end
|
@@ -60,6 +61,10 @@ module NewRelic
|
|
60
61
|
@operations ||= {}
|
61
62
|
end
|
62
63
|
|
64
|
+
def segments
|
65
|
+
@segments ||= {}
|
66
|
+
end
|
67
|
+
|
63
68
|
def generate_statement(event)
|
64
69
|
NewRelic::Agent::Datastores::Mongo::EventFormatter.format(
|
65
70
|
event.command_name,
|
@@ -69,19 +74,9 @@ module NewRelic
|
|
69
74
|
end
|
70
75
|
|
71
76
|
def notice_nosql_statement(state, event, metric, duration)
|
72
|
-
end_time = Time.now.to_f
|
73
|
-
|
74
|
-
stack = state.traced_method_stack
|
75
|
-
|
76
|
-
# enter transaction trace node
|
77
|
-
frame = stack.push_frame(state, :mongo_db, end_time - duration)
|
78
|
-
|
79
77
|
NewRelic::Agent.instance.transaction_sampler.notice_nosql_statement(
|
80
78
|
generate_statement(event), duration
|
81
79
|
)
|
82
|
-
|
83
|
-
# exit transaction trace node
|
84
|
-
stack.pop_frame(state, frame, metric, end_time)
|
85
80
|
end
|
86
81
|
end
|
87
82
|
end
|
@@ -74,19 +74,15 @@ module NewRelic
|
|
74
74
|
first_name = metric_names.shift
|
75
75
|
return yield unless first_name
|
76
76
|
|
77
|
-
|
78
|
-
|
79
|
-
expected_scope = trace_execution_scoped_header(state, start_time)
|
77
|
+
segment = NewRelic::Agent::Transaction.start_segment first_name, metric_names
|
78
|
+
segment.record_metrics = options.fetch(:metric, true)
|
80
79
|
|
81
80
|
begin
|
82
|
-
|
83
|
-
metric_names += Array(additional_metrics_callback.call) if additional_metrics_callback
|
84
|
-
result
|
81
|
+
yield
|
85
82
|
ensure
|
86
|
-
|
83
|
+
segment.finish
|
87
84
|
end
|
88
85
|
end
|
89
|
-
|
90
86
|
end
|
91
87
|
end
|
92
88
|
end
|
@@ -140,7 +140,7 @@ module NewRelic
|
|
140
140
|
# @api public
|
141
141
|
# @deprecated Use {Datastores.notice_sql} instead.
|
142
142
|
#
|
143
|
-
def notice_sql(sql, metric_name, config, duration, state=nil, explainer=nil, binds=
|
143
|
+
def notice_sql(sql, metric_name, config, duration, state=nil, explainer=nil, binds=nil, name=nil) #THREAD_LOCAL_ACCESS sometimes
|
144
144
|
state ||= TransactionState.tl_get
|
145
145
|
data = state.sql_sampler_transaction_data
|
146
146
|
return unless data
|
@@ -154,6 +154,19 @@ module NewRelic
|
|
154
154
|
end
|
155
155
|
end
|
156
156
|
|
157
|
+
def notice_sql_statement(statement, metric_name, duration)
|
158
|
+
state ||= TransactionState.tl_get
|
159
|
+
data = state.sql_sampler_transaction_data
|
160
|
+
return unless data
|
161
|
+
|
162
|
+
if state.is_sql_recorded?
|
163
|
+
if duration > Agent.config[:'slow_sql.explain_threshold']
|
164
|
+
backtrace = caller.join("\n")
|
165
|
+
data.sql_data << SlowSql.new(statement, metric_name, duration, backtrace)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
157
170
|
def merge!(sql_traces)
|
158
171
|
@samples_lock.synchronize do
|
159
172
|
sql_traces.each do |trace|
|
@@ -66,6 +66,15 @@ module NewRelic
|
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
69
|
+
# This aliasing was introduced for T2 so that MetricsStats and
|
70
|
+
# TransactionStates have the same interface for recording
|
71
|
+
# unscoped metrics. The tl_ version should be used outside of the
|
72
|
+
# segment api.
|
73
|
+
#
|
74
|
+
# @api private
|
75
|
+
#
|
76
|
+
alias_method :record_unscoped, :tl_record_unscoped_metrics
|
77
|
+
|
69
78
|
# Like tl_record_unscoped_metrics, but records a scoped metric as well.
|
70
79
|
#
|
71
80
|
# This is an internal method, subject to change at any time. Client apps
|
@@ -108,6 +117,15 @@ module NewRelic
|
|
108
117
|
end
|
109
118
|
end
|
110
119
|
|
120
|
+
# This aliasing was introduced for T2 so that MetricsStats and
|
121
|
+
# TransactionStates have the same interface for recording
|
122
|
+
# scoped metrics. The tl_ version should be used outside of the
|
123
|
+
# segment api.
|
124
|
+
#
|
125
|
+
# @api private
|
126
|
+
#
|
127
|
+
alias_method :record_scoped_and_unscoped, :tl_record_scoped_and_unscoped_metrics
|
128
|
+
|
111
129
|
# This method is deprecated and not thread safe, and should not be used
|
112
130
|
# by any new client code.
|
113
131
|
#
|
@@ -11,7 +11,7 @@ module NewRelic
|
|
11
11
|
{
|
12
12
|
:type => :ruby,
|
13
13
|
:name => "MRI",
|
14
|
-
:supported => ["1.8.7", "1.9.2", "1.9.3", "2.0.0", "~> 2.1.0", "~> 2.2.0" ],
|
14
|
+
:supported => ["1.8.7", "1.9.2", "1.9.3", "2.0.0", "~> 2.1.0", "~> 2.2.0", "~> 2.3.0"],
|
15
15
|
:url => "https://www.ruby-lang.org",
|
16
16
|
:feed => "https://www.ruby-lang.org/en/feeds/news.rss",
|
17
17
|
:notes => [
|
@@ -85,8 +85,7 @@ module NewRelic
|
|
85
85
|
:rails =>
|
86
86
|
{
|
87
87
|
:type => :web,
|
88
|
-
:supported => ["~>2.1.0", "~>2.2.0", "~>2.3.0", "~3.0.0", "~>3.1.0", "~>3.2.0", "~>4.0.0", "~>4.1.0", "~>4.2.0"],
|
89
|
-
:experimental=> ["5.0.0.rc1"],
|
88
|
+
:supported => ["~>2.1.0", "~>2.2.0", "~>2.3.0", "~3.0.0", "~>3.1.0", "~>3.2.0", "~>4.0.0", "~>4.1.0", "~>4.2.0", "~> 5.0.0"],
|
90
89
|
:deprecated => ["~>2.0.0"],
|
91
90
|
:url => "https://rubygems.org/gems/rails",
|
92
91
|
:feed => "https://rubygems.org/gems/rails/versions.atom",
|
@@ -37,6 +37,12 @@ module NewRelic
|
|
37
37
|
frame
|
38
38
|
end
|
39
39
|
|
40
|
+
def push_segment state, segment
|
41
|
+
transaction_sampler.notice_push_frame(state, segment.start_time) if sampler_enabled?
|
42
|
+
@stack.push segment
|
43
|
+
segment
|
44
|
+
end
|
45
|
+
|
40
46
|
# Pops a frame off the transaction stack - this updates the transaction
|
41
47
|
# sampler that we've finished execution of a traced method.
|
42
48
|
#
|
@@ -50,7 +56,7 @@ module NewRelic
|
|
50
56
|
note_children_time(frame, time, deduct_call_time_from_parent)
|
51
57
|
|
52
58
|
transaction_sampler.notice_pop_frame(state, name, time) if sampler_enabled?
|
53
|
-
frame.name = name
|
59
|
+
frame.name = name if frame.is_a? TracedMethodFrame
|
54
60
|
frame
|
55
61
|
end
|
56
62
|
|
@@ -8,6 +8,7 @@ require 'new_relic/agent/transaction_metrics'
|
|
8
8
|
require 'new_relic/agent/method_tracer_helpers'
|
9
9
|
require 'new_relic/agent/transaction/attributes'
|
10
10
|
require 'new_relic/agent/transaction/request_attributes'
|
11
|
+
require 'new_relic/agent/transaction/tracing'
|
11
12
|
|
12
13
|
module NewRelic
|
13
14
|
module Agent
|
@@ -16,6 +17,7 @@ module NewRelic
|
|
16
17
|
#
|
17
18
|
# @api public
|
18
19
|
class Transaction
|
20
|
+
include Tracing
|
19
21
|
|
20
22
|
# for nested transactions
|
21
23
|
SUBTRANSACTION_PREFIX = 'Nested/'.freeze
|
@@ -41,6 +43,9 @@ module NewRelic
|
|
41
43
|
TRACE_OPTIONS_SCOPED = { :metric => true, :scoped_metric => true }.freeze
|
42
44
|
TRACE_OPTIONS_UNSCOPED = { :metric => true, :scoped_metric => false }.freeze
|
43
45
|
|
46
|
+
# reference to the transaction state managing this transaction
|
47
|
+
attr_accessor :state
|
48
|
+
|
44
49
|
# A Time instance for the start time, never nil
|
45
50
|
attr_accessor :start_time
|
46
51
|
|
@@ -128,6 +133,7 @@ module NewRelic
|
|
128
133
|
def self.start_new_transaction(state, category, options)
|
129
134
|
txn = Transaction.new(category, options)
|
130
135
|
state.reset(txn)
|
136
|
+
txn.state = state
|
131
137
|
txn.start(state)
|
132
138
|
txn
|
133
139
|
end
|