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.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -3
  3. data/.rubocop_todo.yml +14 -7
  4. data/Brewfile +1 -0
  5. data/CHANGELOG.md +78 -16
  6. data/README.md +1 -1
  7. data/bin/nrdebug +2 -0
  8. data/docker-compose.yml +22 -0
  9. data/lib/new_relic/agent/agent/shutdown.rb +1 -0
  10. data/lib/new_relic/agent/agent/special_startup.rb +2 -0
  11. data/lib/new_relic/agent/agent/startup.rb +1 -0
  12. data/lib/new_relic/agent/agent_logger.rb +1 -1
  13. data/lib/new_relic/agent/attributes.rb +1 -0
  14. data/lib/new_relic/agent/audit_logger.rb +2 -1
  15. data/lib/new_relic/agent/commands/thread_profiler_session.rb +1 -0
  16. data/lib/new_relic/agent/configuration/default_source.rb +1415 -1359
  17. data/lib/new_relic/agent/configuration/dotted_hash.rb +1 -0
  18. data/lib/new_relic/agent/configuration/environment_source.rb +3 -2
  19. data/lib/new_relic/agent/configuration/high_security_source.rb +1 -0
  20. data/lib/new_relic/agent/configuration/manager.rb +3 -0
  21. data/lib/new_relic/agent/configuration/security_policy_source.rb +10 -0
  22. data/lib/new_relic/agent/configuration/yaml_source.rb +1 -0
  23. data/lib/new_relic/agent/connect/request_builder.rb +1 -0
  24. data/lib/new_relic/agent/database/obfuscation_helpers.rb +1 -0
  25. data/lib/new_relic/agent/database.rb +7 -0
  26. data/lib/new_relic/agent/database_adapter.rb +2 -0
  27. data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +3 -2
  28. data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +1 -1
  29. data/lib/new_relic/agent/datastores/nosql_obfuscator.rb +41 -0
  30. data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +3 -0
  31. data/lib/new_relic/agent/distributed_tracing/distributed_trace_attributes.rb +3 -0
  32. data/lib/new_relic/agent/distributed_tracing/distributed_trace_metrics.rb +1 -0
  33. data/lib/new_relic/agent/distributed_tracing/distributed_trace_payload.rb +1 -0
  34. data/lib/new_relic/agent/distributed_tracing/trace_context.rb +1 -0
  35. data/lib/new_relic/agent/encoding_normalizer.rb +2 -0
  36. data/lib/new_relic/agent/error_collector.rb +3 -0
  37. data/lib/new_relic/agent/error_filter.rb +1 -0
  38. data/lib/new_relic/agent/error_trace_aggregator.rb +1 -0
  39. data/lib/new_relic/agent/event_aggregator.rb +1 -0
  40. data/lib/new_relic/agent/event_loop.rb +2 -0
  41. data/lib/new_relic/agent/http_clients/abstract.rb +2 -0
  42. data/lib/new_relic/agent/http_clients/http_rb_wrappers.rb +1 -1
  43. data/lib/new_relic/agent/http_clients/httpclient_wrappers.rb +1 -1
  44. data/lib/new_relic/agent/http_clients/typhoeus_wrappers.rb +1 -0
  45. data/lib/new_relic/agent/instrumentation/active_merchant.rb +1 -2
  46. data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +2 -0
  47. data/lib/new_relic/agent/instrumentation/acts_as_solr.rb +1 -2
  48. data/lib/new_relic/agent/instrumentation/authlogic.rb +0 -2
  49. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +1 -0
  50. data/lib/new_relic/agent/instrumentation/data_mapper.rb +0 -1
  51. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +1 -2
  52. data/lib/new_relic/agent/instrumentation/elasticsearch/chain.rb +29 -0
  53. data/lib/new_relic/agent/instrumentation/elasticsearch/instrumentation.rb +66 -0
  54. data/lib/new_relic/agent/instrumentation/elasticsearch/prepend.rb +13 -0
  55. data/lib/new_relic/agent/instrumentation/elasticsearch.rb +31 -0
  56. data/lib/new_relic/agent/instrumentation/excon.rb +17 -0
  57. data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +1 -0
  58. data/lib/new_relic/agent/instrumentation/logger/instrumentation.rb +4 -0
  59. data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +2 -0
  60. data/lib/new_relic/agent/instrumentation/notifications_subscriber.rb +2 -0
  61. data/lib/new_relic/agent/instrumentation/rack/chain.rb +10 -2
  62. data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +3 -0
  63. data/lib/new_relic/agent/instrumentation/rack/prepend.rb +9 -2
  64. data/lib/new_relic/agent/instrumentation/rainbows_instrumentation.rb +0 -1
  65. data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +1 -0
  66. data/lib/new_relic/agent/instrumentation/redis/chain.rb +18 -6
  67. data/lib/new_relic/agent/instrumentation/redis/constants.rb +17 -0
  68. data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +28 -18
  69. data/lib/new_relic/agent/instrumentation/redis/middleware.rb +16 -0
  70. data/lib/new_relic/agent/instrumentation/redis/prepend.rb +6 -0
  71. data/lib/new_relic/agent/instrumentation/redis.rb +6 -0
  72. data/lib/new_relic/agent/instrumentation/sidekiq/client.rb +20 -0
  73. data/lib/new_relic/agent/instrumentation/sidekiq/extensions/delayed_class.rb +30 -0
  74. data/lib/new_relic/agent/instrumentation/sidekiq/server.rb +37 -0
  75. data/lib/new_relic/agent/instrumentation/sidekiq.rb +7 -70
  76. data/lib/new_relic/agent/instrumentation/sinatra.rb +1 -2
  77. data/lib/new_relic/agent/instrumentation/sunspot.rb +0 -2
  78. data/lib/new_relic/agent/instrumentation/thread/instrumentation.rb +1 -0
  79. data/lib/new_relic/agent/instrumentation/tilt/instrumentation.rb +1 -0
  80. data/lib/new_relic/agent/javascript_instrumentor.rb +1 -0
  81. data/lib/new_relic/agent/local_log_decorator.rb +1 -0
  82. data/lib/new_relic/agent/log_event_aggregator.rb +1 -0
  83. data/lib/new_relic/agent/messaging.rb +1 -0
  84. data/lib/new_relic/agent/method_tracer.rb +4 -0
  85. data/lib/new_relic/agent/method_tracer_helpers.rb +1 -1
  86. data/lib/new_relic/agent/monitors/distributed_tracing_monitor.rb +1 -0
  87. data/lib/new_relic/agent/new_relic_service.rb +2 -0
  88. data/lib/new_relic/agent/parameter_filtering.rb +7 -1
  89. data/lib/new_relic/agent/pipe_channel_manager.rb +2 -0
  90. data/lib/new_relic/agent/rules_engine.rb +1 -0
  91. data/lib/new_relic/agent/samplers/cpu_sampler.rb +1 -0
  92. data/lib/new_relic/agent/samplers/memory_sampler.rb +5 -0
  93. data/lib/new_relic/agent/span_event_primitive.rb +1 -0
  94. data/lib/new_relic/agent/stats.rb +1 -0
  95. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +1 -0
  96. data/lib/new_relic/agent/system_info.rb +3 -0
  97. data/lib/new_relic/agent/threading/agent_thread.rb +1 -0
  98. data/lib/new_relic/agent/threading/backtrace_service.rb +1 -0
  99. data/lib/new_relic/agent/threading/thread_profile.rb +3 -0
  100. data/lib/new_relic/agent/tracer.rb +5 -1
  101. data/lib/new_relic/agent/transaction/abstract_segment.rb +3 -0
  102. data/lib/new_relic/agent/transaction/datastore_segment.rb +3 -0
  103. data/lib/new_relic/agent/transaction/distributed_tracer.rb +4 -0
  104. data/lib/new_relic/agent/transaction/distributed_tracing.rb +1 -0
  105. data/lib/new_relic/agent/transaction/external_request_segment.rb +1 -0
  106. data/lib/new_relic/agent/transaction/message_broker_segment.rb +1 -0
  107. data/lib/new_relic/agent/transaction/segment.rb +1 -0
  108. data/lib/new_relic/agent/transaction/trace.rb +4 -0
  109. data/lib/new_relic/agent/transaction/trace_node.rb +1 -0
  110. data/lib/new_relic/agent/transaction/transaction_sample_buffer.rb +2 -0
  111. data/lib/new_relic/agent/transaction.rb +10 -0
  112. data/lib/new_relic/agent/transaction_event_aggregator.rb +1 -0
  113. data/lib/new_relic/agent/transaction_time_aggregator.rb +1 -0
  114. data/lib/new_relic/agent/utilization/pcf.rb +1 -0
  115. data/lib/new_relic/agent/utilization/vendor.rb +2 -0
  116. data/lib/new_relic/agent/utilization_data.rb +3 -0
  117. data/lib/new_relic/agent.rb +4 -2
  118. data/lib/new_relic/cli/commands/install.rb +1 -0
  119. data/lib/new_relic/coerce.rb +6 -0
  120. data/lib/new_relic/collection_helper.rb +1 -0
  121. data/lib/new_relic/constants.rb +2 -0
  122. data/lib/new_relic/control/frameworks/rails.rb +5 -0
  123. data/lib/new_relic/control/instrumentation.rb +6 -8
  124. data/lib/new_relic/dependency_detection.rb +2 -0
  125. data/lib/new_relic/helper.rb +1 -0
  126. data/lib/new_relic/language_support.rb +1 -0
  127. data/lib/new_relic/latest_changes.rb +1 -0
  128. data/lib/new_relic/local_environment.rb +7 -1
  129. data/lib/new_relic/metric_spec.rb +2 -0
  130. data/lib/new_relic/rack/agent_middleware.rb +2 -0
  131. data/lib/new_relic/rack/browser_monitoring.rb +1 -0
  132. data/lib/new_relic/traced_thread.rb +1 -0
  133. data/lib/new_relic/version.rb +1 -1
  134. data/lib/tasks/helpers/format.rb +3 -0
  135. data/lib/tasks/helpers/prompt.rb +1 -1
  136. data/lib/tasks/instrumentation_generator/README.md +2 -2
  137. data/lib/tasks/instrumentation_generator/TODO.md +5 -5
  138. data/lib/tasks/instrumentation_generator/instrumentation.thor +27 -5
  139. data/lib/tasks/instrumentation_generator/templates/chain.tt +2 -1
  140. data/lib/tasks/instrumentation_generator/templates/chain_method.tt +3 -2
  141. data/lib/tasks/instrumentation_generator/templates/instrumentation.tt +2 -1
  142. data/lib/tasks/instrumentation_generator/templates/instrumentation_method.tt +1 -1
  143. data/lib/tasks/instrumentation_generator/templates/prepend.tt +1 -1
  144. data/lib/tasks/instrumentation_generator/templates/prepend_method.tt +1 -1
  145. data/lib/tasks/instrumentation_generator/templates/test.tt +1 -1
  146. data/newrelic.yml +13 -3
  147. data/newrelic_rpm.gemspec +7 -7
  148. data/test/agent_helper.rb +24 -0
  149. metadata +18 -79
  150. data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +0 -43
@@ -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
@@ -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)
@@ -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
- ruby_22_deprecation
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 ruby_22_deprecation
86
- return unless RUBY_VERSION <= '2.2.0'
87
- deprecation_msg = 'The Ruby Agent is dropping support for Ruby 2.2 ' \
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
 
@@ -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)
@@ -10,6 +10,7 @@ module NewRelic
10
10
  def can_fork?
11
11
  # this is expensive to check, so we should only check once
12
12
  return @@forkable if !@@forkable.nil?
13
+
13
14
  @@forkable = Process.respond_to?(:fork)
14
15
  end
15
16
 
@@ -56,6 +56,7 @@ EOS
56
56
  version_count += 1
57
57
  end
58
58
  break if version_count >= 2
59
+
59
60
  changes << line.sub(/^ \* /, "* ").chomp
60
61
  end
61
62
  changes
@@ -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
@@ -6,7 +6,7 @@
6
6
  module NewRelic
7
7
  module VERSION # :nodoc:
8
8
  MAJOR = 8
9
- MINOR = 11
9
+ MINOR = 13
10
10
  TINY = 0
11
11
 
12
12
  STRING = "#{MAJOR}.#{MINOR}.#{TINY}"
@@ -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
 
@@ -15,7 +15,7 @@ module Prompt
15
15
  puts
16
16
  print "Do you wish to continue? ('y' to continue, return to cancel) [n] "
17
17
  continue = STDIN.gets.chomp
18
- if continue.casecmp('y').zero?
18
+ if continue.casecmp('y') == 0
19
19
  system(command)
20
20
  else
21
21
  puts 'Cancelled'
@@ -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 has been created that generates the required files to create new instrumentation. This prototype accepts three arguments: name (name of the library), method (method to instrument), args (arguments for the method).
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
- The Ruby gem Thor, a toolkit for building powerful command-line interfaces used in Bundler, Vagrant, Rails and others powers this CLI.
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
- # - [ ] Make sure multiple arguments can be passed to the command line
29
+ # - [ ] Allow multiple method arguments to be passed to the command line
30
+
31
+ # - [ ] Add tests for the instrumentation_generator code
32
32
 
33
- # - [ ] Add tests
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
- create_configuration(name)
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 create_configuration(name)
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 config_block(library)
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.#{library}' => {
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 #{library} library at start up. May be one of [auto|prepend|chain|disabled].'
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 %>_with_tracing<%= "(#{@args})" unless @args.empty? %> do
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 :<%= @method.downcase %>_without_new_relic, :<%= @method.downcase %>
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 %>_with_tracing<%= "(#{@args})" unless @args.empty? %> do
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 %>_with_tracing<%= "(#{@args})" unless @args.empty? %>
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
@@ -1,3 +1,3 @@
1
- def <%= @method.downcase %>_with_tracing<%= "(#{@args})" unless @args.empty? %>
1
+ def <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %>
2
2
  # add instrumentation content here
3
3
  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 %>_with_tracing<%= "(#{@args})" unless @args.empty? %> { super }
10
+ <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %> { super }
11
11
  end
12
12
  end
13
13
  end
@@ -1,3 +1,3 @@
1
1
  def <%= @method.downcase %><%= "(#{@args})" unless @args.empty? %>
2
- <%= @method.downcase %>_with_tracing<%= "(#{@args})" unless @args.empty? %> { super }
2
+ <%= @method.downcase %>_with_new_relic<%= "(#{@args})" unless @args.empty? %> { super }
3
3
  end
@@ -11,5 +11,5 @@ class <%= @class_name %>InstrumentationTest < Minitest::Test
11
11
  NewRelic::Agent.instance.stats_engine.clear_stats
12
12
  end
13
13
 
14
- # Add tests Here
14
+ # Add tests here
15
15
  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: 1000
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 bot be. Known use-case for this option is where Sinatra is
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 asa semicolon-delimited ; string of
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.14.0'
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' if RUBY_VERSION > '2.5.0'
58
- s.add_development_dependency 'rubocop-minitest' if RUBY_VERSION > '2.5.0'
59
- s.add_development_dependency 'rubocop-performance' if RUBY_VERSION > '2.5.0'
60
- s.add_development_dependency 'rubocop-rake' if RUBY_VERSION > '2.5.0'
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