newrelic_rpm 8.11.0 → 8.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -3
- data/.rubocop_todo.yml +14 -7
- data/Brewfile +1 -0
- data/CHANGELOG.md +78 -16
- data/README.md +1 -1
- data/bin/nrdebug +2 -0
- data/docker-compose.yml +22 -0
- data/lib/new_relic/agent/agent/shutdown.rb +1 -0
- data/lib/new_relic/agent/agent/special_startup.rb +2 -0
- data/lib/new_relic/agent/agent/startup.rb +1 -0
- data/lib/new_relic/agent/agent_logger.rb +1 -1
- data/lib/new_relic/agent/attributes.rb +1 -0
- data/lib/new_relic/agent/audit_logger.rb +2 -1
- data/lib/new_relic/agent/commands/thread_profiler_session.rb +1 -0
- data/lib/new_relic/agent/configuration/default_source.rb +1415 -1359
- data/lib/new_relic/agent/configuration/dotted_hash.rb +1 -0
- data/lib/new_relic/agent/configuration/environment_source.rb +3 -2
- data/lib/new_relic/agent/configuration/high_security_source.rb +1 -0
- data/lib/new_relic/agent/configuration/manager.rb +3 -0
- data/lib/new_relic/agent/configuration/security_policy_source.rb +10 -0
- data/lib/new_relic/agent/configuration/yaml_source.rb +1 -0
- data/lib/new_relic/agent/connect/request_builder.rb +1 -0
- data/lib/new_relic/agent/database/obfuscation_helpers.rb +1 -0
- data/lib/new_relic/agent/database.rb +7 -0
- data/lib/new_relic/agent/database_adapter.rb +2 -0
- data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +3 -2
- data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +1 -1
- data/lib/new_relic/agent/datastores/nosql_obfuscator.rb +41 -0
- data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +3 -0
- data/lib/new_relic/agent/distributed_tracing/distributed_trace_attributes.rb +3 -0
- data/lib/new_relic/agent/distributed_tracing/distributed_trace_metrics.rb +1 -0
- data/lib/new_relic/agent/distributed_tracing/distributed_trace_payload.rb +1 -0
- data/lib/new_relic/agent/distributed_tracing/trace_context.rb +1 -0
- data/lib/new_relic/agent/encoding_normalizer.rb +2 -0
- data/lib/new_relic/agent/error_collector.rb +3 -0
- data/lib/new_relic/agent/error_filter.rb +1 -0
- data/lib/new_relic/agent/error_trace_aggregator.rb +1 -0
- data/lib/new_relic/agent/event_aggregator.rb +1 -0
- data/lib/new_relic/agent/event_loop.rb +2 -0
- data/lib/new_relic/agent/http_clients/abstract.rb +2 -0
- data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +1 -1
- data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +1 -1
- data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +1 -0
- data/lib/new_relic/agent/instrumentation/active_merchant.rb +1 -2
- data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +2 -0
- data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +1 -2
- data/lib/new_relic/agent/instrumentation/authlogic.rb +0 -2
- data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +1 -0
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +0 -1
- data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +1 -2
- data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +29 -0
- data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +66 -0
- data/lib/new_relic/agent/instrumentation/elasticsearch/prepend.rb +13 -0
- data/lib/new_relic/agent/instrumentation/elasticsearch.rb +31 -0
- data/lib/new_relic/agent/instrumentation/excon.rb +17 -0
- data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +1 -0
- data/lib/new_relic/agent/instrumentation/logger/instrumentation.rb +4 -0
- data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +2 -0
- data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +2 -0
- data/lib/new_relic/agent/instrumentation/rack/chain.rb +10 -2
- data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +3 -0
- data/lib/new_relic/agent/instrumentation/rack/prepend.rb +9 -2
- data/lib/new_relic/agent/instrumentation/rainbows_instrumentation.rb +0 -1
- data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +1 -0
- data/lib/new_relic/agent/instrumentation/redis/chain.rb +18 -6
- data/lib/new_relic/agent/instrumentation/redis/constants.rb +17 -0
- data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +28 -18
- data/lib/new_relic/agent/instrumentation/redis/middleware.rb +16 -0
- data/lib/new_relic/agent/instrumentation/redis/prepend.rb +6 -0
- data/lib/new_relic/agent/instrumentation/redis.rb +6 -0
- data/lib/new_relic/agent/instrumentation/sidekiq/client.rb +20 -0
- data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +30 -0
- data/lib/new_relic/agent/instrumentation/sidekiq/server.rb +37 -0
- data/lib/new_relic/agent/instrumentation/sidekiq.rb +7 -70
- data/lib/new_relic/agent/instrumentation/sinatra.rb +1 -2
- data/lib/new_relic/agent/instrumentation/sunspot.rb +0 -2
- data/lib/new_relic/agent/instrumentation/thread/instrumentation.rb +1 -0
- data/lib/new_relic/agent/instrumentation/tilt/instrumentation.rb +1 -0
- data/lib/new_relic/agent/javascript_instrumentor.rb +1 -0
- data/lib/new_relic/agent/local_log_decorator.rb +1 -0
- data/lib/new_relic/agent/log_event_aggregator.rb +1 -0
- data/lib/new_relic/agent/messaging.rb +1 -0
- data/lib/new_relic/agent/method_tracer.rb +4 -0
- data/lib/new_relic/agent/method_tracer_helpers.rb +1 -1
- data/lib/new_relic/agent/monitors/distributed_tracing_monitor.rb +1 -0
- data/lib/new_relic/agent/new_relic_service.rb +2 -0
- data/lib/new_relic/agent/parameter_filtering.rb +7 -1
- data/lib/new_relic/agent/pipe_channel_manager.rb +2 -0
- data/lib/new_relic/agent/rules_engine.rb +1 -0
- data/lib/new_relic/agent/samplers/cpu_sampler.rb +1 -0
- data/lib/new_relic/agent/samplers/memory_sampler.rb +5 -0
- data/lib/new_relic/agent/span_event_primitive.rb +1 -0
- data/lib/new_relic/agent/stats.rb +1 -0
- data/lib/new_relic/agent/stats_engine/gc_profiler.rb +1 -0
- data/lib/new_relic/agent/system_info.rb +3 -0
- data/lib/new_relic/agent/threading/agent_thread.rb +1 -0
- data/lib/new_relic/agent/threading/backtrace_service.rb +1 -0
- data/lib/new_relic/agent/threading/thread_profile.rb +3 -0
- data/lib/new_relic/agent/tracer.rb +5 -1
- data/lib/new_relic/agent/transaction/abstract_segment.rb +3 -0
- data/lib/new_relic/agent/transaction/datastore_segment.rb +3 -0
- data/lib/new_relic/agent/transaction/distributed_tracer.rb +4 -0
- data/lib/new_relic/agent/transaction/distributed_tracing.rb +1 -0
- data/lib/new_relic/agent/transaction/external_request_segment.rb +1 -0
- data/lib/new_relic/agent/transaction/message_broker_segment.rb +1 -0
- data/lib/new_relic/agent/transaction/segment.rb +1 -0
- data/lib/new_relic/agent/transaction/trace.rb +4 -0
- data/lib/new_relic/agent/transaction/trace_node.rb +1 -0
- data/lib/new_relic/agent/transaction/transaction_sample_buffer.rb +2 -0
- data/lib/new_relic/agent/transaction.rb +10 -0
- data/lib/new_relic/agent/transaction_event_aggregator.rb +1 -0
- data/lib/new_relic/agent/transaction_time_aggregator.rb +1 -0
- data/lib/new_relic/agent/utilization/pcf.rb +1 -0
- data/lib/new_relic/agent/utilization/vendor.rb +2 -0
- data/lib/new_relic/agent/utilization_data.rb +3 -0
- data/lib/new_relic/agent.rb +4 -2
- data/lib/new_relic/cli/commands/install.rb +1 -0
- data/lib/new_relic/coerce.rb +6 -0
- data/lib/new_relic/collection_helper.rb +1 -0
- data/lib/new_relic/constants.rb +2 -0
- data/lib/new_relic/control/frameworks/rails.rb +5 -0
- data/lib/new_relic/control/instrumentation.rb +6 -8
- data/lib/new_relic/dependency_detection.rb +2 -0
- data/lib/new_relic/helper.rb +1 -0
- data/lib/new_relic/language_support.rb +1 -0
- data/lib/new_relic/latest_changes.rb +1 -0
- data/lib/new_relic/local_environment.rb +7 -1
- data/lib/new_relic/metric_spec.rb +2 -0
- data/lib/new_relic/rack/agent_middleware.rb +2 -0
- data/lib/new_relic/rack/browser_monitoring.rb +1 -0
- data/lib/new_relic/traced_thread.rb +1 -0
- data/lib/new_relic/version.rb +1 -1
- data/lib/tasks/helpers/format.rb +3 -0
- data/lib/tasks/helpers/prompt.rb +1 -1
- data/lib/tasks/instrumentation_generator/README.md +2 -2
- data/lib/tasks/instrumentation_generator/TODO.md +5 -5
- data/lib/tasks/instrumentation_generator/instrumentation.thor +27 -5
- data/lib/tasks/instrumentation_generator/templates/chain.tt +2 -1
- data/lib/tasks/instrumentation_generator/templates/chain_method.tt +3 -2
- data/lib/tasks/instrumentation_generator/templates/instrumentation.tt +2 -1
- data/lib/tasks/instrumentation_generator/templates/instrumentation_method.tt +1 -1
- data/lib/tasks/instrumentation_generator/templates/prepend.tt +1 -1
- data/lib/tasks/instrumentation_generator/templates/prepend_method.tt +1 -1
- data/lib/tasks/instrumentation_generator/templates/test.tt +1 -1
- data/newrelic.yml +13 -3
- data/newrelic_rpm.gemspec +7 -7
- data/test/agent_helper.rb +24 -0
- metadata +18 -79
- data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +0 -43
data/lib/new_relic/agent.rb
CHANGED
@@ -102,8 +102,6 @@ module NewRelic
|
|
102
102
|
# An error while serializing data for the collector
|
103
103
|
class SerializationError < StandardError; end
|
104
104
|
|
105
|
-
class BackgroundLoadingError < StandardError; end
|
106
|
-
|
107
105
|
# placeholder name used when we cannot determine a transaction's name
|
108
106
|
UNKNOWN_METRIC = '(unknown)'.freeze
|
109
107
|
|
@@ -115,6 +113,7 @@ module NewRelic
|
|
115
113
|
# The singleton Agent instance. Used internally.
|
116
114
|
def agent # :nodoc:
|
117
115
|
return @agent if @agent
|
116
|
+
|
118
117
|
NewRelic::Agent.logger.warn("Agent unavailable as it hasn't been started.")
|
119
118
|
NewRelic::Agent.logger.warn(caller.join("\n"))
|
120
119
|
nil
|
@@ -217,6 +216,7 @@ module NewRelic
|
|
217
216
|
|
218
217
|
def increment_metric(metric_name, amount = 1) # THREAD_LOCAL_ACCESS
|
219
218
|
return unless agent
|
219
|
+
|
220
220
|
if amount == 1
|
221
221
|
metrics = [metric_name, SUPPORTABILITY_INCREMENT_METRIC]
|
222
222
|
agent.stats_engine.tl_record_unscoped_metrics(metrics) { |stats| stats.increment_count }
|
@@ -347,6 +347,7 @@ module NewRelic
|
|
347
347
|
#
|
348
348
|
def manual_start(options = {})
|
349
349
|
raise "Options must be a hash" unless Hash === options
|
350
|
+
|
350
351
|
NewRelic::Control.instance.init_plugin({:agent_enabled => true, :sync_startup => true}.merge(options))
|
351
352
|
record_api_supportability_metric(:manual_start)
|
352
353
|
end
|
@@ -757,6 +758,7 @@ module NewRelic
|
|
757
758
|
record_api_supportability_metric(:browser_timing_header)
|
758
759
|
|
759
760
|
return EMPTY_STR unless agent
|
761
|
+
|
760
762
|
agent.javascript_instrumentor.browser_timing_header(nonce)
|
761
763
|
end
|
762
764
|
|
@@ -42,6 +42,7 @@ class NewRelic::Cli::Install < NewRelic::Cli::Command
|
|
42
42
|
if File.exist?(dest_file) && !@force
|
43
43
|
raise NewRelic::Cli::Command::CommandFailure, "newrelic.yml file already exists. Use --force flag to overwrite."
|
44
44
|
end
|
45
|
+
|
45
46
|
File.open(dest_file, 'w') { |out| out.puts(content) }
|
46
47
|
|
47
48
|
puts <<-EOF unless quiet
|
data/lib/new_relic/coerce.rb
CHANGED
@@ -22,6 +22,7 @@ module NewRelic
|
|
22
22
|
|
23
23
|
def int_or_nil(value, context = nil)
|
24
24
|
return nil if value.nil?
|
25
|
+
|
25
26
|
Integer(value)
|
26
27
|
rescue => error
|
27
28
|
log_failure(value, Integer, context, error)
|
@@ -31,6 +32,7 @@ module NewRelic
|
|
31
32
|
def float(value, context = nil)
|
32
33
|
result = Float(value)
|
33
34
|
raise "Value #{result.inspect} is not finite." unless result.finite?
|
35
|
+
|
34
36
|
result
|
35
37
|
rescue => error
|
36
38
|
log_failure(value, Float, context, error)
|
@@ -39,6 +41,7 @@ module NewRelic
|
|
39
41
|
|
40
42
|
def string(value, context = nil)
|
41
43
|
return value if value.nil?
|
44
|
+
|
42
45
|
String(value)
|
43
46
|
rescue => error
|
44
47
|
log_failure(value.class, String, context, error)
|
@@ -62,6 +65,7 @@ module NewRelic
|
|
62
65
|
|
63
66
|
def int!(value)
|
64
67
|
return nil unless value_or_nil(value)
|
68
|
+
|
65
69
|
Integer(value)
|
66
70
|
end
|
67
71
|
|
@@ -74,11 +78,13 @@ module NewRelic
|
|
74
78
|
|
75
79
|
def float!(value, precision = NewRelic::PRIORITY_PRECISION)
|
76
80
|
return nil unless value_or_nil(value)
|
81
|
+
|
77
82
|
value.to_f.round(precision)
|
78
83
|
end
|
79
84
|
|
80
85
|
def value_or_nil(value)
|
81
86
|
return nil if value.nil? || (value.respond_to?(:empty?) && value.empty?)
|
87
|
+
|
82
88
|
value
|
83
89
|
end
|
84
90
|
|
@@ -13,6 +13,7 @@ module NewRelic
|
|
13
13
|
when Hash
|
14
14
|
# Optimize for empty hash since that is often what this is called with.
|
15
15
|
return params if params.empty?
|
16
|
+
|
16
17
|
new_params = {}
|
17
18
|
params.each do |key, value|
|
18
19
|
new_params[truncate(normalize_params(key), 64)] = normalize_params(value)
|
data/lib/new_relic/constants.rb
CHANGED
@@ -27,6 +27,8 @@ module NewRelic
|
|
27
27
|
TRACEPARENT_KEY = "traceparent"
|
28
28
|
TRACESTATE_KEY = "tracestate"
|
29
29
|
|
30
|
+
STANDARD_OUT = 'STDOUT'
|
31
|
+
|
30
32
|
HTTP_TRACEPARENT_KEY = "HTTP_#{TRACEPARENT_KEY.upcase}"
|
31
33
|
HTTP_TRACESTATE_KEY = "HTTP_#{TRACESTATE_KEY.upcase}"
|
32
34
|
HTTP_NEWRELIC_KEY = "HTTP_#{NEWRELIC_KEY.upcase}"
|
@@ -68,11 +68,14 @@ module NewRelic
|
|
68
68
|
|
69
69
|
def install_agent_hooks(config)
|
70
70
|
return if defined?(@agent_hooks_installed) && @agent_hooks_installed
|
71
|
+
|
71
72
|
@agent_hooks_installed = true
|
72
73
|
return if config.nil? || !config.respond_to?(:middleware)
|
74
|
+
|
73
75
|
begin
|
74
76
|
require 'new_relic/rack/agent_hooks'
|
75
77
|
return unless NewRelic::Rack::AgentHooks.needed?
|
78
|
+
|
76
79
|
config.middleware.use(NewRelic::Rack::AgentHooks)
|
77
80
|
::NewRelic::Agent.logger.debug("Installed New Relic Agent Hooks middleware")
|
78
81
|
rescue => e
|
@@ -83,8 +86,10 @@ module NewRelic
|
|
83
86
|
def install_browser_monitoring(config)
|
84
87
|
@install_lock.synchronize do
|
85
88
|
return if defined?(@browser_monitoring_installed) && @browser_monitoring_installed
|
89
|
+
|
86
90
|
@browser_monitoring_installed = true
|
87
91
|
return if config.nil? || !config.respond_to?(:middleware) || !Agent.config[:'browser_monitoring.auto_instrument']
|
92
|
+
|
88
93
|
begin
|
89
94
|
require 'new_relic/rack/browser_monitoring'
|
90
95
|
config.middleware.use(NewRelic::Rack::BrowserMonitoring)
|
@@ -62,7 +62,7 @@ module NewRelic
|
|
62
62
|
File.join(instrumentation_path, app.to_s, '*.rb')
|
63
63
|
@instrumentation_files.each { |pattern| load_instrumentation_files(pattern) }
|
64
64
|
DependencyDetection.detect!
|
65
|
-
|
65
|
+
ruby_deprecation
|
66
66
|
rails_32_deprecation
|
67
67
|
::NewRelic::Agent.logger.info("Finished instrumentation")
|
68
68
|
end
|
@@ -70,6 +70,7 @@ module NewRelic
|
|
70
70
|
|
71
71
|
def rails_32_deprecation
|
72
72
|
return unless defined?(Rails::VERSION) && Gem::Version.new(Rails::VERSION::STRING) <= Gem::Version.new('3.2')
|
73
|
+
|
73
74
|
deprecation_msg = 'The Ruby Agent is dropping support for Rails 3.2 ' \
|
74
75
|
'in a future major release. Please upgrade your Rails version to continue receiving support. ' \
|
75
76
|
|
@@ -78,13 +79,12 @@ module NewRelic
|
|
78
79
|
:deprecated_rails_version,
|
79
80
|
deprecation_msg
|
80
81
|
)
|
81
|
-
|
82
|
-
::NewRelic::Agent.record_metric("Supportability/Deprecated/Rails32", 1)
|
83
82
|
end
|
84
83
|
|
85
|
-
def
|
86
|
-
return unless RUBY_VERSION
|
87
|
-
|
84
|
+
def ruby_deprecation
|
85
|
+
return unless RUBY_VERSION < '2.4.0'
|
86
|
+
|
87
|
+
deprecation_msg = 'The Ruby Agent is dropping support for Rubies below 2.4 ' \
|
88
88
|
'in version 9.0.0. Please upgrade your Ruby version to continue receiving support. ' \
|
89
89
|
|
90
90
|
::NewRelic::Agent.logger.log_once(
|
@@ -92,8 +92,6 @@ module NewRelic
|
|
92
92
|
:deprecated_ruby_version,
|
93
93
|
deprecation_msg
|
94
94
|
)
|
95
|
-
|
96
|
-
::NewRelic::Agent.record_metric("Supportability/Deprecated/Ruby22", 1)
|
97
95
|
end
|
98
96
|
|
99
97
|
include Instrumentation
|
@@ -165,6 +165,7 @@ module DependencyDetection
|
|
165
165
|
|
166
166
|
def config_key
|
167
167
|
return nil if self.config_name.nil?
|
168
|
+
|
168
169
|
@config_key ||= "instrumentation.#{self.config_name}".to_sym
|
169
170
|
end
|
170
171
|
|
@@ -193,6 +194,7 @@ module DependencyDetection
|
|
193
194
|
|
194
195
|
def config_value
|
195
196
|
return AUTO_CONFIG_VALUE unless config_key
|
197
|
+
|
196
198
|
fetch_config_value(config_key)
|
197
199
|
end
|
198
200
|
|
data/lib/new_relic/helper.rb
CHANGED
@@ -17,6 +17,7 @@ module NewRelic
|
|
17
17
|
# If not force the encoding to ASCII-8BIT (binary)
|
18
18
|
def correctly_encoded(string)
|
19
19
|
return string unless string.is_a?(String)
|
20
|
+
|
20
21
|
# The .dup here is intentional, since force_encoding mutates the target,
|
21
22
|
# and we don't know who is going to use this string downstream of us.
|
22
23
|
string.valid_encoding? ? string : string.dup.force_encoding(Encoding::ASCII_8BIT)
|
@@ -71,10 +71,10 @@ module NewRelic
|
|
71
71
|
thin
|
72
72
|
mongrel
|
73
73
|
litespeed
|
74
|
+
unicorn
|
74
75
|
webrick
|
75
76
|
fastcgi
|
76
77
|
rainbows
|
77
|
-
unicorn
|
78
78
|
]
|
79
79
|
# TODO: MAJOR VERSION - remove rainbows
|
80
80
|
while dispatchers.any? && @discovered_dispatcher.nil?
|
@@ -85,6 +85,7 @@ module NewRelic
|
|
85
85
|
def check_for_torquebox
|
86
86
|
return unless defined?(::JRuby) &&
|
87
87
|
(org.torquebox::TorqueBox rescue nil)
|
88
|
+
|
88
89
|
@discovered_dispatcher = :torquebox
|
89
90
|
end
|
90
91
|
|
@@ -93,11 +94,13 @@ module NewRelic
|
|
93
94
|
(((com.sun.grizzly.jruby.rack.DefaultRackApplicationFactory rescue nil) &&
|
94
95
|
defined?(com::sun::grizzly::jruby::rack::DefaultRackApplicationFactory)) ||
|
95
96
|
(jruby_rack? && defined?(::GlassFish::Server)))
|
97
|
+
|
96
98
|
@discovered_dispatcher = :glassfish
|
97
99
|
end
|
98
100
|
|
99
101
|
def check_for_trinidad
|
100
102
|
return unless defined?(::JRuby) && jruby_rack? && defined?(::Trinidad::Server)
|
103
|
+
|
101
104
|
@discovered_dispatcher = :trinidad
|
102
105
|
end
|
103
106
|
|
@@ -107,17 +110,20 @@ module NewRelic
|
|
107
110
|
|
108
111
|
def check_for_webrick
|
109
112
|
return unless defined?(::WEBrick) && defined?(::WEBrick::VERSION)
|
113
|
+
|
110
114
|
@discovered_dispatcher = :webrick
|
111
115
|
end
|
112
116
|
|
113
117
|
def check_for_fastcgi
|
114
118
|
return unless defined?(::FCGI)
|
119
|
+
|
115
120
|
@discovered_dispatcher = :fastcgi
|
116
121
|
end
|
117
122
|
|
118
123
|
# this case covers starting by mongrel_rails
|
119
124
|
def check_for_mongrel
|
120
125
|
return unless defined?(::Mongrel) && defined?(::Mongrel::HttpServer)
|
126
|
+
|
121
127
|
@discovered_dispatcher = :mongrel
|
122
128
|
end
|
123
129
|
|
@@ -44,6 +44,7 @@ class NewRelic::MetricSpec
|
|
44
44
|
|
45
45
|
def to_s
|
46
46
|
return name if scope.empty?
|
47
|
+
|
47
48
|
"#{name}:#{scope}"
|
48
49
|
end
|
49
50
|
|
@@ -59,6 +60,7 @@ class NewRelic::MetricSpec
|
|
59
60
|
def <=>(o)
|
60
61
|
namecmp = self.name <=> o.name
|
61
62
|
return namecmp if namecmp != 0
|
63
|
+
|
62
64
|
return (self.scope || '') <=> (o.scope || '')
|
63
65
|
end
|
64
66
|
end
|
@@ -33,11 +33,13 @@ module NewRelic
|
|
33
33
|
# response code before it goes back to the client.
|
34
34
|
def capture_http_response_code(state, result)
|
35
35
|
return if NewRelic::Agent.config[:disable_middleware_instrumentation]
|
36
|
+
|
36
37
|
super
|
37
38
|
end
|
38
39
|
|
39
40
|
def capture_response_content_type(state, result)
|
40
41
|
return if NewRelic::Agent.config[:disable_middleware_instrumentation]
|
42
|
+
|
41
43
|
super
|
42
44
|
end
|
43
45
|
end
|
@@ -104,6 +104,7 @@ module NewRelic
|
|
104
104
|
end
|
105
105
|
|
106
106
|
def streaming?(env, headers)
|
107
|
+
# Chunked transfer encoding is a streaming data transfer mechanism available only in HTTP/1.1
|
107
108
|
return true if headers && headers['Transfer-Encoding'] == 'chunked'
|
108
109
|
|
109
110
|
defined?(ActionController::Live) &&
|
@@ -28,6 +28,7 @@ module NewRelic
|
|
28
28
|
|
29
29
|
def create_traced_block(*args, &block)
|
30
30
|
return block if NewRelic::Agent.config[:'instrumentation.thread.tracing'] # if this is on, don't double trace
|
31
|
+
|
31
32
|
NewRelic::Agent::Tracer.thread_block_with_current_transaction(*args, &block)
|
32
33
|
end
|
33
34
|
end
|
data/lib/new_relic/version.rb
CHANGED
data/lib/tasks/helpers/format.rb
CHANGED
@@ -25,6 +25,7 @@ module Format
|
|
25
25
|
sections = Hash.new { |hash, key| hash[key] = [] }
|
26
26
|
NewRelic::Agent::Configuration::DEFAULTS.each do |key, value|
|
27
27
|
next unless value[:public]
|
28
|
+
|
28
29
|
key = key.to_s
|
29
30
|
section_key = section_key(key, key.split('.'))
|
30
31
|
sections[section_key] << format_sections(key, value)
|
@@ -55,6 +56,7 @@ module Format
|
|
55
56
|
|
56
57
|
def format_default_value(spec)
|
57
58
|
return spec[:documentation_default] if !spec[:documentation_default].nil?
|
59
|
+
|
58
60
|
if spec[:default].is_a?(Proc)
|
59
61
|
'(Dynamic)'
|
60
62
|
else
|
@@ -71,6 +73,7 @@ module Format
|
|
71
73
|
|
72
74
|
def format_env_var(key)
|
73
75
|
return "None" if NON_ENV_CONFIGS.include?(key)
|
76
|
+
|
74
77
|
"NEW_RELIC_#{key.tr(".", "_").upcase}"
|
75
78
|
end
|
76
79
|
|
data/lib/tasks/helpers/prompt.rb
CHANGED
@@ -58,6 +58,6 @@ Furthermore, we also create very similar snippets inside the default source conf
|
|
58
58
|
|
59
59
|
## Outcome
|
60
60
|
|
61
|
-
A prototype outside the agent
|
61
|
+
A prototype outside the agent was first created. This prototype generated the required files to add instrumentation. The prototype accepted three arguments: name (name of the library), method (method to instrument), args (arguments for the method). This prototype has evolved into the current directory.
|
62
62
|
|
63
|
-
|
63
|
+
This project leverages the Ruby gem Thor, a toolkit for building powerful command-line interfaces used in Bundler, Vagrant, Rails and others powers this CLI.
|
@@ -22,12 +22,12 @@
|
|
22
22
|
|
23
23
|
# - [ ] Append a new method to instrument to an existing instrumentation class (with tests?)
|
24
24
|
|
25
|
-
# - [ ] Documentation: examples of what to add in each gap
|
26
|
-
|
27
|
-
# - [ ] Good examples of tests, instrumentation, etc. as comments
|
25
|
+
# - [ ] Documentation: examples of what to add in each gap (Good examples of tests, instrumentation, etc. as comments to guide users)
|
28
26
|
|
29
27
|
# - [ ] Handle multi-word gem names (camel case for classes, handle hyphens, concurrent-ruby as example)
|
30
28
|
|
31
|
-
# - [ ]
|
29
|
+
# - [ ] Allow multiple method arguments to be passed to the command line
|
30
|
+
|
31
|
+
# - [ ] Add tests for the instrumentation_generator code
|
32
32
|
|
33
|
-
# - [ ]
|
33
|
+
# - [ ] See if instrumentation PRs can get automatically generated when an already instrumented library adds methods to its codebase
|
@@ -11,6 +11,7 @@ class Instrumentation < Thor
|
|
11
11
|
INSTRUMENTATION_ROOT = 'lib/new_relic/agent/instrumentation/'
|
12
12
|
MULTIVERSE_SUITE_ROOT = 'test/multiverse/suites/'
|
13
13
|
DEFAULT_SOURCE_LOCATION = 'lib/new_relic/agent/configuration/default_source.rb'
|
14
|
+
NEWRELIC_YML_LOCATION = 'newrelic.yml'
|
14
15
|
|
15
16
|
desc('scaffold NAME', 'Scaffold the required files for adding new instrumentation')
|
16
17
|
long_desc <<-LONGDESC
|
@@ -37,7 +38,8 @@ class Instrumentation < Thor
|
|
37
38
|
|
38
39
|
empty_directory(base_path)
|
39
40
|
create_instrumentation_files(base_path)
|
40
|
-
|
41
|
+
append_to_default_source(name)
|
42
|
+
append_to_newrelic_yml(name)
|
41
43
|
create_tests(name)
|
42
44
|
end
|
43
45
|
|
@@ -76,7 +78,7 @@ class Instrumentation < Thor
|
|
76
78
|
template('templates/newrelic.yml.tt', "#{base_path}/config/newrelic.yml")
|
77
79
|
end
|
78
80
|
|
79
|
-
def
|
81
|
+
def append_to_default_source(name)
|
80
82
|
insert_into_file(
|
81
83
|
DEFAULT_SOURCE_LOCATION,
|
82
84
|
config_block(name.downcase),
|
@@ -85,18 +87,38 @@ class Instrumentation < Thor
|
|
85
87
|
)
|
86
88
|
end
|
87
89
|
|
88
|
-
def
|
90
|
+
def append_to_newrelic_yml(name)
|
91
|
+
insert_into_file(
|
92
|
+
NEWRELIC_YML_LOCATION,
|
93
|
+
yaml_block(name),
|
94
|
+
after: "# instrumentation.bunny: auto\n"
|
95
|
+
)
|
96
|
+
end
|
97
|
+
|
98
|
+
def config_block(name)
|
89
99
|
<<-CONFIG
|
90
|
-
:'instrumentation.#{
|
100
|
+
:'instrumentation.#{name.downcase}' => {
|
91
101
|
:default => 'auto',
|
92
102
|
:public => true,
|
93
103
|
:type => String,
|
94
104
|
:dynamic_name => true,
|
95
105
|
:allowed_from_server => false,
|
96
|
-
:description => 'Controls auto-instrumentation of the #{
|
106
|
+
:description => 'Controls auto-instrumentation of the #{name} library at start up. May be one of [auto|prepend|chain|disabled].'
|
97
107
|
},
|
98
108
|
CONFIG
|
99
109
|
end
|
110
|
+
|
111
|
+
# TODO: OLD RUBIES - RUBY_VERSION 2.2
|
112
|
+
# When we only support 2.3+ this can be changed to a sqiggle heredoc (<<~)
|
113
|
+
# and use standard indentation
|
114
|
+
def yaml_block(name)
|
115
|
+
<<HEREDOC # rubocop:disable Layout/IndentationWidth
|
116
|
+
|
117
|
+
# Controls auto-instrumentation of #{name} at start up.
|
118
|
+
# May be one of [auto|prepend|chain|disabled]
|
119
|
+
# instrumentation.#{name.downcase}: auto
|
120
|
+
HEREDOC
|
121
|
+
end
|
100
122
|
end
|
101
123
|
|
102
124
|
Instrumentation.start(ARGV)
|
@@ -9,9 +9,10 @@ module NewRelic::Agent::Instrumentation
|
|
9
9
|
include NewRelic::Agent::Instrumentation::<%= @class_name %>
|
10
10
|
|
11
11
|
alias_method(:<%= @method.downcase %>_without_new_relic, :<%= @method.downcase %>)
|
12
|
+
alias_method(:<%= @method.downcase %>, :<%= @method.downcase %>_with_new_relic)
|
12
13
|
|
13
14
|
def <%= @method.downcase %><%= "(#{@args})" unless @args.empty? %>
|
14
|
-
<%= @method.downcase %>
|
15
|
+
<%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %> do
|
15
16
|
<%= @method.downcase %>_without_new_relic<%= "(#{@args})" unless @args.empty? %>
|
16
17
|
end
|
17
18
|
end
|
@@ -1,7 +1,8 @@
|
|
1
|
-
alias_method
|
1
|
+
alias_method(:<%= @method.downcase %>_without_new_relic, :<%= @method.downcase %>)
|
2
|
+
alias_method(:<%= @method.downcase %>, :<%= @method.downcase %>_with_new_relic)
|
2
3
|
|
3
4
|
def <%= @method.downcase %><%= "(#{@args})" unless @args.empty? %>
|
4
|
-
<%= @method.downcase %>
|
5
|
+
<%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %> do
|
5
6
|
<%= @method.downcase %>_without_new_relic<%= "(#{@args})" unless @args.empty? %>
|
6
7
|
end
|
7
8
|
end
|
@@ -5,8 +5,9 @@
|
|
5
5
|
module NewRelic::Agent::Instrumentation
|
6
6
|
module <%= @class_name %>
|
7
7
|
|
8
|
-
def <%= @method.downcase %>
|
8
|
+
def <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %>
|
9
9
|
# add instrumentation content here
|
10
|
+
yield
|
10
11
|
end
|
11
12
|
end
|
12
13
|
end
|
@@ -7,7 +7,7 @@ module NewRelic::Agent::Instrumentation
|
|
7
7
|
include NewRelic::Agent::Instrumentation::<%= @class_name %>
|
8
8
|
|
9
9
|
def <%= @method.downcase %><%= "(#{@args})" unless @args.empty? %>
|
10
|
-
<%= @method.downcase %>
|
10
|
+
<%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %> { super }
|
11
11
|
end
|
12
12
|
end
|
13
13
|
end
|
data/newrelic.yml
CHANGED
@@ -145,7 +145,7 @@ common: &default_settings
|
|
145
145
|
|
146
146
|
# Specify a maximum number of custom Insights events to buffer in memory at a
|
147
147
|
# time.
|
148
|
-
# custom_insights_events.max_samples_stored:
|
148
|
+
# custom_insights_events.max_samples_stored: 3000
|
149
149
|
|
150
150
|
# If false, the agent will not add database_name parameter to transaction or #
|
151
151
|
# slow sql traces.
|
@@ -271,7 +271,7 @@ common: &default_settings
|
|
271
271
|
|
272
272
|
# Forces the exit handler that sends all cached data to collector before
|
273
273
|
# shutting down to be installed regardless of detecting scenarios where it
|
274
|
-
# generally should
|
274
|
+
# generally should not be. Known use-case for this option is where Sinatra is
|
275
275
|
# running as an embedded service within another framework and the agent is
|
276
276
|
# detecting the Sinatra app and skipping the at_exit handler as a result.
|
277
277
|
# Sinatra classically runs the entire application in an at_exit block and would
|
@@ -322,6 +322,10 @@ common: &default_settings
|
|
322
322
|
# May be one of [auto|prepend|chain|disabled].
|
323
323
|
# instrumentation.delayed_job: auto
|
324
324
|
|
325
|
+
# Controls auto-instrumentation of the elasticsearch library at start up.
|
326
|
+
# May be one of [auto|prepend|chain|disabled].
|
327
|
+
# instrumentation.elasticsearch: auto
|
328
|
+
|
325
329
|
# Controls auto-instrumentation of Excon at start up.
|
326
330
|
# May be one of [enabled|disabled].
|
327
331
|
# instrumentation.excon: auto
|
@@ -434,7 +438,7 @@ common: &default_settings
|
|
434
438
|
# instrumentation.grpc.host_denylist: ""
|
435
439
|
|
436
440
|
# A dictionary of label names and values that will be applied to the data sent
|
437
|
-
# from this agent. May also be expressed
|
441
|
+
# from this agent. May also be expressed as a semicolon-delimited ; string of
|
438
442
|
# colon-separated : pairs.
|
439
443
|
# For example,<var>Server</var>:<var>One</var>;<var>Data Center</var>:<var>Primary</var>.
|
440
444
|
# labels: ""
|
@@ -459,6 +463,12 @@ common: &default_settings
|
|
459
463
|
# If true, the agent obfuscates Mongo queries in transaction traces.
|
460
464
|
# mongo.obfuscate_queries: true
|
461
465
|
|
466
|
+
# If true, the agent captures Elasticsearch queries in transaction traces.
|
467
|
+
# elasticsearch.capture_queries: true
|
468
|
+
|
469
|
+
# If true, the agent obfuscates Elasticsearch queries in transaction traces.
|
470
|
+
# elasticsearch.obfuscate_queries: true
|
471
|
+
|
462
472
|
# When true, the agent transmits data about your app to the New Relic collector.
|
463
473
|
# monitor_mode: true
|
464
474
|
|
data/newrelic_rpm.gemspec
CHANGED
@@ -51,14 +51,14 @@ https://github.com/newrelic/newrelic-ruby-agent/
|
|
51
51
|
s.add_development_dependency 'httparty' unless ENV['CI'] # for perf tests and Gabby
|
52
52
|
s.add_development_dependency 'minitest', "#{RUBY_VERSION >= '2.7.0' ? '5.3.3' : '4.7.5'}"
|
53
53
|
s.add_development_dependency 'minitest-stub-const', '0.6'
|
54
|
-
s.add_development_dependency 'mocha', '~> 1.
|
54
|
+
s.add_development_dependency 'mocha', '~> 1.16'
|
55
55
|
s.add_development_dependency 'pry' unless ENV['CI']
|
56
56
|
s.add_development_dependency 'rake', '12.3.3'
|
57
|
-
s.add_development_dependency 'rubocop'
|
58
|
-
s.add_development_dependency 'rubocop-minitest'
|
59
|
-
s.add_development_dependency 'rubocop-performance'
|
60
|
-
s.add_development_dependency 'rubocop-rake'
|
57
|
+
s.add_development_dependency 'rubocop' unless ENV['CI'] && RUBY_VERSION < '3.0.0'
|
58
|
+
s.add_development_dependency 'rubocop-minitest' unless ENV['CI'] && RUBY_VERSION < '3.0.0'
|
59
|
+
s.add_development_dependency 'rubocop-performance' unless ENV['CI'] && RUBY_VERSION < '3.0.0'
|
60
|
+
s.add_development_dependency 'rubocop-rake' unless ENV['CI'] && RUBY_VERSION < '3.0.0'
|
61
61
|
s.add_development_dependency 'simplecov' if RUBY_VERSION >= '2.7.0'
|
62
|
-
s.add_development_dependency 'thor'
|
63
|
-
s.add_development_dependency 'yard'
|
62
|
+
s.add_development_dependency 'thor' unless ENV['CI']
|
63
|
+
s.add_development_dependency 'yard', "#{RUBY_VERSION < '2.3.0' ? '0.9.26' : '> 0.9.26'}"
|
64
64
|
end
|