newrelic_rpm 6.15.0 → 8.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (156) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/CHANGELOG.md +260 -22
  4. data/CONTRIBUTING.md +13 -2
  5. data/README.md +4 -2
  6. data/lib/new_relic/agent/adaptive_sampler.rb +2 -2
  7. data/lib/new_relic/agent/agent.rb +8 -7
  8. data/lib/new_relic/agent/autostart.rb +1 -2
  9. data/lib/new_relic/agent/commands/thread_profiler_session.rb +7 -3
  10. data/lib/new_relic/agent/configuration/default_source.rb +456 -233
  11. data/lib/new_relic/agent/configuration/event_harvest_config.rb +28 -12
  12. data/lib/new_relic/agent/configuration/manager.rb +3 -4
  13. data/lib/new_relic/agent/configuration/server_source.rb +3 -2
  14. data/lib/new_relic/agent/configuration/yaml_source.rb +22 -1
  15. data/lib/new_relic/agent/connect/request_builder.rb +4 -2
  16. data/lib/new_relic/agent/custom_event_aggregator.rb +2 -1
  17. data/lib/new_relic/agent/database.rb +5 -2
  18. data/lib/new_relic/agent/datastores/mongo.rb +5 -10
  19. data/lib/new_relic/agent/datastores/redis.rb +0 -4
  20. data/lib/new_relic/agent/datastores.rb +7 -7
  21. data/lib/new_relic/agent/distributed_tracing/cross_app_payload.rb +5 -5
  22. data/lib/new_relic/agent/distributed_tracing/cross_app_tracing.rb +10 -6
  23. data/lib/new_relic/agent/distributed_tracing/distributed_trace_attributes.rb +0 -1
  24. data/lib/new_relic/agent/distributed_tracing/distributed_trace_payload.rb +1 -1
  25. data/lib/new_relic/agent/distributed_tracing/trace_context_payload.rb +1 -1
  26. data/lib/new_relic/agent/distributed_tracing.rb +0 -66
  27. data/lib/new_relic/agent/error_collector.rb +52 -37
  28. data/lib/new_relic/agent/error_filter.rb +167 -0
  29. data/lib/new_relic/agent/event_loop.rb +6 -6
  30. data/lib/new_relic/agent/external.rb +0 -32
  31. data/lib/new_relic/agent/http_clients/abstract.rb +2 -2
  32. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +1 -1
  33. data/lib/new_relic/agent/instrumentation/active_merchant.rb +3 -3
  34. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +0 -16
  35. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +1 -3
  36. data/lib/new_relic/agent/instrumentation/bunny/chain.rb +45 -0
  37. data/lib/new_relic/agent/instrumentation/bunny/instrumentation.rb +152 -0
  38. data/lib/new_relic/agent/instrumentation/bunny/prepend.rb +35 -0
  39. data/lib/new_relic/agent/instrumentation/bunny.rb +10 -152
  40. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +2 -1
  41. data/lib/new_relic/agent/instrumentation/curb/chain.rb +93 -0
  42. data/lib/new_relic/agent/instrumentation/curb/instrumentation.rb +222 -0
  43. data/lib/new_relic/agent/instrumentation/curb/prepend.rb +63 -0
  44. data/lib/new_relic/agent/instrumentation/curb.rb +9 -241
  45. data/lib/new_relic/agent/instrumentation/delayed_job/chain.rb +38 -0
  46. data/lib/new_relic/agent/instrumentation/delayed_job/instrumentation.rb +53 -0
  47. data/lib/new_relic/agent/instrumentation/delayed_job/prepend.rb +34 -0
  48. data/lib/new_relic/agent/instrumentation/delayed_job_instrumentation.rb +8 -50
  49. data/lib/new_relic/agent/instrumentation/excon.rb +4 -22
  50. data/lib/new_relic/agent/instrumentation/grape/chain.rb +25 -0
  51. data/lib/new_relic/agent/instrumentation/grape/instrumentation.rb +100 -0
  52. data/lib/new_relic/agent/instrumentation/grape/prepend.rb +17 -0
  53. data/lib/new_relic/agent/instrumentation/grape.rb +13 -113
  54. data/lib/new_relic/agent/instrumentation/httpclient/chain.rb +25 -0
  55. data/lib/new_relic/agent/instrumentation/httpclient/instrumentation.rb +38 -0
  56. data/lib/new_relic/agent/instrumentation/httpclient/prepend.rb +17 -0
  57. data/lib/new_relic/agent/instrumentation/httpclient.rb +8 -30
  58. data/lib/new_relic/agent/instrumentation/httprb/chain.rb +22 -0
  59. data/lib/new_relic/agent/instrumentation/httprb/instrumentation.rb +30 -0
  60. data/lib/new_relic/agent/instrumentation/httprb/prepend.rb +15 -0
  61. data/lib/new_relic/agent/instrumentation/httprb.rb +29 -0
  62. data/lib/new_relic/agent/instrumentation/memcache/chain.rb +16 -0
  63. data/lib/new_relic/agent/instrumentation/memcache/dalli.rb +38 -121
  64. data/lib/new_relic/agent/instrumentation/memcache/helper.rb +56 -0
  65. data/lib/new_relic/agent/instrumentation/memcache/instrumentation.rb +88 -0
  66. data/lib/new_relic/agent/instrumentation/memcache/prepend.rb +88 -0
  67. data/lib/new_relic/agent/instrumentation/memcache.rb +54 -69
  68. data/lib/new_relic/agent/instrumentation/middleware_proxy.rb +2 -0
  69. data/lib/new_relic/agent/instrumentation/mongo.rb +3 -134
  70. data/lib/new_relic/agent/instrumentation/net_http/chain.rb +25 -0
  71. data/lib/new_relic/agent/instrumentation/{net_prepend.rb → net_http/instrumentation.rb} +3 -3
  72. data/lib/new_relic/agent/instrumentation/net_http/prepend.rb +21 -0
  73. data/lib/new_relic/agent/instrumentation/net_http.rb +44 -0
  74. data/lib/new_relic/agent/instrumentation/padrino/chain.rb +34 -0
  75. data/lib/new_relic/agent/instrumentation/padrino/instrumentation.rb +27 -0
  76. data/lib/new_relic/agent/instrumentation/padrino/prepend.rb +20 -0
  77. data/lib/new_relic/agent/instrumentation/padrino.rb +18 -53
  78. data/lib/new_relic/agent/instrumentation/queue_time.rb +4 -4
  79. data/lib/new_relic/agent/instrumentation/rack/chain.rb +58 -0
  80. data/lib/new_relic/agent/instrumentation/rack/helpers.rb +32 -0
  81. data/lib/new_relic/agent/instrumentation/rack/instrumentation.rb +73 -0
  82. data/lib/new_relic/agent/instrumentation/rack/prepend.rb +37 -0
  83. data/lib/new_relic/agent/instrumentation/rack.rb +29 -139
  84. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +5 -5
  85. data/lib/new_relic/agent/instrumentation/rails/action_web_service.rb +1 -1
  86. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +5 -41
  87. data/lib/new_relic/agent/instrumentation/rake/chain.rb +25 -0
  88. data/lib/new_relic/agent/instrumentation/rake/instrumentation.rb +144 -0
  89. data/lib/new_relic/agent/instrumentation/rake/prepend.rb +14 -0
  90. data/lib/new_relic/agent/instrumentation/rake.rb +13 -154
  91. data/lib/new_relic/agent/instrumentation/redis/chain.rb +34 -0
  92. data/lib/new_relic/agent/instrumentation/redis/instrumentation.rb +65 -0
  93. data/lib/new_relic/agent/instrumentation/redis/prepend.rb +24 -0
  94. data/lib/new_relic/agent/instrumentation/redis.rb +12 -107
  95. data/lib/new_relic/agent/instrumentation/resque/chain.rb +22 -0
  96. data/lib/new_relic/agent/instrumentation/resque/helper.rb +19 -0
  97. data/lib/new_relic/agent/instrumentation/resque/instrumentation.rb +35 -0
  98. data/lib/new_relic/agent/instrumentation/resque/prepend.rb +16 -0
  99. data/lib/new_relic/agent/instrumentation/resque.rb +21 -32
  100. data/lib/new_relic/agent/instrumentation/sidekiq.rb +6 -1
  101. data/lib/new_relic/agent/instrumentation/sinatra/chain.rb +55 -0
  102. data/lib/new_relic/agent/instrumentation/sinatra/ignorer.rb +29 -34
  103. data/lib/new_relic/agent/instrumentation/sinatra/instrumentation.rb +124 -0
  104. data/lib/new_relic/agent/instrumentation/sinatra/prepend.rb +33 -0
  105. data/lib/new_relic/agent/instrumentation/sinatra.rb +20 -158
  106. data/lib/new_relic/agent/instrumentation/typhoeus/chain.rb +22 -0
  107. data/lib/new_relic/agent/instrumentation/typhoeus/instrumentation.rb +82 -0
  108. data/lib/new_relic/agent/instrumentation/typhoeus/prepend.rb +14 -0
  109. data/lib/new_relic/agent/instrumentation/typhoeus.rb +10 -89
  110. data/lib/new_relic/agent/javascript_instrumentor.rb +15 -10
  111. data/lib/new_relic/agent/messaging.rb +10 -24
  112. data/lib/new_relic/agent/method_tracer.rb +132 -138
  113. data/lib/new_relic/agent/monitors/cross_app_monitor.rb +6 -1
  114. data/lib/new_relic/agent/new_relic_service.rb +24 -22
  115. data/lib/new_relic/agent/pipe_channel_manager.rb +10 -6
  116. data/lib/new_relic/agent/pipe_service.rb +1 -1
  117. data/lib/new_relic/agent/samplers/cpu_sampler.rb +1 -1
  118. data/lib/new_relic/agent/span_event_aggregator.rb +2 -2
  119. data/lib/new_relic/agent/sql_sampler.rb +4 -4
  120. data/lib/new_relic/agent/stats_engine/stats_hash.rb +1 -1
  121. data/lib/new_relic/agent/stats_engine.rb +1 -1
  122. data/lib/new_relic/agent/supported_versions.rb +1 -1
  123. data/lib/new_relic/agent/threading/backtrace_service.rb +4 -5
  124. data/lib/new_relic/agent/threading/thread_profile.rb +1 -1
  125. data/lib/new_relic/agent/tracer.rb +15 -37
  126. data/lib/new_relic/agent/transaction/abstract_segment.rb +3 -3
  127. data/lib/new_relic/agent/transaction/message_broker_segment.rb +5 -11
  128. data/lib/new_relic/agent/transaction.rb +8 -32
  129. data/lib/new_relic/agent/transaction_time_aggregator.rb +5 -5
  130. data/lib/new_relic/agent/vm/snapshot.rb +1 -1
  131. data/lib/new_relic/agent/worker_loop.rb +5 -5
  132. data/lib/new_relic/agent.rb +10 -13
  133. data/lib/new_relic/cli/commands/deployments.rb +2 -2
  134. data/lib/new_relic/constants.rb +0 -4
  135. data/lib/new_relic/control/frameworks/rails.rb +11 -9
  136. data/lib/new_relic/control/instance_methods.rb +1 -0
  137. data/lib/new_relic/dependency_detection.rb +116 -10
  138. data/lib/new_relic/noticed_error.rb +5 -9
  139. data/lib/new_relic/supportability_helper.rb +1 -2
  140. data/lib/new_relic/version.rb +2 -2
  141. data/lib/newrelic_rpm.rb +10 -34
  142. data/lib/tasks/all.rb +1 -1
  143. data/lib/tasks/config.html.erb +14 -25
  144. data/lib/tasks/config.rake +8 -7
  145. data/newrelic.yml +593 -3
  146. data/newrelic_rpm.gemspec +1 -1
  147. data/test/agent_helper.rb +27 -2
  148. metadata +56 -14
  149. data/cert/cacert.pem +0 -1177
  150. data/lib/new_relic/agent/datastores/mongo/statement_formatter.rb +0 -53
  151. data/lib/new_relic/agent/instrumentation/excon/connection.rb +0 -49
  152. data/lib/new_relic/agent/instrumentation/http.rb +0 -49
  153. data/lib/new_relic/agent/instrumentation/merb/controller.rb +0 -44
  154. data/lib/new_relic/agent/instrumentation/merb/errors.rb +0 -33
  155. data/lib/new_relic/agent/instrumentation/net.rb +0 -70
  156. data/lib/new_relic/control/frameworks/merb.rb +0 -29
@@ -0,0 +1,167 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
+
5
+ module NewRelic
6
+ module Agent
7
+
8
+ # Handles loading of ignored and expected errors from the agent configuration, and
9
+ # determining at runtime whether an exception is ignored or expected.
10
+ class ErrorFilter
11
+
12
+ def initialize
13
+ reset
14
+ end
15
+
16
+ def reset
17
+ @ignore_classes, @expected_classes = [], []
18
+ @ignore_messages, @expected_messages = {}, {}
19
+ @ignore_status_codes, @expected_status_codes = [], []
20
+ end
21
+
22
+ def load_all
23
+ %i(
24
+ ignore_errors ignore_classes ignore_messages ignore_status_codes
25
+ expected_classes expected_messages expected_status_codes
26
+ ).each { |setting| load_from_config(setting) }
27
+ end
28
+
29
+ def load_from_config(setting, value = nil)
30
+ errors = nil
31
+ new_value = value || fetch_agent_config(setting.to_sym)
32
+ return if new_value.nil? || new_value.empty?
33
+
34
+ case setting.to_sym
35
+ when :ignore_errors, :ignore_classes
36
+ new_value = new_value.split(',').map!(&:strip) if new_value.is_a?(String)
37
+ errors = @ignore_classes = new_value
38
+ when :ignore_messages
39
+ errors = @ignore_messages = new_value || {}
40
+ when :ignore_status_codes
41
+ errors = @ignore_status_codes = parse_status_codes(new_value) || []
42
+ when :expected_classes
43
+ errors = @expected_classes = new_value || []
44
+ when :expected_messages
45
+ errors = @expected_messages = new_value || {}
46
+ when :expected_status_codes
47
+ errors = @expected_status_codes = parse_status_codes(new_value) || []
48
+ end
49
+ log_filter(setting, errors) if errors
50
+ end
51
+
52
+ def ignore?(ex, status_code = nil)
53
+ @ignore_classes.include?(ex.class.name) ||
54
+ (@ignore_messages.keys.include?(ex.class.name) &&
55
+ @ignore_messages[ex.class.name].any? { |m| ex.message.include?(m) }) ||
56
+ @ignore_status_codes.include?(status_code.to_i)
57
+ end
58
+
59
+ def expected?(ex, status_code = nil)
60
+ @expected_classes.include?(ex.class.name) ||
61
+ (@expected_messages.keys.include?(ex.class.name) &&
62
+ @expected_messages[ex.class.name].any? { |m| ex.message.include?(m) }) ||
63
+ @expected_status_codes.include?(status_code.to_i)
64
+ end
65
+
66
+ def fetch_agent_config(cfg)
67
+ NewRelic::Agent.config[:"error_collector.#{cfg}"]
68
+ end
69
+
70
+ # A generic method for adding ignore filters manually. This is kept for compatibility
71
+ # with the previous ErrorCollector#ignore method, and adds some flexibility for adding
72
+ # different ignore/expected error types by examining each argument.
73
+ def ignore(*args)
74
+ args.each do |errors|
75
+ case errors
76
+ when Array
77
+ errors.each { |e| ignore(e) }
78
+ when Integer
79
+ @ignore_status_codes << errors
80
+ when Hash
81
+ @ignore_messages.update(errors)
82
+ log_filter(:ignore_messages, errors)
83
+ when String
84
+ if errors.match(/^[\d\,\-]+$/)
85
+ @ignore_status_codes |= parse_status_codes(errors)
86
+ log_filter(:ignore_status_codes, errors)
87
+ else
88
+ new_ignore_classes = errors.split(',').map!(&:strip)
89
+ @ignore_classes |= new_ignore_classes
90
+ log_filter(:ignore_classes, new_ignore_classes)
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ # See #ignore above.
97
+ def expect(*args)
98
+ args.each do |errors|
99
+ case errors
100
+ when Array
101
+ errors.each { |e| expect(e) }
102
+ when Integer
103
+ @expected_status_codes << errors
104
+ when Hash
105
+ @expected_messages.update(errors)
106
+ log_filter(:expected_messages, errors)
107
+ when String
108
+ if errors.match(/^[\d\,\-]+$/)
109
+ @expected_status_codes |= parse_status_codes(errors)
110
+ log_filter(:expected_status_codes, errors)
111
+ else
112
+ new_expected_classes = errors.split(',').map!(&:strip)
113
+ @expected_classes |= new_expected_classes
114
+ log_filter(:expected_classes, new_expected_classes)
115
+ end
116
+ end
117
+ end
118
+ end
119
+
120
+ private
121
+
122
+ def log_filter(setting, errors)
123
+ case setting
124
+ when :ignore_errors, :ignore_classes
125
+ errors.each do |error|
126
+ ::NewRelic::Agent.logger.debug("Ignoring errors of type '#{error}'")
127
+ end
128
+ when :ignore_messages
129
+ errors.each do |error,messages|
130
+ ::NewRelic::Agent.logger.debug("Ignoring errors of type '#{error}' with messages: #{messages.join(',')}")
131
+ end
132
+ when :ignore_status_codes
133
+ ::NewRelic::Agent.logger.debug("Ignoring errors associated with status codes: #{errors}")
134
+ when :expected_classes
135
+ errors.each do |error|
136
+ ::NewRelic::Agent.logger.debug("Expecting errors of type '#{error}'")
137
+ end
138
+ when :expected_messages
139
+ errors.each do |error,messages|
140
+ ::NewRelic::Agent.logger.debug("Expecting errors of type '#{error}' with messages: #{messages.join(',')}")
141
+ end
142
+ when :expected_status_codes
143
+ ::NewRelic::Agent.logger.debug("Expecting errors associated with status codes: #{errors}")
144
+ end
145
+ end
146
+
147
+ def parse_status_codes(codes)
148
+ code_list = codes.is_a?(String) ? codes.split(',') : codes
149
+ result = []
150
+ code_list.each do |code|
151
+ result << code && next if code.is_a?(Integer)
152
+ m = code.match(/(\d{3})(-\d{3})?/)
153
+ if m.nil? || m[1].nil?
154
+ ::NewRelic::Agent.logger.warn("Invalid HTTP status code: '#{code}'; ignoring config")
155
+ next
156
+ end
157
+ if m[2]
158
+ result += (m[1]..m[2].tr('-', '')).to_a.map(&:to_i)
159
+ else
160
+ result << m[1].to_i
161
+ end
162
+ end
163
+ result.uniq
164
+ end
165
+ end
166
+ end
167
+ end
@@ -14,7 +14,7 @@ module NewRelic
14
14
  @interval = interval
15
15
  @event = event
16
16
  @repeat = repeat
17
- @started_at = Time.now
17
+ @started_at = Process.clock_gettime(Process::CLOCK_REALTIME)
18
18
  @last_fired_at = nil
19
19
  reschedule
20
20
  end
@@ -32,7 +32,7 @@ module NewRelic
32
32
  end
33
33
 
34
34
  def calculate_next_fire_time
35
- now = Time.now
35
+ now = Process.clock_gettime(Process::CLOCK_REALTIME)
36
36
  return now if @interval == 0
37
37
  fire_time = @last_fired_at || now
38
38
  while fire_time <= now
@@ -42,10 +42,10 @@ module NewRelic
42
42
  end
43
43
 
44
44
  def set_fired_time
45
- @last_fired_at = Time.now
45
+ @last_fired_at = Process.clock_gettime(Process::CLOCK_REALTIME)
46
46
  end
47
47
 
48
- def due?(now=Time.now)
48
+ def due?(now=Process.clock_gettime(Process::CLOCK_REALTIME))
49
49
  now >= @next_fire_time
50
50
  end
51
51
 
@@ -69,7 +69,7 @@ module NewRelic
69
69
  existing_timer = @timers[timer.event]
70
70
 
71
71
  if existing_timer
72
- elapsed_interval = Time.now - existing_timer.last_interval_start
72
+ elapsed_interval = Process.clock_gettime(Process::CLOCK_REALTIME) - existing_timer.last_interval_start
73
73
  timer.advance(elapsed_interval)
74
74
  end
75
75
 
@@ -80,7 +80,7 @@ module NewRelic
80
80
 
81
81
  def next_timeout
82
82
  return nil if @timers.empty?
83
- timeout = @timers.values.map(&:next_fire_time).min - Time.now
83
+ timeout = @timers.values.map(&:next_fire_time).min - Process.clock_gettime(Process::CLOCK_REALTIME)
84
84
  timeout < 0 ? 0 : timeout
85
85
  end
86
86
 
@@ -18,38 +18,6 @@ module NewRelic
18
18
  module External
19
19
  extend self
20
20
 
21
- # This method creates and starts an external request segment using the
22
- # given library, URI, and procedure. This is used to time external calls
23
- # made over HTTP.
24
- #
25
- # @param [String] library a string of the class name of the library used to
26
- # make the external call, for example, 'Net::HTTP'.
27
- #
28
- # @param [String, URI] uri indicates the URI to which the
29
- # external request is being made. The URI should begin with the protocol,
30
- # for example, 'https://github.com'.
31
- #
32
- # @param [String] procedure the HTTP method being used for the external
33
- # request as a string, for example, 'GET'.
34
- #
35
- # @api public
36
- def start_segment(library: nil, uri: nil, procedure: nil)
37
- Deprecator.deprecate 'External.start_segment',
38
- 'Tracer#start_external_request_segment'
39
-
40
- raise ArgumentError, 'Argument `library` is required' if library.nil?
41
- raise ArgumentError, 'Argument `uri` is required' if uri.nil?
42
- raise ArgumentError, 'Argument `procedure` is required' if procedure.nil?
43
-
44
- ::NewRelic::Agent.record_api_supportability_metric(:start_segment)
45
-
46
- ::NewRelic::Agent::Tracer.start_external_request_segment(
47
- library: library,
48
- uri: uri,
49
- procedure: procedure
50
- )
51
- end
52
-
53
21
  NON_HTTP_CAT_ID_HEADER = 'NewRelicID'.freeze
54
22
  NON_HTTP_CAT_TXN_HEADER = 'NewRelicTransaction'.freeze
55
23
  NON_HTTP_CAT_SYNTHETICS_HEADER = 'NewRelicSynthetics'.freeze
@@ -46,7 +46,7 @@ module NewRelic
46
46
  # NOTE: response_object should be non-nil!
47
47
  class AbstractResponse # :nodoc:
48
48
 
49
- def initialize wrapped_response
49
+ def initialize(wrapped_response)
50
50
  if wrapped_response.nil?
51
51
  raise ArgumentError, WHINY_NIL_ERROR % self.class
52
52
  end
@@ -65,7 +65,7 @@ module NewRelic
65
65
 
66
66
  private
67
67
 
68
- def get_status_code_using method_name
68
+ def get_status_code_using(method_name)
69
69
  return unless @wrapped_response.respond_to?(method_name)
70
70
  code = @wrapped_response.send(method_name).to_i
71
71
  code == 0 ? nil : code
@@ -91,7 +91,7 @@ module NewRelic
91
91
 
92
92
  def queue_start(request)
93
93
  if request && request.respond_to?(:env)
94
- QueueTime.parse_frontend_timestamp(request.env, Time.now)
94
+ QueueTime.parse_frontend_timestamp(request.env, Process.clock_gettime(Process::CLOCK_REALTIME))
95
95
  end
96
96
  end
97
97
  end
@@ -26,9 +26,9 @@ DependencyDetection.defer do
26
26
  gateway_name = self.name.split('::').last
27
27
  [:authorize, :purchase, :credit, :void, :capture, :recurring, :store, :unstore, :update].each do |operation|
28
28
  if implemented_methods.include?(operation)
29
- add_method_tracer operation, "ActiveMerchant/gateway/#{gateway_name}/#{operation}"
30
- add_method_tracer operation, "ActiveMerchant/gateway/#{gateway_name}", :push_scope => false
31
- add_method_tracer operation, "ActiveMerchant/operation/#{operation}", :push_scope => false
29
+ add_method_tracer operation, [-> (*) { "ActiveMerchant/gateway/#{gateway_name}/#{operation}" },
30
+ -> (*) { "ActiveMerchant/gateway/#{gateway_name}" },
31
+ -> (*) { "ActiveMerchant/operation/#{operation}" }]
32
32
  end
33
33
  end
34
34
  end
@@ -92,22 +92,6 @@ DependencyDetection.defer do
92
92
  !NewRelic::Agent::Instrumentation::ActiveRecordSubscriber.subscribed?
93
93
  end
94
94
 
95
-
96
- depends_on do
97
- # If the deprecated :disable_active_record_4 setting is true, and
98
- # the active record version is four, disable!
99
- NewRelic::Agent.config[:disable_active_record_4] == false \
100
- || ::ActiveRecord::VERSION::MAJOR.to_i != 4
101
- end
102
-
103
- depends_on do
104
- # If the deprecated :disable_active_record_5 setting is true, and
105
- # the active record version is five, disable!
106
- NewRelic::Agent.config[:disable_active_record_5] == false \
107
- || ::ActiveRecord::VERSION::MAJOR.to_i != 5
108
- end
109
-
110
-
111
95
  executes do
112
96
  ::NewRelic::Agent.logger.info 'Installing notifications based Active Record instrumentation'
113
97
  end
@@ -84,8 +84,6 @@ module NewRelic
84
84
  end
85
85
 
86
86
  def active_record_config(payload)
87
- return unless payload[:connection_id]
88
-
89
87
  # handle if the notification payload provides the AR connection
90
88
  # available in Rails 6+ & our ActiveRecordNotifications#log extension
91
89
  if payload[:connection]
@@ -93,8 +91,8 @@ module NewRelic
93
91
  return connection_config if connection_config
94
92
  end
95
93
 
94
+ return unless connection_id = payload[:connection_id]
96
95
  connection = nil
97
- connection_id = payload[:connection_id]
98
96
 
99
97
  ::ActiveRecord::Base.connection_handler.connection_pool_list.each do |handler|
100
98
  connection = handler.connections.detect do |conn|
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module Bunny
7
+ def self.instrument!
8
+ ::Bunny::Exchange.class_eval do
9
+ include NewRelic::Agent::Instrumentation::Bunny::Exchange
10
+
11
+ alias_method :publish_without_new_relic, :publish
12
+
13
+ def publish payload, opts = {}
14
+ publish_with_tracing(payload, opts) { publish_without_new_relic payload, opts }
15
+ end
16
+ end
17
+
18
+ ::Bunny::Queue.class_eval do
19
+ include NewRelic::Agent::Instrumentation::Bunny::Queue
20
+
21
+ alias_method :pop_without_new_relic, :pop
22
+
23
+ def pop(opts = {:manual_ack => false}, &block)
24
+ pop_with_tracing { pop_without_new_relic opts, &block }
25
+ end
26
+
27
+ alias_method :purge_without_new_relic, :purge
28
+
29
+ def purge *args
30
+ purge_with_tracing { purge_without_new_relic(*args) }
31
+ end
32
+ end
33
+
34
+ ::Bunny::Consumer.class_eval do
35
+ include NewRelic::Agent::Instrumentation::Bunny::Consumer
36
+
37
+ alias_method :call_without_new_relic, :call
38
+
39
+ def call *args
40
+ call_with_tracing(*args) { call_without_new_relic(*args) }
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,152 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
+ # frozen_string_literal: true
5
+
6
+ module NewRelic
7
+ module Agent
8
+ module Instrumentation
9
+ module Bunny
10
+ module_function
11
+
12
+ LIBRARY = 'RabbitMQ'
13
+ DEFAULT_NAME = 'Default'
14
+ DEFAULT_TYPE = :direct
15
+ SLASH = '/'
16
+
17
+ def exchange_name name
18
+ name.empty? ? DEFAULT_NAME : name
19
+ end
20
+
21
+ def exchange_type delivery_info, channel
22
+ if di_exchange = delivery_info[:exchange]
23
+ return DEFAULT_TYPE if di_exchange.empty?
24
+ return channel.exchanges[delivery_info[:exchange]].type if channel.exchanges[di_exchange]
25
+ end
26
+ end
27
+
28
+ module Exchange
29
+ include Bunny
30
+
31
+ def publish_with_tracing payload, opts = {}
32
+ begin
33
+ destination = exchange_name(name)
34
+
35
+ tracing_enabled =
36
+ NewRelic::Agent::CrossAppTracing.cross_app_enabled? ||
37
+ NewRelic::Agent.config[:'distributed_tracing.enabled']
38
+ opts[:headers] ||= {} if tracing_enabled
39
+
40
+ segment = NewRelic::Agent::Messaging.start_amqp_publish_segment(
41
+ library: LIBRARY,
42
+ destination_name: destination,
43
+ headers: opts[:headers],
44
+ routing_key: opts[:routing_key] || opts[:key],
45
+ reply_to: opts[:reply_to],
46
+ correlation_id: opts[:correlation_id],
47
+ exchange_type: type
48
+ )
49
+ rescue => e
50
+ NewRelic::Agent.logger.error "Error starting message broker segment in Bunny::Exchange#publish", e
51
+ yield
52
+ else
53
+ NewRelic::Agent::Tracer.capture_segment_error segment do
54
+ yield
55
+ end
56
+ ensure
57
+ segment.finish if segment
58
+ end
59
+ end
60
+ end
61
+
62
+ module Queue
63
+ include Bunny
64
+
65
+ def pop_with_tracing
66
+ bunny_error, delivery_info, message_properties, _payload = nil, nil, nil, nil
67
+ begin
68
+ t0 = Process.clock_gettime(Process::CLOCK_REALTIME)
69
+ msg = yield
70
+ delivery_info, message_properties, _payload = msg
71
+ rescue StandardError => error
72
+ bunny_error = error
73
+ end
74
+
75
+ begin
76
+ exch_name, exch_type = if delivery_info
77
+ [ exchange_name(delivery_info.exchange),
78
+ exchange_type(delivery_info, channel) ]
79
+ else
80
+ [ exchange_name(NewRelic::EMPTY_STR),
81
+ exchange_type({}, channel) ]
82
+ end
83
+
84
+ segment = NewRelic::Agent::Messaging.start_amqp_consume_segment(
85
+ library: LIBRARY,
86
+ destination_name: exch_name,
87
+ delivery_info: (delivery_info || {}),
88
+ message_properties: (message_properties || {headers: {}}),
89
+ exchange_type: exch_type,
90
+ queue_name: name,
91
+ start_time: t0
92
+ )
93
+ rescue => e
94
+ NewRelic::Agent.logger.error "Error starting message broker segment in Bunny::Queue#pop", e
95
+ else
96
+ if bunny_error
97
+ segment.notice_error bunny_error
98
+ raise bunny_error
99
+ end
100
+ ensure
101
+ segment.finish if segment
102
+ end
103
+
104
+ msg
105
+ end
106
+
107
+ def purge_with_tracing
108
+ begin
109
+ type = server_named? ? :temporary_queue : :queue
110
+ segment = NewRelic::Agent::Tracer.start_message_broker_segment(
111
+ action: :purge,
112
+ library: LIBRARY,
113
+ destination_type: type,
114
+ destination_name: name
115
+ )
116
+ rescue => e
117
+ NewRelic::Agent.logger.error "Error starting message broker segment in Bunny::Queue#purge", e
118
+ yield
119
+ else
120
+ NewRelic::Agent::Tracer.capture_segment_error segment do
121
+ yield
122
+ end
123
+ ensure
124
+ segment.finish if segment
125
+ end
126
+ end
127
+ end
128
+
129
+ module Consumer
130
+ include Bunny
131
+
132
+ def call_with_tracing *args
133
+ delivery_info, message_properties, _ = args
134
+ queue_name = queue.respond_to?(:name) ? queue.name : queue
135
+
136
+ NewRelic::Agent::Messaging.wrap_amqp_consume_transaction(
137
+ library: LIBRARY,
138
+ destination_name: exchange_name(delivery_info.exchange),
139
+ delivery_info: delivery_info,
140
+ message_properties: message_properties,
141
+ exchange_type: exchange_type(delivery_info, channel),
142
+ queue_name: queue_name) do
143
+
144
+ yield
145
+ end
146
+ end
147
+
148
+ end
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,35 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
+
5
+ module NewRelic::Agent::Instrumentation
6
+ module Bunny::Prepend
7
+ module Exchange
8
+ include NewRelic::Agent::Instrumentation::Bunny::Exchange
9
+
10
+ def publish payload, opts = {}
11
+ publish_with_tracing(payload, opts) { super }
12
+ end
13
+ end
14
+
15
+ module Queue
16
+ include NewRelic::Agent::Instrumentation::Bunny::Queue
17
+
18
+ def pop(opts = {:manual_ack => false}, &block)
19
+ pop_with_tracing { super }
20
+ end
21
+
22
+ def purge *args
23
+ purge_with_tracing { super }
24
+ end
25
+ end
26
+
27
+ module Consumer
28
+ include NewRelic::Agent::Instrumentation::Bunny::Consumer
29
+
30
+ def call *args
31
+ call_with_tracing(*args) { super }
32
+ end
33
+ end
34
+ end
35
+ end