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
@@ -0,0 +1,85 @@
|
|
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 Datastores
|
8
|
+
module MetricHelper
|
9
|
+
ROLLUP_METRIC = "Datastore/all".freeze
|
10
|
+
WEB_ROLLUP_METRIC = "Datastore/allWeb".freeze
|
11
|
+
OTHER_ROLLUP_METRIC = "Datastore/allOther".freeze
|
12
|
+
DEFAULT_PRODUCT_NAME = "ActiveRecord".freeze
|
13
|
+
OTHER = "Other".freeze
|
14
|
+
|
15
|
+
ALL = "all".freeze
|
16
|
+
ALL_WEB = "allWeb".freeze
|
17
|
+
ALL_OTHER = "allOther".freeze
|
18
|
+
|
19
|
+
def self.statement_metric_for(product, collection, operation)
|
20
|
+
"Datastore/statement/#{product}/#{collection}/#{operation}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.operation_metric_for(product, operation)
|
24
|
+
"Datastore/operation/#{product}/#{operation}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.product_suffixed_rollup(product, suffix)
|
28
|
+
"Datastore/#{product}/#{suffix}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.product_rollup(product)
|
32
|
+
"Datastore/#{product}/all"
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.suffixed_rollup(suffix)
|
36
|
+
"Datastore/#{suffix}"
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.all_suffix
|
40
|
+
if NewRelic::Agent::Transaction.recording_web_transaction?
|
41
|
+
ALL_WEB
|
42
|
+
else
|
43
|
+
ALL_OTHER
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.metrics_for(product, operation, collection = nil)
|
48
|
+
if overrides = overridden_operation_and_collection
|
49
|
+
operation, collection = overrides
|
50
|
+
end
|
51
|
+
|
52
|
+
suffix = all_suffix
|
53
|
+
|
54
|
+
# Order of these metrics matters--the first metric in the list will
|
55
|
+
# be treated as the scoped metric in a bunch of different cases.
|
56
|
+
metrics = [
|
57
|
+
operation_metric_for(product, operation),
|
58
|
+
product_suffixed_rollup(product, suffix),
|
59
|
+
product_rollup(product),
|
60
|
+
suffixed_rollup(suffix),
|
61
|
+
ROLLUP_METRIC
|
62
|
+
]
|
63
|
+
|
64
|
+
metrics.unshift statement_metric_for(product, collection, operation) if collection
|
65
|
+
|
66
|
+
metrics
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.metrics_from_sql(product, sql)
|
70
|
+
operation = NewRelic::Agent::Database.parse_operation_from_query(sql) || OTHER
|
71
|
+
metrics_for(product, operation)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Allow Transaction#with_database_metric_name to override our
|
75
|
+
# collection and operation
|
76
|
+
def self.overridden_operation_and_collection #THREAD_LOCAL_ACCESS
|
77
|
+
state = NewRelic::Agent::TransactionState.tl_get
|
78
|
+
txn = state.current_transaction
|
79
|
+
txn ? txn.instrumentation_state[:datastore_override] : nil
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -3,13 +3,14 @@
|
|
3
3
|
# See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
|
4
4
|
|
5
5
|
require 'new_relic/agent/datastores/mongo/obfuscator'
|
6
|
+
require 'new_relic/agent/datastores/metric_helper'
|
6
7
|
|
7
8
|
module NewRelic
|
8
9
|
module Agent
|
9
10
|
module Datastores
|
10
11
|
module Mongo
|
11
12
|
module MetricTranslator
|
12
|
-
def self.metrics_for(name, payload
|
13
|
+
def self.metrics_for(name, payload)
|
13
14
|
payload ||= {}
|
14
15
|
|
15
16
|
if collection_in_selector?(payload)
|
@@ -50,28 +51,18 @@ module NewRelic
|
|
50
51
|
collection = collection_name_from_rename_selector(payload)
|
51
52
|
end
|
52
53
|
|
53
|
-
build_metrics(name, collection
|
54
|
+
build_metrics(name, collection)
|
55
|
+
rescue => e
|
56
|
+
NewRelic::Agent.logger.debug("Failure during Mongo metric generation", e)
|
57
|
+
[]
|
54
58
|
end
|
55
59
|
|
56
|
-
|
57
|
-
default_metrics = [
|
58
|
-
"Datastore/statement/MongoDB/#{collection}/#{name}",
|
59
|
-
"Datastore/operation/MongoDB/#{name}",
|
60
|
-
"Datastore/all"
|
61
|
-
]
|
60
|
+
MONGO_PRODUCT_NAME = "MongoDB".freeze
|
62
61
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
default_metrics << 'Datastore/allOther'
|
68
|
-
end
|
69
|
-
|
70
|
-
default_metrics
|
71
|
-
end
|
72
|
-
|
73
|
-
def self.instance_metric(host, port, database)
|
74
|
-
"Datastore/instance/MongoDB/#{host}:#{port}/#{database}"
|
62
|
+
def self.build_metrics(name, collection)
|
63
|
+
NewRelic::Agent::Datastores::MetricHelper.metrics_for(MONGO_PRODUCT_NAME,
|
64
|
+
name,
|
65
|
+
collection)
|
75
66
|
end
|
76
67
|
|
77
68
|
def self.collection_in_selector?(payload)
|
@@ -0,0 +1,18 @@
|
|
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 Deprecator
|
8
|
+
def self.deprecate(method_name, new_method_name = nil, version = nil)
|
9
|
+
msgs = ["The method #{method_name} is deprecated."]
|
10
|
+
msgs << "It will be removed in version #{version}." if version
|
11
|
+
msgs << "Please use #{new_method_name} instead." if new_method_name
|
12
|
+
|
13
|
+
NewRelic::Agent.logger.log_once(:warn, "deprecated_#{method_name}".to_sym, msgs)
|
14
|
+
NewRelic::Agent.record_metric("Supportability/Deprecated/#{method_name}", 1)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -20,15 +20,6 @@ module NewRelic
|
|
20
20
|
::ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval do
|
21
21
|
include ::NewRelic::Agent::Instrumentation::ActiveRecord
|
22
22
|
end
|
23
|
-
|
24
|
-
::ActiveRecord::Base.class_eval do
|
25
|
-
class << self
|
26
|
-
add_method_tracer(:find_by_sql, 'ActiveRecord/#{self.name}/find_by_sql',
|
27
|
-
:metric => false)
|
28
|
-
add_method_tracer(:transaction, 'ActiveRecord/#{self.name}/transaction',
|
29
|
-
:metric => false)
|
30
|
-
end
|
31
|
-
end
|
32
23
|
end
|
33
24
|
|
34
25
|
def self.included(instrumented_class)
|
@@ -49,35 +40,29 @@ module NewRelic
|
|
49
40
|
end
|
50
41
|
|
51
42
|
sql, name, _ = args
|
52
|
-
|
53
|
-
|
43
|
+
metrics = ActiveRecordHelper.metrics_for(
|
44
|
+
NewRelic::Helper.correctly_encoded(name),
|
45
|
+
NewRelic::Helper.correctly_encoded(sql),
|
46
|
+
@config && @config[:adapter])
|
54
47
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
metrics = [metric, remote_service_metric].compact
|
59
|
-
metrics += ActiveRecordHelper.rollup_metrics_for(metric)
|
60
|
-
self.class.trace_execution_scoped(metrics) do
|
61
|
-
t0 = Time.now
|
62
|
-
begin
|
63
|
-
log_without_newrelic_instrumentation(*args, &block)
|
64
|
-
ensure
|
65
|
-
elapsed_time = (Time.now - t0).to_f
|
48
|
+
# It is critical that we grab this name before trace_execution_scoped
|
49
|
+
# because that method mutates the metrics list passed in.
|
50
|
+
scoped_metric = metrics.first
|
66
51
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
52
|
+
NewRelic::Agent::MethodTracer.trace_execution_scoped(metrics) do
|
53
|
+
t0 = Time.now
|
54
|
+
begin
|
55
|
+
log_without_newrelic_instrumentation(*args, &block)
|
56
|
+
ensure
|
57
|
+
elapsed_time = (Time.now - t0).to_f
|
77
58
|
|
78
|
-
|
79
|
-
|
80
|
-
|
59
|
+
NewRelic::Agent.instance.transaction_sampler.notice_sql(sql,
|
60
|
+
@config, elapsed_time,
|
61
|
+
state, &EXPLAINER)
|
62
|
+
NewRelic::Agent.instance.sql_sampler.notice_sql(sql, scoped_metric,
|
63
|
+
@config, elapsed_time,
|
64
|
+
state, &EXPLAINER)
|
65
|
+
end
|
81
66
|
end
|
82
67
|
end
|
83
68
|
end
|
@@ -1,81 +1,140 @@
|
|
1
1
|
# encoding: utf-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
|
+
|
5
|
+
require 'new_relic/agent/datastores/metric_helper'
|
6
|
+
require 'new_relic/agent/deprecator'
|
7
|
+
|
4
8
|
module NewRelic
|
5
9
|
module Agent
|
6
10
|
module Instrumentation
|
7
11
|
module ActiveRecordHelper
|
8
12
|
module_function
|
9
13
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
14
|
+
ACTIVE_RECORD = "ActiveRecord".freeze unless defined?(ACTIVE_RECORD)
|
15
|
+
OTHER = "other".freeze unless defined?(OTHER)
|
16
|
+
|
17
|
+
def metrics_for(name, sql, adapter_name)
|
18
|
+
product = map_product(adapter_name)
|
19
|
+
splits = split_name(name)
|
20
|
+
model = model_from_splits(splits)
|
21
|
+
operation = operation_from_splits(splits, sql)
|
22
|
+
|
23
|
+
NewRelic::Agent::Datastores::MetricHelper.metrics_for(product,
|
24
|
+
operation,
|
25
|
+
model)
|
26
|
+
end
|
27
|
+
|
28
|
+
# @deprecated
|
29
|
+
def rollup_metrics_for(*_)
|
30
|
+
NewRelic::Agent::Deprecator.deprecate("#{self.class}.rollup_metrics_for",
|
31
|
+
"NewRelic::Agent::Datastores::MetricHelper.metrics_for")
|
32
|
+
|
33
|
+
rollup_metric = if NewRelic::Agent::Transaction.recording_web_transaction?
|
34
|
+
NewRelic::Agent::Datastores::MetricHelper::WEB_ROLLUP_METRIC
|
35
|
+
else
|
36
|
+
NewRelic::Agent::Datastores::MetricHelper::OTHER_ROLLUP_METRIC
|
37
|
+
end
|
38
|
+
|
39
|
+
[rollup_metric,
|
40
|
+
NewRelic::Agent::Datastores::MetricHelper::ROLLUP_METRIC]
|
41
|
+
end
|
42
|
+
|
43
|
+
SPACE = ' '.freeze unless defined?(SPACE)
|
44
|
+
EMPTY = [].freeze unless defined?(EMPTY)
|
45
|
+
|
46
|
+
def split_name(name)
|
47
|
+
if name && name.respond_to?(:split)
|
48
|
+
name.split(SPACE)
|
49
|
+
else
|
50
|
+
EMPTY
|
31
51
|
end
|
32
52
|
end
|
33
53
|
|
34
|
-
def
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
if operation
|
40
|
-
# Could not determine the model/operation so use a fallback metric
|
41
|
-
metric = "Database/SQL/#{operation}"
|
42
|
-
else
|
43
|
-
metric = "Database/SQL/other"
|
44
|
-
end
|
54
|
+
def model_from_splits(splits)
|
55
|
+
if splits.length == 2
|
56
|
+
splits.first
|
57
|
+
else
|
58
|
+
nil
|
45
59
|
end
|
46
|
-
metric
|
47
60
|
end
|
48
61
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
# If the metric name is in the form of "ActiveRecord/action"
|
53
|
-
# this returns merely: [ "Datastore/all", "ActiveRecord/all" ]
|
54
|
-
def rollup_metrics_for(metric)
|
55
|
-
metrics = ["Datastore/all"]
|
56
|
-
|
57
|
-
# If we're outside of a web transaction, don't record any rollup
|
58
|
-
# database metrics. This is to prevent metrics from background tasks
|
59
|
-
# from polluting the metrics used to drive overview graphs.
|
60
|
-
if NewRelic::Agent::Transaction.recording_web_transaction?
|
61
|
-
metrics << "ActiveRecord/all"
|
62
|
+
def operation_from_splits(splits, sql)
|
63
|
+
if splits.length == 2
|
64
|
+
map_operation(splits[1])
|
62
65
|
else
|
63
|
-
|
66
|
+
NewRelic::Agent::Database.parse_operation_from_query(sql) || OTHER
|
64
67
|
end
|
65
|
-
|
68
|
+
end
|
66
69
|
|
67
|
-
|
70
|
+
# These are used primarily to optimize and avoid allocation on well
|
71
|
+
# known operations coming in. Anything not matching the list is fine,
|
72
|
+
# it just needs to get downcased directly for use.
|
73
|
+
OPERATION_NAMES = {
|
74
|
+
'Find' => 'find',
|
75
|
+
'Load' => 'find',
|
76
|
+
'Count' => 'find',
|
77
|
+
'Exists' => 'find',
|
78
|
+
'Create' => 'create',
|
79
|
+
'Columns' => 'columns',
|
80
|
+
'Indexes' => 'indexes',
|
81
|
+
'Destroy' => 'destroy',
|
82
|
+
'Update' => 'update',
|
83
|
+
'Save' => 'save'
|
84
|
+
}.freeze unless defined?(OPERATION_NAMES)
|
85
|
+
|
86
|
+
def map_operation(raw_operation)
|
87
|
+
direct_op = OPERATION_NAMES[raw_operation]
|
88
|
+
return direct_op if direct_op
|
89
|
+
|
90
|
+
raw_operation.downcase
|
68
91
|
end
|
69
92
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
93
|
+
PRODUCT_NAMES = {
|
94
|
+
"mysql" => "MySQL",
|
95
|
+
"mysql2" => "MySQL",
|
96
|
+
|
97
|
+
"postgresql" => "Postgres",
|
98
|
+
|
99
|
+
"sqlite3" => "SQLite",
|
100
|
+
|
101
|
+
# https://rubygems.org/gems/activerecord-jdbcpostgresql-adapter
|
102
|
+
"jdbcmysql" => "MySQL",
|
103
|
+
|
104
|
+
# https://rubygems.org/gems/activerecord-jdbcpostgresql-adapter
|
105
|
+
"jdbcpostgresql" => "Postgres",
|
106
|
+
|
107
|
+
# https://rubygems.org/gems/activerecord-jdbcsqlite3-adapter
|
108
|
+
"jdbcsqlite3" => "SQLite",
|
109
|
+
|
110
|
+
# https://rubygems.org/gems/activerecord-jdbcderby-adapter
|
111
|
+
"derby" => "Derby",
|
112
|
+
"jdbcderby" => "Derby",
|
113
|
+
|
114
|
+
# https://rubygems.org/gems/activerecord-jdbc-adapter
|
115
|
+
"jdbc" => "JDBC",
|
116
|
+
|
117
|
+
# https://rubygems.org/gems/activerecord-jdbcmssql-adapter
|
118
|
+
"jdbcmssql" => "MSSQL",
|
119
|
+
"mssql" => "MSSQL",
|
120
|
+
|
121
|
+
# https://rubygems.org/gems/activerecord-sqlserver-adapter
|
122
|
+
"sqlserver" => "MSSQL",
|
123
|
+
|
124
|
+
# https://rubygems.org/gems/activerecord-odbc-adapter
|
125
|
+
"odbc" => "ODBC",
|
126
|
+
|
127
|
+
# https://rubygems.org/gems/activerecord-oracle_enhanced-adapter
|
128
|
+
"oracle_enhanced" => "Oracle"
|
129
|
+
}.freeze unless defined?(PRODUCT_NAMES)
|
130
|
+
|
131
|
+
ACTIVE_RECORD_DEFAULT_PRODUCT_NAME = "ActiveRecord".freeze unless defined?(ACTIVE_RECORD_DEFAULT_PRODUCT_NAME)
|
132
|
+
|
133
|
+
def map_product(adapter_name)
|
134
|
+
PRODUCT_NAMES.fetch(adapter_name,
|
135
|
+
ACTIVE_RECORD_DEFAULT_PRODUCT_NAME)
|
78
136
|
end
|
137
|
+
|
79
138
|
end
|
80
139
|
end
|
81
140
|
end
|
@@ -25,9 +25,10 @@ module NewRelic
|
|
25
25
|
return if payload[:name] == CACHED_QUERY_NAME
|
26
26
|
state = NewRelic::Agent::TransactionState.tl_get
|
27
27
|
return unless state.is_execution_traced?
|
28
|
-
event
|
29
|
-
|
30
|
-
|
28
|
+
event = pop_event(id)
|
29
|
+
config = active_record_config_for_event(event)
|
30
|
+
base_metric = record_metrics(event, config)
|
31
|
+
notice_sql(state, event, config, base_metric)
|
31
32
|
rescue => e
|
32
33
|
log_notification_error(e, name, 'finish')
|
33
34
|
end
|
@@ -42,10 +43,8 @@ module NewRelic
|
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
45
|
-
def notice_sql(state, event)
|
46
|
+
def notice_sql(state, event, config, metric)
|
46
47
|
stack = state.traced_method_stack
|
47
|
-
config = active_record_config_for_event(event)
|
48
|
-
metric = base_metric(event)
|
49
48
|
|
50
49
|
# enter transaction trace segment
|
51
50
|
frame = stack.push_frame(state, :active_record, event.time)
|
@@ -64,24 +63,16 @@ module NewRelic
|
|
64
63
|
stack.pop_frame(state, frame, metric, event.end)
|
65
64
|
end
|
66
65
|
|
67
|
-
def record_metrics(event) #THREAD_LOCAL_ACCESS
|
68
|
-
base =
|
69
|
-
|
70
|
-
|
71
|
-
if config = active_record_config_for_event(event)
|
72
|
-
other_metrics << ActiveRecordHelper.remote_service_metric(config[:adapter], config[:host])
|
73
|
-
end
|
74
|
-
other_metrics.compact!
|
66
|
+
def record_metrics(event, config) #THREAD_LOCAL_ACCESS
|
67
|
+
base, *other_metrics = ActiveRecordHelper.metrics_for(event.payload[:name],
|
68
|
+
NewRelic::Helper.correctly_encoded(event.payload[:sql]),
|
69
|
+
config && config[:adapter])
|
75
70
|
|
76
71
|
NewRelic::Agent.instance.stats_engine.tl_record_scoped_and_unscoped_metrics(
|
77
72
|
base, other_metrics,
|
78
|
-
Helper.milliseconds_to_seconds(event.duration)
|
79
|
-
)
|
80
|
-
end
|
73
|
+
Helper.milliseconds_to_seconds(event.duration))
|
81
74
|
|
82
|
-
|
83
|
-
ActiveRecordHelper.metric_for_name(event.payload[:name]) ||
|
84
|
-
ActiveRecordHelper.metric_for_sql(NewRelic::Helper.correctly_encoded(event.payload[:sql]))
|
75
|
+
base
|
85
76
|
end
|
86
77
|
|
87
78
|
def active_record_config_for_event(event)
|