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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ec626b83799ad14fe3e3534083621d692bfbd138
|
4
|
+
data.tar.gz: 0593104dbbfb3f5faa967043e7025e42991ce168
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3caec728f33c30b9149c5c01e27d9c573562268f19cc69a06416af69634e622c25e11cb2a9267082615b063b8f3963cb62de03ab97b9d6ddfb6aa721b18d7d66
|
7
|
+
data.tar.gz: 688803e2468ece921d1c4b18dd3f81bb3d7c5ddc41d6ecf0ebb24fef10db0fcfe8ca85d8f329f71a8126769e7bd6c036a9fe2234bee373eed29852dfbf71245f
|
data/.travis.yml
CHANGED
@@ -45,7 +45,8 @@ rvm:
|
|
45
45
|
# Run slowest builds first to try and optimize overall cycle time.
|
46
46
|
- jruby-1.7.23
|
47
47
|
- jruby-9.0.4.0
|
48
|
-
- 2.
|
48
|
+
- 2.3.1
|
49
|
+
- 2.2.5
|
49
50
|
- 2.1.8
|
50
51
|
- 2.0.0-p648
|
51
52
|
- 1.9.3
|
@@ -97,12 +98,20 @@ matrix:
|
|
97
98
|
env: TYPE=FUNCTIONAL GROUP=agent
|
98
99
|
|
99
100
|
# Unsupported Rails/Ruby combinations
|
101
|
+
# 2.3
|
102
|
+
- rvm: 2.3.1
|
103
|
+
env: TYPE=UNIT ENVIRONMENT=rails21
|
104
|
+
- rvm: 2.3.1
|
105
|
+
env: TYPE=UNIT ENVIRONMENT=rails22
|
106
|
+
- rvm: 2.3.1
|
107
|
+
env: TYPE=UNIT ENVIRONMENT=rails23
|
108
|
+
|
100
109
|
# 2.2
|
101
|
-
- rvm: 2.2.
|
110
|
+
- rvm: 2.2.5
|
102
111
|
env: TYPE=UNIT ENVIRONMENT=rails21
|
103
|
-
- rvm: 2.2.
|
112
|
+
- rvm: 2.2.5
|
104
113
|
env: TYPE=UNIT ENVIRONMENT=rails22
|
105
|
-
- rvm: 2.2.
|
114
|
+
- rvm: 2.2.5
|
106
115
|
env: TYPE=UNIT ENVIRONMENT=rails23
|
107
116
|
|
108
117
|
# 2.1
|
data/CHANGELOG
CHANGED
@@ -1,11 +1,50 @@
|
|
1
1
|
# New Relic Ruby Agent Release Notes #
|
2
2
|
|
3
|
+
## v3.16.1
|
4
|
+
|
5
|
+
* Internal datastore instrumentation rewrites
|
6
|
+
|
7
|
+
The agent's internal tracing of datastore segments has been rewritten, and
|
8
|
+
instrumentation updated to utilize the new classes.
|
9
|
+
|
10
|
+
* Fix Grape endpoint versions in transaction names
|
11
|
+
|
12
|
+
Grape 0.16 changed Route#version (formerly #route_version) to possibly return
|
13
|
+
an Array of versions for the current endpoint. The agent has been updated to
|
14
|
+
use rack.env['api.version'] set by Grape, and fall back to joining the version
|
15
|
+
Array with '|' before inclusion in the transaction name when api.version is
|
16
|
+
not available. Thanks Geoff Massanek for the contribution!
|
17
|
+
|
18
|
+
* Fix deprecation warnings from various Rails error subclasses
|
19
|
+
|
20
|
+
Rails 5 deprecates #original_exception on a few internal subclasses of
|
21
|
+
StandardError in favor of Exception#cause from Ruby stdlib. The agent has
|
22
|
+
been updated to try Exception#cause first, thus avoiding deprecation
|
23
|
+
warnings. Thanks Alexander Stuart-Kregor for the contribution!
|
24
|
+
|
25
|
+
* Fix instrumentation for Sequel 4.35.0
|
26
|
+
|
27
|
+
The latest version of Sequel changes the name and signature of the method
|
28
|
+
that the Ruby Agent wraps for instrumentation. The agent has been updated
|
29
|
+
to handle these changes. Users using Sequel 4.35.0 or newer should upgrade
|
30
|
+
their agent.
|
31
|
+
|
32
|
+
* Fix DataMapper instrumentation for additional versions
|
33
|
+
|
34
|
+
Different versions of DataMapper have different methods for retrieving the
|
35
|
+
adapter name, and Postmodern expanded our coverage. Thanks for the
|
36
|
+
contribution!
|
37
|
+
|
3
38
|
## v3.16.0
|
4
39
|
|
5
|
-
*
|
40
|
+
* Official Rails 5.0 support
|
41
|
+
|
42
|
+
This version of the agent has been verified against the Rails 5.0.0 release.
|
43
|
+
|
44
|
+
* Early access Action Cable instrumentation
|
6
45
|
|
7
46
|
The Ruby agent instruments Action Cable channel actions and calls to
|
8
|
-
ActionCable::Channel#Transmit in Rails 5
|
47
|
+
ActionCable::Channel#Transmit in Rails 5. Feedback is welcome!
|
9
48
|
|
10
49
|
* Obfuscate queries from `oracle_enhanced` adapter correctly
|
11
50
|
|
@@ -27,8 +27,17 @@ module NewRelic
|
|
27
27
|
|
28
28
|
extend self
|
29
29
|
|
30
|
+
# Properly encode, truncate, and dup the incoming query.
|
31
|
+
# Take care not to the dup the query more than once as
|
32
|
+
# correctly encoded may also dup the query.
|
30
33
|
def capture_query(query)
|
31
|
-
|
34
|
+
id = query.object_id
|
35
|
+
query = Helper.correctly_encoded(truncate_query(query))
|
36
|
+
if query.object_id == id
|
37
|
+
query.dup
|
38
|
+
else
|
39
|
+
query
|
40
|
+
end
|
32
41
|
end
|
33
42
|
|
34
43
|
def truncate_query(query)
|
@@ -176,7 +185,7 @@ module NewRelic
|
|
176
185
|
|
177
186
|
DEFAULT_QUERY_NAME = "SQL".freeze
|
178
187
|
|
179
|
-
def initialize(sql, config={}, explainer=nil, binds=
|
188
|
+
def initialize(sql, config={}, explainer=nil, binds=nil, name=DEFAULT_QUERY_NAME)
|
180
189
|
@sql = Database.capture_query(sql)
|
181
190
|
@config = config
|
182
191
|
@explainer = explainer
|
@@ -232,15 +241,17 @@ module NewRelic
|
|
232
241
|
end
|
233
242
|
end
|
234
243
|
|
244
|
+
ELLIPSIS = "...".freeze
|
245
|
+
|
235
246
|
def explainable?
|
236
247
|
return false unless @explainer && is_select?(@sql)
|
237
248
|
|
238
|
-
if @sql
|
249
|
+
if @sql.end_with?(ELLIPSIS)
|
239
250
|
NewRelic::Agent.logger.debug('Unable to collect explain plan for truncated query.')
|
240
251
|
return false
|
241
252
|
end
|
242
253
|
|
243
|
-
if parameterized?(@sql) && @binds.empty?
|
254
|
+
if parameterized?(@sql) && (!@binds || @binds.empty?)
|
244
255
|
NewRelic::Agent.logger.debug('Unable to collect explain plan for parameter-less parameterized query.')
|
245
256
|
return false
|
246
257
|
end
|
@@ -11,9 +11,10 @@ module NewRelic
|
|
11
11
|
module ExplainPlanHelpers
|
12
12
|
|
13
13
|
SUPPORTED_ADAPTERS_FOR_EXPLAIN = [:postgres, :mysql2, :mysql, :sqlite]
|
14
|
+
SELECT = 'select'.freeze
|
14
15
|
|
15
16
|
def is_select?(sql)
|
16
|
-
NewRelic::Agent::Database.parse_operation_from_query(sql) ==
|
17
|
+
NewRelic::Agent::Database.parse_operation_from_query(sql) == SELECT
|
17
18
|
end
|
18
19
|
|
19
20
|
def parameterized?(sql)
|
@@ -45,9 +45,11 @@ module NewRelic
|
|
45
45
|
alias_method method_name_without_newrelic, method_name
|
46
46
|
|
47
47
|
define_method(method_name) do |*args, &blk|
|
48
|
-
|
49
|
-
|
48
|
+
segment = NewRelic::Agent::Transaction.start_datastore_segment(product, operation)
|
49
|
+
begin
|
50
50
|
send(method_name_without_newrelic, *args, &blk)
|
51
|
+
ensure
|
52
|
+
segment.finish
|
51
53
|
end
|
52
54
|
end
|
53
55
|
|
@@ -103,18 +105,16 @@ module NewRelic
|
|
103
105
|
def self.wrap(product, operation, collection = nil, callback = nil)
|
104
106
|
return yield unless operation
|
105
107
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
elapsed_time = (Time.now - t0).to_f
|
115
|
-
callback.call(result, scoped_metric, elapsed_time)
|
116
|
-
end
|
108
|
+
segment = NewRelic::Agent::Transaction.start_datastore_segment(product, operation, collection)
|
109
|
+
|
110
|
+
begin
|
111
|
+
result = yield
|
112
|
+
ensure
|
113
|
+
if callback
|
114
|
+
elapsed_time = (Time.now - segment.start_time).to_f
|
115
|
+
callback.call(result, segment.name, elapsed_time)
|
117
116
|
end
|
117
|
+
segment.finish
|
118
118
|
end
|
119
119
|
end
|
120
120
|
|
@@ -44,14 +44,41 @@ module NewRelic
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
def self.
|
47
|
+
def self.scoped_metric_for product, operation, collection=nil
|
48
|
+
if collection
|
49
|
+
statement_metric_for product, collection, operation
|
50
|
+
else
|
51
|
+
operation_metric_for product, operation
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.unscoped_metrics_for product, operation, collection=nil
|
56
|
+
suffix = all_suffix
|
57
|
+
|
58
|
+
metrics = [
|
59
|
+
product_suffixed_rollup(product, suffix),
|
60
|
+
product_rollup(product),
|
61
|
+
suffixed_rollup(suffix),
|
62
|
+
ROLLUP_METRIC
|
63
|
+
]
|
64
|
+
|
65
|
+
metrics.unshift operation_metric_for(product, operation) if collection
|
66
|
+
|
67
|
+
metrics
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.product_operation_collection_for product, operation, collection=nil, generic_product = nil
|
48
71
|
if overrides = overridden_operation_and_collection
|
49
72
|
if should_override?(overrides, product, generic_product)
|
50
73
|
operation = overrides[0] || operation
|
51
74
|
collection = overrides[1] || collection
|
52
75
|
end
|
53
76
|
end
|
77
|
+
[product, operation, collection]
|
78
|
+
end
|
54
79
|
|
80
|
+
def self.metrics_for(product, operation, collection = nil, generic_product = nil)
|
81
|
+
product, operation, collection = product_operation_collection_for(product, operation, collection, generic_product)
|
55
82
|
suffix = all_suffix
|
56
83
|
|
57
84
|
# Order of these metrics matters--the first metric in the list will
|
@@ -70,10 +97,14 @@ module NewRelic
|
|
70
97
|
end
|
71
98
|
|
72
99
|
def self.metrics_from_sql(product, sql)
|
73
|
-
operation =
|
100
|
+
operation = operation_from_sql(sql)
|
74
101
|
metrics_for(product, operation)
|
75
102
|
end
|
76
103
|
|
104
|
+
def self.operation_from_sql(sql)
|
105
|
+
NewRelic::Agent::Database.parse_operation_from_query(sql) || OTHER
|
106
|
+
end
|
107
|
+
|
77
108
|
# Allow Transaction#with_database_metric_name to override our
|
78
109
|
# collection and operation
|
79
110
|
def self.overridden_operation_and_collection #THREAD_LOCAL_ACCESS
|
@@ -10,7 +10,7 @@ module NewRelic
|
|
10
10
|
module Datastores
|
11
11
|
module Mongo
|
12
12
|
module MetricTranslator
|
13
|
-
def self.
|
13
|
+
def self.operation_and_collection_for(name, payload)
|
14
14
|
payload ||= {}
|
15
15
|
|
16
16
|
if collection_in_selector?(payload)
|
@@ -51,20 +51,14 @@ module NewRelic
|
|
51
51
|
collection = collection_name_from_rename_selector(payload)
|
52
52
|
end
|
53
53
|
|
54
|
-
|
54
|
+
[name.to_s, collection]
|
55
55
|
rescue => e
|
56
56
|
NewRelic::Agent.logger.debug("Failure during Mongo metric generation", e)
|
57
|
-
|
57
|
+
nil
|
58
58
|
end
|
59
59
|
|
60
60
|
MONGO_PRODUCT_NAME = "MongoDB".freeze
|
61
61
|
|
62
|
-
def self.build_metrics(name, collection)
|
63
|
-
NewRelic::Agent::Datastores::MetricHelper.metrics_for(MONGO_PRODUCT_NAME,
|
64
|
-
name,
|
65
|
-
collection)
|
66
|
-
end
|
67
|
-
|
68
62
|
def self.collection_in_selector?(payload)
|
69
63
|
payload[:collection] == '$cmd' && payload[:selector]
|
70
64
|
end
|
@@ -185,8 +185,8 @@ module NewRelic
|
|
185
185
|
|
186
186
|
# extracts a stack trace from the exception for debugging purposes
|
187
187
|
def extract_stack_trace(exception)
|
188
|
-
actual_exception = sense_method(exception,
|
189
|
-
sense_method(actual_exception,
|
188
|
+
actual_exception = sense_method(exception, :cause) || sense_method(exception, :original_exception) || exception
|
189
|
+
sense_method(actual_exception, :backtrace) || '<no stack trace>'
|
190
190
|
end
|
191
191
|
|
192
192
|
# See NewRelic::Agent.notice_error for options and commentary
|
@@ -44,29 +44,19 @@ module NewRelic
|
|
44
44
|
end
|
45
45
|
|
46
46
|
sql, name, _ = args
|
47
|
-
|
47
|
+
|
48
|
+
product, operation, collection = ActiveRecordHelper.product_operation_collection_for(
|
48
49
|
NewRelic::Helper.correctly_encoded(name),
|
49
50
|
NewRelic::Helper.correctly_encoded(sql),
|
50
51
|
@config && @config[:adapter])
|
51
52
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
log_without_newrelic_instrumentation(*args, &block)
|
60
|
-
ensure
|
61
|
-
elapsed_time = (Time.now - t0).to_f
|
62
|
-
|
63
|
-
NewRelic::Agent.instance.transaction_sampler.notice_sql(sql,
|
64
|
-
@config, elapsed_time,
|
65
|
-
state, EXPLAINER)
|
66
|
-
NewRelic::Agent.instance.sql_sampler.notice_sql(sql, scoped_metric,
|
67
|
-
@config, elapsed_time,
|
68
|
-
state, EXPLAINER)
|
69
|
-
end
|
53
|
+
segment = NewRelic::Agent::Transaction.start_datastore_segment(product, operation, collection)
|
54
|
+
segment._notice_sql(sql, @config, EXPLAINER)
|
55
|
+
|
56
|
+
begin
|
57
|
+
log_without_newrelic_instrumentation(*args, &block)
|
58
|
+
ensure
|
59
|
+
segment.finish
|
70
60
|
end
|
71
61
|
end
|
72
62
|
end
|
@@ -86,16 +86,12 @@ module NewRelic
|
|
86
86
|
ACTIVE_RECORD = "ActiveRecord".freeze unless defined?(ACTIVE_RECORD)
|
87
87
|
OTHER = "other".freeze unless defined?(OTHER)
|
88
88
|
|
89
|
-
def
|
89
|
+
def product_operation_collection_for name, sql, adapter_name
|
90
90
|
product = map_product(adapter_name)
|
91
91
|
splits = split_name(name)
|
92
92
|
model = model_from_splits(splits)
|
93
93
|
operation = operation_from_splits(splits, sql)
|
94
|
-
|
95
|
-
NewRelic::Agent::Datastores::MetricHelper.metrics_for(product,
|
96
|
-
operation,
|
97
|
-
model,
|
98
|
-
ACTIVE_RECORD)
|
94
|
+
NewRelic::Agent::Datastores::MetricHelper.product_operation_collection_for product, operation, model, ACTIVE_RECORD
|
99
95
|
end
|
100
96
|
|
101
97
|
# @deprecated
|
@@ -23,7 +23,9 @@ module NewRelic
|
|
23
23
|
def start(name, id, payload) #THREAD_LOCAL_ACCESS
|
24
24
|
return if payload[:name] == CACHED_QUERY_NAME
|
25
25
|
return unless NewRelic::Agent.tl_is_execution_traced?
|
26
|
-
|
26
|
+
config = active_record_config(payload)
|
27
|
+
event = ActiveRecordEvent.new(name, Time.now, nil, id, payload, @explainer, config)
|
28
|
+
push_event(event)
|
27
29
|
rescue => e
|
28
30
|
log_notification_error(e, name, 'start')
|
29
31
|
end
|
@@ -32,10 +34,8 @@ module NewRelic
|
|
32
34
|
return if payload[:name] == CACHED_QUERY_NAME
|
33
35
|
state = NewRelic::Agent::TransactionState.tl_get
|
34
36
|
return unless state.is_execution_traced?
|
35
|
-
event
|
36
|
-
|
37
|
-
base_metric = record_metrics(event, config)
|
38
|
-
notice_sql(state, event, config, base_metric)
|
37
|
+
event = pop_event(id)
|
38
|
+
event.finish
|
39
39
|
rescue => e
|
40
40
|
log_notification_error(e, name, 'finish')
|
41
41
|
end
|
@@ -52,43 +52,11 @@ module NewRelic
|
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
def
|
56
|
-
|
57
|
-
|
58
|
-
# enter transaction trace node
|
59
|
-
frame = stack.push_frame(state, :active_record, event.time)
|
60
|
-
|
61
|
-
NewRelic::Agent.instance.transaction_sampler \
|
62
|
-
.notice_sql(event.payload[:sql], config,
|
63
|
-
Helper.milliseconds_to_seconds(event.duration),
|
64
|
-
state, @explainer, event.payload[:binds], event.payload[:name])
|
65
|
-
|
66
|
-
NewRelic::Agent.instance.sql_sampler \
|
67
|
-
.notice_sql(event.payload[:sql], metric, config,
|
68
|
-
Helper.milliseconds_to_seconds(event.duration),
|
69
|
-
state, @explainer, event.payload[:binds], event.payload[:name])
|
70
|
-
|
71
|
-
# exit transaction trace node
|
72
|
-
stack.pop_frame(state, frame, metric, event.end)
|
73
|
-
end
|
74
|
-
|
75
|
-
def record_metrics(event, config) #THREAD_LOCAL_ACCESS
|
76
|
-
base, *other_metrics = ActiveRecordHelper.metrics_for(event.payload[:name],
|
77
|
-
NewRelic::Helper.correctly_encoded(event.payload[:sql]),
|
78
|
-
config && config[:adapter])
|
79
|
-
|
80
|
-
NewRelic::Agent.instance.stats_engine.tl_record_scoped_and_unscoped_metrics(
|
81
|
-
base, other_metrics,
|
82
|
-
Helper.milliseconds_to_seconds(event.duration))
|
83
|
-
|
84
|
-
base
|
85
|
-
end
|
86
|
-
|
87
|
-
def active_record_config_for_event(event)
|
88
|
-
return unless event.payload[:connection_id]
|
55
|
+
def active_record_config(payload)
|
56
|
+
return unless payload[:connection_id]
|
89
57
|
|
90
58
|
connection = nil
|
91
|
-
connection_id =
|
59
|
+
connection_id = payload[:connection_id]
|
92
60
|
|
93
61
|
::ActiveRecord::Base.connection_handler.connection_pool_list.each do |handler|
|
94
62
|
connection = handler.connections.detect do |conn|
|
@@ -100,6 +68,47 @@ module NewRelic
|
|
100
68
|
|
101
69
|
connection.instance_variable_get(:@config) if connection
|
102
70
|
end
|
71
|
+
|
72
|
+
class ActiveRecordEvent < Event
|
73
|
+
def initialize(name, start, ending, transaction_id, payload, explainer, config)
|
74
|
+
super(name, start, ending, transaction_id, payload)
|
75
|
+
@explainer = explainer
|
76
|
+
@config = config
|
77
|
+
@segment = start_segment
|
78
|
+
end
|
79
|
+
|
80
|
+
# Events do not always finish in the order they are started for this subscriber.
|
81
|
+
# The traced_method_stack expects that frames are popped off in the order that they
|
82
|
+
# are pushed, otherwise it will continue to pop up the stack until it finds the frame
|
83
|
+
# it expects. This will be fixed when we replace the tracer internals, but for now
|
84
|
+
# we need to work around this limitation.
|
85
|
+
def start_segment
|
86
|
+
product, operation, collection = ActiveRecordHelper.product_operation_collection_for(payload[:name],
|
87
|
+
sql, @config && @config[:adapter])
|
88
|
+
segment = NewRelic::Agent::Transaction::DatastoreSegment.new product, operation, collection
|
89
|
+
if txn = state.current_transaction
|
90
|
+
segment.transaction = txn
|
91
|
+
end
|
92
|
+
segment._notice_sql sql, @config, @explainer, payload[:binds], payload[:name]
|
93
|
+
segment.start
|
94
|
+
segment
|
95
|
+
end
|
96
|
+
|
97
|
+
# See comment for start_segment as we continue to work around limitations of the
|
98
|
+
# current tracer in this method.
|
99
|
+
def finish
|
100
|
+
state.traced_method_stack.push_segment state, @segment
|
101
|
+
@segment.finish
|
102
|
+
end
|
103
|
+
|
104
|
+
def state
|
105
|
+
@state ||= NewRelic::Agent::TransactionState.tl_get
|
106
|
+
end
|
107
|
+
|
108
|
+
def sql
|
109
|
+
@sql ||= Helper.correctly_encoded payload[:sql]
|
110
|
+
end
|
111
|
+
end
|
103
112
|
end
|
104
113
|
end
|
105
114
|
end
|