newrelic_rpm 3.15.1.316 → 3.15.2.317
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +41 -0
- data/lib/new_relic/agent/agent.rb +1 -1
- data/lib/new_relic/agent/autostart.rb +1 -1
- data/lib/new_relic/agent/database.rb +72 -165
- data/lib/new_relic/agent/database/explain_plan_helpers.rb +127 -0
- data/lib/new_relic/agent/database/obfuscation_helpers.rb +2 -1
- data/lib/new_relic/agent/database/postgres_explain_obfuscator.rb +0 -2
- data/lib/new_relic/agent/instrumentation/active_record.rb +5 -5
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +10 -8
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +2 -1
- data/lib/new_relic/agent/instrumentation/grape.rb +23 -9
- data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +1 -6
- data/lib/new_relic/agent/instrumentation/padrino.rb +36 -0
- data/lib/new_relic/agent/method_tracer.rb +20 -18
- data/lib/new_relic/agent/new_relic_service.rb +3 -33
- data/lib/new_relic/agent/pipe_service.rb +0 -4
- data/lib/new_relic/agent/sql_sampler.rb +3 -3
- data/lib/new_relic/agent/transaction/trace_node.rb +2 -5
- data/lib/new_relic/agent/transaction_sampler.rb +2 -2
- data/lib/new_relic/metric_data.rb +6 -14
- data/lib/new_relic/version.rb +1 -1
- data/newrelic_rpm.gemspec +1 -1
- data/test/environments/lib/environments/runner.rb +1 -1
- data/test/environments/rails40/Gemfile +9 -0
- data/test/environments/rails41/Gemfile +9 -0
- data/test/environments/rails42/Gemfile +9 -0
- data/test/multiverse/lib/multiverse/suite.rb +12 -0
- data/test/multiverse/suites/agent_only/harvest_timestamps_test.rb +0 -31
- data/test/multiverse/suites/grape/Envfile +1 -1
- data/test/multiverse/suites/mongo/Envfile +3 -0
- data/test/multiverse/suites/mongo/mongo2_instrumentation_test.rb +3 -2
- data/test/multiverse/suites/padrino/Envfile +8 -0
- data/test/multiverse/suites/typhoeus/Envfile +21 -0
- data/test/new_relic/agent/database_test.rb +216 -144
- data/test/new_relic/agent/new_relic_service_test.rb +0 -58
- data/test/new_relic/metric_data_test.rb +24 -71
- data/test/new_relic/metric_spec_test.rb +3 -4
- data/test/new_relic/rack/developer_mode_test.rb +5 -2
- metadata +4 -2
@@ -40,6 +40,7 @@ module NewRelic
|
|
40
40
|
# placeholder.
|
41
41
|
CLEANUP_REGEX = {
|
42
42
|
:mysql => /'|"|\/\*|\*\//,
|
43
|
+
:mysql2 => /'|"|\/\*|\*\//,
|
43
44
|
:postgres => /'|\/\*|\*\/|\$(?!\?)/,
|
44
45
|
:sqlite => /'|\/\*|\*\//,
|
45
46
|
:cassandra => /'|\/\*|\*\//,
|
@@ -68,7 +69,7 @@ module NewRelic
|
|
68
69
|
|
69
70
|
def obfuscate(sql, adapter)
|
70
71
|
case adapter
|
71
|
-
when :mysql
|
72
|
+
when :mysql, :mysql2
|
72
73
|
regex = MYSQL_COMPONENTS_REGEX
|
73
74
|
when :postgres
|
74
75
|
regex = POSTGRES_COMPONENTS_REGEX
|
@@ -6,13 +6,13 @@ module NewRelic
|
|
6
6
|
module Agent
|
7
7
|
module Instrumentation
|
8
8
|
module ActiveRecord
|
9
|
-
EXPLAINER = lambda do |
|
10
|
-
connection = NewRelic::Agent::Database.get_connection(config) do
|
11
|
-
::ActiveRecord::Base.send("#{config[:adapter]}_connection",
|
12
|
-
config)
|
9
|
+
EXPLAINER = lambda do |statement|
|
10
|
+
connection = NewRelic::Agent::Database.get_connection(statement.config) do
|
11
|
+
::ActiveRecord::Base.send("#{statement.config[:adapter]}_connection",
|
12
|
+
statement.config)
|
13
13
|
end
|
14
14
|
if connection && connection.respond_to?(:execute)
|
15
|
-
return connection.execute("EXPLAIN #{
|
15
|
+
return connection.execute("EXPLAIN #{statement.sql}")
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -40,13 +40,15 @@ module NewRelic
|
|
40
40
|
log_notification_error(e, name, 'finish')
|
41
41
|
end
|
42
42
|
|
43
|
-
def get_explain_plan(
|
44
|
-
connection = NewRelic::Agent::Database.get_connection(config) do
|
45
|
-
::ActiveRecord::Base.send("#{config[:adapter]}_connection",
|
46
|
-
config)
|
43
|
+
def get_explain_plan(statement)
|
44
|
+
connection = NewRelic::Agent::Database.get_connection(statement.config) do
|
45
|
+
::ActiveRecord::Base.send("#{statement.config[:adapter]}_connection",
|
46
|
+
statement.config)
|
47
47
|
end
|
48
|
-
if connection && connection.respond_to?(:
|
49
|
-
return connection.
|
48
|
+
if connection && connection.respond_to?(:exec_query)
|
49
|
+
return connection.exec_query("EXPLAIN #{statement.sql}",
|
50
|
+
"Explain #{statement.name}",
|
51
|
+
statement.binds)
|
50
52
|
end
|
51
53
|
end
|
52
54
|
|
@@ -59,12 +61,12 @@ module NewRelic
|
|
59
61
|
NewRelic::Agent.instance.transaction_sampler \
|
60
62
|
.notice_sql(event.payload[:sql], config,
|
61
63
|
Helper.milliseconds_to_seconds(event.duration),
|
62
|
-
state, @explainer)
|
64
|
+
state, @explainer, event.payload[:binds], event.payload[:name])
|
63
65
|
|
64
66
|
NewRelic::Agent.instance.sql_sampler \
|
65
67
|
.notice_sql(event.payload[:sql], metric, config,
|
66
68
|
Helper.milliseconds_to_seconds(event.duration),
|
67
|
-
state, @explainer)
|
69
|
+
state, @explainer, event.payload[:binds], event.payload[:name])
|
68
70
|
|
69
71
|
# exit transaction trace node
|
70
72
|
stack.pop_frame(state, frame, metric, event.end)
|
@@ -147,7 +147,8 @@ module NewRelic
|
|
147
147
|
strategy = NewRelic::Agent::Database.record_sql_method(:slow_sql)
|
148
148
|
case strategy
|
149
149
|
when :obfuscated
|
150
|
-
|
150
|
+
adapter_name = self.respond_to?(:options) ? self.options[:adapter] : self.repository.adapter.uri.scheme
|
151
|
+
statement = NewRelic::Agent::Database::Statement.new(e.query, :adapter => adapter_name)
|
151
152
|
obfuscated_sql = NewRelic::Agent::Database.obfuscate_sql(statement)
|
152
153
|
e.instance_variable_set(:@query, obfuscated_sql)
|
153
154
|
when :off
|
@@ -28,15 +28,29 @@ module NewRelic
|
|
28
28
|
Transaction.set_default_transaction_name(txn_name, :grape, node_name)
|
29
29
|
end
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
31
|
+
if defined?(Grape::VERSION) && VersionNumber.new(::Grape::VERSION) >= VersionNumber.new("0.16.0")
|
32
|
+
def name_for_transaction(route, class_name)
|
33
|
+
action_name = route.path.sub(FORMAT_REGEX, EMPTY_STRING)
|
34
|
+
method_name = route.request_method
|
35
|
+
|
36
|
+
if route.version
|
37
|
+
action_name = action_name.sub(VERSION_REGEX, EMPTY_STRING)
|
38
|
+
"#{class_name}-#{route.version}#{action_name} (#{method_name})"
|
39
|
+
else
|
40
|
+
"#{class_name}#{action_name} (#{method_name})"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
else
|
44
|
+
def name_for_transaction(route, class_name)
|
45
|
+
action_name = route.route_path.sub(FORMAT_REGEX, EMPTY_STRING)
|
46
|
+
method_name = route.route_method
|
47
|
+
|
48
|
+
if route.route_version
|
49
|
+
action_name = action_name.sub(VERSION_REGEX, EMPTY_STRING)
|
50
|
+
"#{class_name}-#{route.route_version}#{action_name} (#{method_name})"
|
51
|
+
else
|
52
|
+
"#{class_name}#{action_name} (#{method_name})"
|
53
|
+
end
|
40
54
|
end
|
41
55
|
end
|
42
56
|
|
@@ -9,7 +9,6 @@ module NewRelic
|
|
9
9
|
class MongodbCommandSubscriber
|
10
10
|
|
11
11
|
MONGODB = 'MongoDB'.freeze
|
12
|
-
GET_MORE = "getMore".freeze
|
13
12
|
COLLECTION = "collection".freeze
|
14
13
|
|
15
14
|
def started(event)
|
@@ -45,11 +44,7 @@ module NewRelic
|
|
45
44
|
private
|
46
45
|
|
47
46
|
def collection(event)
|
48
|
-
|
49
|
-
event.command[COLLECTION]
|
50
|
-
else
|
51
|
-
event.command.values.first
|
52
|
-
end
|
47
|
+
event.command[COLLECTION] || event.command[:collection] || event.command.values.first
|
53
48
|
end
|
54
49
|
|
55
50
|
def metrics(event)
|
@@ -27,6 +27,42 @@ DependencyDetection.defer do
|
|
27
27
|
|
28
28
|
alias dispatch_without_newrelic dispatch!
|
29
29
|
alias dispatch! dispatch_with_newrelic
|
30
|
+
|
31
|
+
# Padrino 0.13 mustermann routing
|
32
|
+
if private_method_defined?(:invoke_route)
|
33
|
+
include NewRelic::Agent::Instrumentation::Padrino
|
34
|
+
|
35
|
+
alias invoke_route_without_newrelic invoke_route
|
36
|
+
alias invoke_route invoke_route_with_newrelic
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module NewRelic
|
43
|
+
module Agent
|
44
|
+
module Instrumentation
|
45
|
+
module Padrino
|
46
|
+
def invoke_route_with_newrelic(*args, &block)
|
47
|
+
begin
|
48
|
+
env["newrelic.last_route"] = args[0].original_path
|
49
|
+
rescue => e
|
50
|
+
::NewRelic::Agent.logger.debug("Failed determining last route in Padrino", e)
|
51
|
+
end
|
52
|
+
|
53
|
+
begin
|
54
|
+
txn_name = ::NewRelic::Agent::Instrumentation::Sinatra::TransactionNamer.transaction_name_for_route(env, request)
|
55
|
+
unless txn_name.nil?
|
56
|
+
::NewRelic::Agent::Transaction.set_default_transaction_name(
|
57
|
+
"#{self.class.name}/#{txn_name}", :sinatra)
|
58
|
+
end
|
59
|
+
rescue => e
|
60
|
+
::NewRelic::Agent.logger.debug("Failed during invoke_route to set transaction name", e)
|
61
|
+
end
|
62
|
+
|
63
|
+
invoke_route_without_newrelic(*args, &block)
|
64
|
+
end
|
65
|
+
end
|
30
66
|
end
|
31
67
|
end
|
32
68
|
end
|
@@ -202,7 +202,7 @@ module NewRelic
|
|
202
202
|
# Example:
|
203
203
|
# Foo.default_metric_name_code('bar') #=> "Custom/#{Foo.name}/bar"
|
204
204
|
def default_metric_name_code(method_name)
|
205
|
-
"Custom/#{
|
205
|
+
"Custom/#{derived_class_name}/#{method_name}"
|
206
206
|
end
|
207
207
|
|
208
208
|
# Checks to see if the method we are attempting to trace
|
@@ -210,7 +210,7 @@ module NewRelic
|
|
210
210
|
# anything if the method doesn't exist.
|
211
211
|
def newrelic_method_exists?(method_name)
|
212
212
|
exists = method_defined?(method_name) || private_method_defined?(method_name)
|
213
|
-
::NewRelic::Agent.logger.error("Did not trace #{
|
213
|
+
::NewRelic::Agent.logger.error("Did not trace #{derived_class_name}##{method_name} because that method does not exist") unless exists
|
214
214
|
exists
|
215
215
|
end
|
216
216
|
|
@@ -275,6 +275,23 @@ module NewRelic
|
|
275
275
|
method_without_push_scope(method_name, metric_name_code, options)
|
276
276
|
end
|
277
277
|
end
|
278
|
+
|
279
|
+
private
|
280
|
+
|
281
|
+
def derived_class_name
|
282
|
+
return self.name if self.name && !self.name.empty?
|
283
|
+
return "AnonymousModule" if self.to_s.start_with?("#<Module:")
|
284
|
+
|
285
|
+
# trying to get the "MyClass" portion of "#<Class:MyClass>"
|
286
|
+
name = self.to_s[/^#<Class:(.+)>$/, 1]
|
287
|
+
if name.start_with?("0x")
|
288
|
+
"AnonymousClass"
|
289
|
+
elsif name.start_with?("#<Class:")
|
290
|
+
"AnonymousClass/Class"
|
291
|
+
else
|
292
|
+
"#{name}/Class"
|
293
|
+
end
|
294
|
+
end
|
278
295
|
end
|
279
296
|
include AddMethodTracer
|
280
297
|
|
@@ -345,7 +362,7 @@ module NewRelic
|
|
345
362
|
alias_method method_name, _traced_method_name(method_name, metric_name_code)
|
346
363
|
send visibility, method_name
|
347
364
|
send visibility, _traced_method_name(method_name, metric_name_code)
|
348
|
-
::NewRelic::Agent.logger.debug("Traced method: class = #{
|
365
|
+
::NewRelic::Agent.logger.debug("Traced method: class = #{derived_class_name},"+
|
349
366
|
"method = #{method_name}, "+
|
350
367
|
"metric = '#{metric_name_code}'")
|
351
368
|
end
|
@@ -383,21 +400,6 @@ module NewRelic
|
|
383
400
|
def _sanitize_name(name)
|
384
401
|
name.to_s.tr_s('^a-zA-Z0-9', '_')
|
385
402
|
end
|
386
|
-
|
387
|
-
def class_name
|
388
|
-
return self.name if self.name && !self.name.empty?
|
389
|
-
return "AnonymousModule" if self.to_s.start_with?("#<Module:")
|
390
|
-
|
391
|
-
# trying to get the "MyClass" portion of "#<Class:MyClass>"
|
392
|
-
name = self.to_s[/^#<Class:(.+)>$/, 1]
|
393
|
-
if name.start_with?("0x")
|
394
|
-
"AnonymousClass"
|
395
|
-
elsif name.start_with?("#<Class:")
|
396
|
-
"AnonymousClass/Class"
|
397
|
-
else
|
398
|
-
"#{name}/Class"
|
399
|
-
end
|
400
|
-
end
|
401
403
|
end
|
402
404
|
|
403
405
|
# @!parse extend ClassMethods
|
@@ -30,13 +30,12 @@ module NewRelic
|
|
30
30
|
CONNECTION_ERRORS = [Timeout::Error, EOFError, SystemCallError, SocketError].freeze
|
31
31
|
|
32
32
|
attr_accessor :request_timeout, :agent_id
|
33
|
-
attr_reader :collector, :marshaller
|
33
|
+
attr_reader :collector, :marshaller
|
34
34
|
|
35
35
|
def initialize(license_key=nil, collector=control.server)
|
36
36
|
@license_key = license_key || Agent.config[:license_key]
|
37
37
|
@collector = collector
|
38
38
|
@request_timeout = Agent.config[:timeout]
|
39
|
-
@metric_id_cache = {}
|
40
39
|
@ssl_cert_store = nil
|
41
40
|
@in_session = nil
|
42
41
|
@agent_id = nil
|
@@ -80,46 +79,18 @@ module NewRelic
|
|
80
79
|
invoke_remote(:shutdown, [@agent_id, time.to_i]) if @agent_id
|
81
80
|
end
|
82
81
|
|
83
|
-
def reset_metric_id_cache
|
84
|
-
@metric_id_cache = {}
|
85
|
-
end
|
86
|
-
|
87
82
|
def force_restart
|
88
|
-
reset_metric_id_cache
|
89
83
|
close_shared_connection
|
90
84
|
end
|
91
85
|
|
92
|
-
#
|
93
|
-
# metric cache so we can save the collector some work by
|
94
|
-
# sending integers instead of strings the next time around
|
95
|
-
def fill_metric_id_cache(pairs_of_specs_and_ids)
|
96
|
-
Array(pairs_of_specs_and_ids).each do |metric_spec_hash, metric_id|
|
97
|
-
metric_spec = MetricSpec.new(metric_spec_hash['name'],
|
98
|
-
metric_spec_hash['scope'])
|
99
|
-
metric_id_cache[metric_spec] = metric_id
|
100
|
-
end
|
101
|
-
rescue => e
|
102
|
-
# If we've gotten this far, we don't want this error to propagate and
|
103
|
-
# make this post appear to have been non-successful, which would trigger
|
104
|
-
# re-aggregation of the same metric data into the next post, so just log
|
105
|
-
NewRelic::Agent.logger.error("Failed to fill metric ID cache from response, error details follow ", e)
|
106
|
-
end
|
107
|
-
|
108
|
-
# The collector wants to recieve metric data in a format that's different
|
86
|
+
# The collector wants to receive metric data in a format that's different
|
109
87
|
# from how we store it internally, so this method handles the translation.
|
110
|
-
# It also handles translating metric names to IDs using our metric ID cache.
|
111
88
|
def build_metric_data_array(stats_hash)
|
112
89
|
metric_data_array = []
|
113
90
|
stats_hash.each do |metric_spec, stats|
|
114
91
|
# Omit empty stats as an optimization
|
115
92
|
unless stats.is_reset?
|
116
|
-
|
117
|
-
metric_data = if metric_id
|
118
|
-
NewRelic::MetricData.new(nil, stats, metric_id)
|
119
|
-
else
|
120
|
-
NewRelic::MetricData.new(metric_spec, stats, nil)
|
121
|
-
end
|
122
|
-
metric_data_array << metric_data
|
93
|
+
metric_data_array << NewRelic::MetricData.new(metric_spec, stats)
|
123
94
|
end
|
124
95
|
end
|
125
96
|
metric_data_array
|
@@ -134,7 +105,6 @@ module NewRelic
|
|
134
105
|
[@agent_id, timeslice_start.to_f, timeslice_end.to_f, metric_data_array],
|
135
106
|
:item_count => metric_data_array.size
|
136
107
|
)
|
137
|
-
fill_metric_id_cache(result)
|
138
108
|
result
|
139
109
|
end
|
140
110
|
|
@@ -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) #THREAD_LOCAL_ACCESS sometimes
|
143
|
+
def notice_sql(sql, metric_name, config, duration, state=nil, explainer=nil, binds=[], name="SQL") #THREAD_LOCAL_ACCESS sometimes
|
144
144
|
state ||= TransactionState.tl_get
|
145
145
|
data = state.sql_sampler_transaction_data
|
146
146
|
return unless data
|
@@ -148,7 +148,7 @@ module NewRelic
|
|
148
148
|
if state.is_sql_recorded?
|
149
149
|
if duration > Agent.config[:'slow_sql.explain_threshold']
|
150
150
|
backtrace = caller.join("\n")
|
151
|
-
statement = Database::Statement.new(sql, config, explainer)
|
151
|
+
statement = Database::Statement.new(sql, config, explainer, binds, name)
|
152
152
|
data.sql_data << SlowSql.new(statement, metric_name, duration, backtrace)
|
153
153
|
end
|
154
154
|
end
|
@@ -234,7 +234,7 @@ module NewRelic
|
|
234
234
|
|
235
235
|
def explain
|
236
236
|
if statement.config && statement.explainer
|
237
|
-
NewRelic::Agent::Database.explain_sql(statement
|
237
|
+
NewRelic::Agent::Database.explain_sql(statement)
|
238
238
|
end
|
239
239
|
end
|
240
240
|
|
@@ -165,12 +165,9 @@ module NewRelic
|
|
165
165
|
return params[:explain_plan] if params.key?(:explain_plan)
|
166
166
|
|
167
167
|
statement = params[:sql]
|
168
|
-
return nil unless statement.
|
169
|
-
statement.respond_to?(:explainer)
|
168
|
+
return nil unless statement.is_a?(Database::Statement)
|
170
169
|
|
171
|
-
NewRelic::Agent::Database.explain_sql(statement
|
172
|
-
statement.config,
|
173
|
-
statement.explainer)
|
170
|
+
NewRelic::Agent::Database.explain_sql(statement)
|
174
171
|
end
|
175
172
|
|
176
173
|
def obfuscated_sql
|
@@ -183,13 +183,13 @@ module NewRelic
|
|
183
183
|
# @api public
|
184
184
|
# @deprecated Use {Datastores.notice_sql} instead.
|
185
185
|
#
|
186
|
-
def notice_sql(sql, config, duration, state=nil, explainer=nil) #THREAD_LOCAL_ACCESS sometimes
|
186
|
+
def notice_sql(sql, config, duration, state=nil, explainer=nil, binds=[], name="SQL") #THREAD_LOCAL_ACCESS sometimes
|
187
187
|
# some statements (particularly INSERTS with large BLOBS
|
188
188
|
# may be very large; we should trim them to a maximum usable length
|
189
189
|
state ||= TransactionState.tl_get
|
190
190
|
builder = state.transaction_sample_builder
|
191
191
|
if state.is_sql_recorded?
|
192
|
-
statement = Database::Statement.new(sql, config, explainer)
|
192
|
+
statement = Database::Statement.new(sql, config, explainer, binds, name)
|
193
193
|
notice_extra_data(builder, statement, duration, :sql)
|
194
194
|
end
|
195
195
|
end
|
@@ -6,17 +6,14 @@ require 'new_relic/coerce'
|
|
6
6
|
|
7
7
|
module NewRelic
|
8
8
|
class MetricData
|
9
|
-
#
|
9
|
+
# a NewRelic::MetricSpec object
|
10
10
|
attr_reader :metric_spec
|
11
|
-
# nil or a cached integer ID for the metric from the collector.
|
12
|
-
attr_accessor :metric_id
|
13
11
|
# the actual statistics object
|
14
12
|
attr_accessor :stats
|
15
13
|
|
16
|
-
def initialize(metric_spec, stats
|
14
|
+
def initialize(metric_spec, stats)
|
17
15
|
@metric_spec = metric_spec
|
18
16
|
self.stats = stats
|
19
|
-
self.metric_id = metric_id
|
20
17
|
end
|
21
18
|
|
22
19
|
def eql?(o)
|
@@ -38,27 +35,22 @@ module NewRelic
|
|
38
35
|
metric_spec.hash ^ stats.hash
|
39
36
|
end
|
40
37
|
|
41
|
-
# Serialize with all attributes, but if the metric id is not nil, then don't send the metric spec
|
42
38
|
def to_json(*a)
|
43
|
-
%Q[{"metric_spec":#{
|
39
|
+
%Q[{"metric_spec":#{metric_spec.to_json},"stats":{"total_exclusive_time":#{stats.total_exclusive_time},"min_call_time":#{stats.min_call_time},"call_count":#{stats.call_count},"sum_of_squares":#{stats.sum_of_squares},"total_call_time":#{stats.total_call_time},"max_call_time":#{stats.max_call_time}}}]
|
44
40
|
end
|
45
41
|
|
46
42
|
def to_s
|
47
|
-
|
48
|
-
"#{metric_spec.name}(#{metric_spec.scope}): #{stats}"
|
49
|
-
else
|
50
|
-
"#{metric_id}: #{stats}"
|
51
|
-
end
|
43
|
+
"#{metric_spec.name}(#{metric_spec.scope}): #{stats}"
|
52
44
|
end
|
53
45
|
|
54
46
|
def inspect
|
55
|
-
"#<MetricData metric_spec:#{metric_spec.inspect}, stats:#{stats.inspect}
|
47
|
+
"#<MetricData metric_spec:#{metric_spec.inspect}, stats:#{stats.inspect}>"
|
56
48
|
end
|
57
49
|
|
58
50
|
include NewRelic::Coerce
|
59
51
|
|
60
52
|
def to_collector_array(encoder=nil)
|
61
|
-
stat_key =
|
53
|
+
stat_key = { 'name' => metric_spec.name, 'scope' => metric_spec.scope }
|
62
54
|
[ stat_key,
|
63
55
|
[
|
64
56
|
int(stats.call_count, stat_key),
|