newrelic_rpm 6.3.0.355 → 6.8.0.360

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +50 -10
  4. data/CHANGELOG.md +198 -0
  5. data/Guardfile +7 -1
  6. data/lib/new_relic/agent.rb +80 -0
  7. data/lib/new_relic/agent/agent.rb +87 -26
  8. data/lib/new_relic/agent/agent_logger.rb +4 -0
  9. data/lib/new_relic/agent/attribute_filter.rb +7 -7
  10. data/lib/new_relic/agent/attributes.rb +152 -0
  11. data/lib/new_relic/agent/autostart.rb +19 -14
  12. data/lib/new_relic/agent/commands/agent_command_router.rb +2 -21
  13. data/lib/new_relic/agent/configuration/default_source.rb +129 -39
  14. data/lib/new_relic/agent/configuration/environment_source.rb +4 -2
  15. data/lib/new_relic/agent/configuration/event_harvest_config.rb +45 -0
  16. data/lib/new_relic/agent/configuration/high_security_source.rb +1 -0
  17. data/lib/new_relic/agent/configuration/manager.rb +13 -9
  18. data/lib/new_relic/agent/configuration/server_source.rb +33 -9
  19. data/lib/new_relic/agent/configuration/yaml_source.rb +10 -5
  20. data/lib/new_relic/agent/connect/request_builder.rb +11 -13
  21. data/lib/new_relic/agent/connect/response_handler.rb +1 -1
  22. data/lib/new_relic/agent/cross_app_monitor.rb +1 -1
  23. data/lib/new_relic/agent/datastores/mongo/event_formatter.rb +2 -2
  24. data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +8 -8
  25. data/lib/new_relic/agent/distributed_trace_intrinsics.rb +90 -0
  26. data/lib/new_relic/agent/distributed_trace_metrics.rb +74 -0
  27. data/lib/new_relic/agent/distributed_trace_monitor.rb +2 -12
  28. data/lib/new_relic/agent/distributed_trace_payload.rb +9 -76
  29. data/lib/new_relic/agent/distributed_trace_transport_type.rb +43 -0
  30. data/lib/new_relic/agent/error_collector.rb +2 -2
  31. data/lib/new_relic/agent/error_event_aggregator.rb +2 -1
  32. data/lib/new_relic/agent/error_trace_aggregator.rb +1 -0
  33. data/lib/new_relic/agent/event_aggregator.rb +26 -32
  34. data/lib/new_relic/agent/guid_generator.rb +28 -0
  35. data/lib/new_relic/agent/inbound_request_monitor.rb +2 -2
  36. data/lib/new_relic/agent/instrumentation/action_cable_subscriber.rb +24 -42
  37. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +45 -69
  38. data/lib/new_relic/agent/instrumentation/action_view_subscriber.rb +70 -53
  39. data/lib/new_relic/agent/instrumentation/active_record_notifications.rb +25 -18
  40. data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +33 -47
  41. data/lib/new_relic/agent/instrumentation/active_storage_subscriber.rb +4 -4
  42. data/lib/new_relic/agent/instrumentation/grape.rb +2 -3
  43. data/lib/new_relic/agent/instrumentation/{evented_subscriber.rb → notifications_subscriber.rb} +7 -66
  44. data/lib/new_relic/agent/instrumentation/rails_notifications/action_cable.rb +2 -3
  45. data/lib/new_relic/agent/javascript_instrumentor.rb +1 -1
  46. data/lib/new_relic/agent/logging.rb +129 -0
  47. data/lib/new_relic/agent/new_relic_service.rb +7 -9
  48. data/lib/new_relic/agent/priority_sampled_buffer.rb +2 -0
  49. data/lib/new_relic/agent/span_event_aggregator.rb +2 -4
  50. data/lib/new_relic/agent/span_event_primitive.rb +29 -7
  51. data/lib/new_relic/agent/sql_sampler.rb +1 -1
  52. data/lib/new_relic/agent/threading/backtrace_service.rb +3 -3
  53. data/lib/new_relic/agent/threading/thread_profile.rb +9 -23
  54. data/lib/new_relic/agent/trace_context.rb +244 -0
  55. data/lib/new_relic/agent/trace_context_payload.rb +134 -0
  56. data/lib/new_relic/agent/trace_context_request_monitor.rb +42 -0
  57. data/lib/new_relic/agent/tracer.rb +32 -0
  58. data/lib/new_relic/agent/transaction.rb +26 -20
  59. data/lib/new_relic/agent/transaction/abstract_segment.rb +2 -2
  60. data/lib/new_relic/agent/transaction/distributed_tracing.rb +20 -101
  61. data/lib/new_relic/agent/transaction/external_request_segment.rb +18 -5
  62. data/lib/new_relic/agent/transaction/segment.rb +7 -1
  63. data/lib/new_relic/agent/transaction/trace.rb +3 -8
  64. data/lib/new_relic/agent/transaction/trace_builder.rb +0 -1
  65. data/lib/new_relic/agent/transaction/trace_context.rb +159 -0
  66. data/lib/new_relic/agent/transaction/trace_node.rb +8 -3
  67. data/lib/new_relic/agent/transaction_error_primitive.rb +4 -11
  68. data/lib/new_relic/agent/transaction_event_primitive.rb +3 -11
  69. data/lib/new_relic/agent/transaction_event_recorder.rb +3 -3
  70. data/lib/new_relic/agent/transaction_sampler.rb +1 -5
  71. data/lib/new_relic/cli/commands/deployments.rb +1 -1
  72. data/lib/new_relic/coerce.rb +29 -6
  73. data/lib/new_relic/control/instance_methods.rb +10 -1
  74. data/lib/new_relic/dependency_detection.rb +4 -4
  75. data/lib/new_relic/noticed_error.rb +8 -4
  76. data/lib/new_relic/rack/browser_monitoring.rb +10 -8
  77. data/lib/new_relic/version.rb +1 -1
  78. data/lib/tasks/config.rake +1 -2
  79. data/newrelic_rpm.gemspec +13 -4
  80. data/test/agent_helper.rb +95 -9
  81. data/true +0 -0
  82. metadata +58 -24
  83. data/lib/new_relic/agent/commands/xray_session.rb +0 -55
  84. data/lib/new_relic/agent/commands/xray_session_collection.rb +0 -161
  85. data/lib/new_relic/agent/configuration/event_data.rb +0 -39
  86. data/lib/new_relic/agent/transaction/attributes.rb +0 -154
  87. data/lib/new_relic/agent/transaction/xray_sample_buffer.rb +0 -64
  88. data/lib/tasks/versions.html.erb +0 -28
  89. data/lib/tasks/versions.postface.html +0 -8
  90. data/lib/tasks/versions.preface.html +0 -9
  91. data/lib/tasks/versions.rake +0 -65
  92. data/lib/tasks/versions.txt.erb +0 -14
@@ -1,87 +1,104 @@
1
1
  # encoding: utf-8
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
- require 'new_relic/agent/instrumentation/evented_subscriber'
4
+ require 'new_relic/agent/instrumentation/notifications_subscriber'
5
5
 
6
6
  # Listen for ActiveSupport::Notifications events for ActionView render
7
7
  # events. Write metric data and transaction trace nodes for each event.
8
8
  module NewRelic
9
9
  module Agent
10
10
  module Instrumentation
11
- class ActionViewSubscriber < EventedSubscriber
11
+ class ActionViewSubscriber < NotificationsSubscriber
12
12
 
13
13
  def start(name, id, payload) #THREAD_LOCAL_ACCESS
14
- event = RenderEvent.new(name, Time.now, nil, id, payload)
15
- push_event(event)
16
- if state.is_execution_traced? && event.recordable?
17
- event.segment = NewRelic::Agent::Tracer.start_segment name: event.metric_name
14
+ parent = segment_stack[id].last
15
+ metric_name = format_metric_name(name, payload, parent)
16
+
17
+ event = ActionViewEvent.new(metric_name, payload[:identifier])
18
+ if state.is_execution_traced? && recordable?(name, metric_name)
19
+ event.finishable = Tracer.start_segment(name: metric_name)
18
20
  end
21
+ push_segment id, event
19
22
  rescue => e
20
23
  log_notification_error(e, name, 'start')
21
24
  end
22
25
 
23
26
  def finish(name, id, payload) #THREAD_LOCAL_ACCESS
24
- event = pop_event(id)
25
- event.segment.finish if event.segment
27
+ event = pop_segment(id)
28
+ event.finish if event
26
29
  rescue => e
27
30
  log_notification_error(e, name, 'finish')
28
31
  end
29
32
 
30
- class RenderEvent < Event
31
- attr_accessor :segment
32
-
33
- RENDER_TEMPLATE_EVENT_NAME = 'render_template.action_view'.freeze
34
- RENDER_PARTIAL_EVENT_NAME = 'render_partial.action_view'.freeze
35
- RENDER_COLLECTION_EVENT_NAME = 'render_collection.action_view'.freeze
33
+ def format_metric_name(event_name, payload, parent)
34
+ return parent.name if parent \
35
+ && (payload[:virtual_path] \
36
+ || (parent.identifier =~ /template$/))
36
37
 
37
- # Nearly every "render_blah.action_view" event has a child
38
- # in the form of "!render_blah.action_view". The children
39
- # are the ones we want to record. There are a couple
40
- # special cases of events without children.
41
- def recordable?
42
- name[0] == '!' ||
43
- metric_name == 'View/text template/Rendering' ||
44
- metric_name == "View/#{::NewRelic::Agent::UNKNOWN_METRIC}/Partial"
38
+ if payload.key?(:virtual_path)
39
+ identifier = payload[:virtual_path]
40
+ else
41
+ identifier = payload[:identifier]
45
42
  end
46
43
 
47
- def metric_name
48
- if parent && (payload[:virtual_path] ||
49
- (parent.payload[:identifier] =~ /template$/))
50
- return parent.metric_name
51
- elsif payload.key?(:virtual_path)
52
- identifier = payload[:virtual_path]
53
- else
54
- identifier = payload[:identifier]
55
- end
44
+ "View/#{metric_path(event_name, identifier)}/#{metric_action(event_name)}"
45
+ end
56
46
 
57
- # memoize
58
- @metric_name ||= "View/#{metric_path(name, identifier)}/#{metric_action(name)}"
59
- @metric_name
60
- end
47
+ # Nearly every "render_blah.action_view" event has a child
48
+ # in the form of "!render_blah.action_view". The children
49
+ # are the ones we want to record. There are a couple
50
+ # special cases of events without children.
51
+ def recordable?(event_name, metric_name)
52
+ event_name[0] == '!' \
53
+ || metric_name == 'View/text template/Rendering' \
54
+ || metric_name == "View/#{::NewRelic::Agent::UNKNOWN_METRIC}/Partial"
55
+ end
56
+
57
+ RENDER_TEMPLATE_EVENT_NAME = 'render_template.action_view'.freeze
58
+ RENDER_PARTIAL_EVENT_NAME = 'render_partial.action_view'.freeze
59
+ RENDER_COLLECTION_EVENT_NAME = 'render_collection.action_view'.freeze
61
60
 
62
- def metric_path(name, identifier)
63
- # Rails 5 sets identifier to nil for empty collections,
64
- # so do not mistake rendering a collection for rendering a file.
65
- if identifier == nil && name != RENDER_COLLECTION_EVENT_NAME
66
- 'file'
67
- elsif identifier =~ /template$/
68
- identifier
69
- elsif identifier && (parts = identifier.split('/')).size > 1
70
- parts[-2..-1].join('/')
71
- else
72
- ::NewRelic::Agent::UNKNOWN_METRIC
73
- end
61
+ def metric_action(name)
62
+ case name
63
+ when /#{RENDER_TEMPLATE_EVENT_NAME}$/ then 'Rendering'
64
+ when RENDER_PARTIAL_EVENT_NAME then 'Partial'
65
+ when RENDER_COLLECTION_EVENT_NAME then 'Partial'
74
66
  end
67
+ end
75
68
 
76
- def metric_action(name)
77
- case name
78
- when /#{RENDER_TEMPLATE_EVENT_NAME}$/ then 'Rendering'
79
- when RENDER_PARTIAL_EVENT_NAME then 'Partial'
80
- when RENDER_COLLECTION_EVENT_NAME then 'Partial'
81
- end
69
+ def metric_path(name, identifier)
70
+ # Rails 5 sets identifier to nil for empty collections,
71
+ # so do not mistake rendering a collection for rendering a file.
72
+ if identifier.nil? && name != RENDER_COLLECTION_EVENT_NAME
73
+ 'file'
74
+ elsif identifier =~ /template$/
75
+ identifier
76
+ elsif identifier && (parts = identifier.split('/')).size > 1
77
+ parts[-2..-1].join('/')
78
+ else
79
+ ::NewRelic::Agent::UNKNOWN_METRIC
82
80
  end
83
81
  end
84
82
  end
83
+
84
+ # This class holds state information between calls to `start`
85
+ # and `finish` for ActiveSupport events that we do not want to track
86
+ # as a transaction or segment.
87
+ class ActionViewEvent
88
+ attr_reader :name, :identifier
89
+ attr_accessor :finishable
90
+
91
+ def initialize(name, identifier)
92
+ @name = name
93
+ @identifier = identifier
94
+ @finishable = nil
95
+ end
96
+
97
+ def finish
98
+ @finishable.finish if @finishable
99
+ end
100
+ end
85
101
  end
102
+
86
103
  end
87
104
  end
@@ -13,11 +13,13 @@ module NewRelic
13
13
  module Agent
14
14
  module Instrumentation
15
15
  module ActiveRecordNotifications
16
- module BaseExtensions41
16
+ SQL_ACTIVE_RECORD = 'sql.active_record'.freeze
17
+
18
+ module BaseExtensions4x
17
19
  # https://github.com/rails/rails/blob/4-1-stable/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb#L371
18
20
  def log(sql, name = "SQL", binds = [], statement_name = nil)
19
21
  @instrumenter.instrument(
20
- "sql.active_record",
22
+ SQL_ACTIVE_RECORD,
21
23
  :sql => sql,
22
24
  :name => name,
23
25
  :connection_id => object_id,
@@ -25,7 +27,12 @@ module NewRelic
25
27
  :statement_name => statement_name,
26
28
  :binds => binds) { yield }
27
29
  rescue => e
28
- raise translate_exception(e, sql)
30
+ # The translate_exception_class method got introduced in 4.1
31
+ if ::ActiveRecord::VERSION::MINOR == 0
32
+ raise translate_exception(e, sql)
33
+ else
34
+ raise translate_exception_class(e, sql)
35
+ end
29
36
  end
30
37
  end
31
38
 
@@ -33,7 +40,7 @@ module NewRelic
33
40
  # https://github.com/rails/rails/blob/5-0-stable/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb#L582
34
41
  def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil)
35
42
  @instrumenter.instrument(
36
- "sql.active_record",
43
+ SQL_ACTIVE_RECORD,
37
44
  sql: sql,
38
45
  name: name,
39
46
  binds: binds,
@@ -50,7 +57,7 @@ module NewRelic
50
57
  # https://github.com/rails/rails/blob/5-1-stable/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb#L603
51
58
  def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil) # :doc:
52
59
  @instrumenter.instrument(
53
- "sql.active_record",
60
+ SQL_ACTIVE_RECORD,
54
61
  sql: sql,
55
62
  name: name,
56
63
  binds: binds,
@@ -87,17 +94,17 @@ DependencyDetection.defer do
87
94
 
88
95
 
89
96
  depends_on do
90
- # If the deprecated :disable_active_record_4 setting is true, and
97
+ # If the deprecated :disable_active_record_4 setting is true, and
91
98
  # the active record version is four, disable!
92
99
  NewRelic::Agent.config[:disable_active_record_4] == false \
93
100
  || ::ActiveRecord::VERSION::MAJOR.to_i != 4
94
101
  end
95
102
 
96
103
  depends_on do
97
- # If the deprecated :disable_active_record_5 setting is true, and
104
+ # If the deprecated :disable_active_record_5 setting is true, and
98
105
  # the active record version is five, disable!
99
106
  NewRelic::Agent.config[:disable_active_record_5] == false \
100
- || ::ActiveRecord::VERSION::MAJOR.to_i != 5
107
+ || ::ActiveRecord::VERSION::MAJOR.to_i != 5
101
108
  end
102
109
 
103
110
 
@@ -116,7 +123,7 @@ DependencyDetection.defer do
116
123
  ::ActiveRecord::Base,
117
124
  ::ActiveRecord::Relation)
118
125
 
119
- # Default to .prepending, unless the ActiveRecord version is <=4
126
+ # Default to .prepending, unless the ActiveRecord version is <=4
120
127
  # **AND** the :prepend_active_record_instrumentation config is false
121
128
  if ::ActiveRecord::VERSION::MAJOR > 4 \
122
129
  || ::NewRelic::Agent.config[:prepend_active_record_instrumentation]
@@ -133,15 +140,15 @@ DependencyDetection.defer do
133
140
 
134
141
  executes do
135
142
  if NewRelic::Agent.config[:backport_fast_active_record_connection_lookup]
136
-
137
- activerecord_extension = if ::ActiveRecord::VERSION::MAJOR.to_i == 4
138
- ::NewRelic::Agent::Instrumentation::ActiveRecordNotifications::BaseExtensions41
139
- elsif ::ActiveRecord::VERSION::MAJOR.to_i == 5
140
- if ::ActiveRecord::VERSION::MINOR.to_i == 0
141
- ::NewRelic::Agent::Instrumentation::ActiveRecordNotifications::BaseExtensions50
142
- elsif ::ActiveRecord::VERSION::MINOR.to_i >= 1
143
- ::NewRelic::Agent::Instrumentation::ActiveRecordNotifications::BaseExtensions51
144
- end
143
+ major_version = ::ActiveRecord::VERSION::MAJOR.to_i
144
+ minor_version = ::ActiveRecord::VERSION::MINOR.to_i
145
+
146
+ activerecord_extension = if major_version == 4
147
+ ::NewRelic::Agent::Instrumentation::ActiveRecordNotifications::BaseExtensions4x
148
+ elsif major_version == 5 && minor_version == 0
149
+ ::NewRelic::Agent::Instrumentation::ActiveRecordNotifications::BaseExtensions50
150
+ elsif major_version == 5 && minor_version == 1
151
+ ::NewRelic::Agent::Instrumentation::ActiveRecordNotifications::BaseExtensions51
145
152
  end
146
153
 
147
154
  unless activerecord_extension.nil?
@@ -2,7 +2,7 @@
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
4
  require 'new_relic/agent/instrumentation/active_record_helper'
5
- require 'new_relic/agent/instrumentation/evented_subscriber'
5
+ require 'new_relic/agent/instrumentation/notifications_subscriber'
6
6
 
7
7
  # Listen for ActiveSupport::Notifications events for ActiveRecord query
8
8
  # events. Write metric data, transaction trace nodes and slow sql
@@ -10,7 +10,7 @@ require 'new_relic/agent/instrumentation/evented_subscriber'
10
10
  module NewRelic
11
11
  module Agent
12
12
  module Instrumentation
13
- class ActiveRecordSubscriber < EventedSubscriber
13
+ class ActiveRecordSubscriber < NotificationsSubscriber
14
14
  CACHED_QUERY_NAME = 'CACHE'.freeze
15
15
 
16
16
  def initialize
@@ -31,6 +31,7 @@ module NewRelic
31
31
  # we don't expect this to be called more than once, but we're being
32
32
  # defensive.
33
33
  return if defined?(cached?)
34
+
34
35
  if defined?(::ActiveRecord) && ::ActiveRecord::VERSION::STRING >= "5.1.0"
35
36
  def cached?(payload)
36
37
  payload.fetch(:cached, false)
@@ -45,9 +46,10 @@ module NewRelic
45
46
  def start(name, id, payload) #THREAD_LOCAL_ACCESS
46
47
  return if cached?(payload)
47
48
  return unless NewRelic::Agent.tl_is_execution_traced?
49
+
48
50
  config = active_record_config(payload)
49
- event = ActiveRecordEvent.new(name, Time.now, nil, id, payload, @explainer, config)
50
- push_event(event)
51
+ segment = start_segment(config, payload)
52
+ push_segment(id, segment)
51
53
  rescue => e
52
54
  log_notification_error(e, name, 'start')
53
55
  end
@@ -55,8 +57,9 @@ module NewRelic
55
57
  def finish(name, id, payload) #THREAD_LOCAL_ACCESS
56
58
  return if cached?(payload)
57
59
  return unless state.is_execution_traced?
58
- event = pop_event(id)
59
- event.finish
60
+
61
+ segment = pop_segment(id)
62
+ segment.finish if segment
60
63
  rescue => e
61
64
  log_notification_error(e, name, 'finish')
62
65
  end
@@ -99,50 +102,33 @@ module NewRelic
99
102
  connection.instance_variable_get(:@config) if connection
100
103
  end
101
104
 
102
- class ActiveRecordEvent < Event
103
- def initialize(name, start, ending, transaction_id, payload, explainer, config)
104
- super(name, start, ending, transaction_id, payload)
105
- @explainer = explainer
106
- @config = config
107
- @segment = start_segment
108
- end
109
-
110
- def start_segment
111
- product, operation, collection = ActiveRecordHelper.product_operation_collection_for(payload[:name],
112
- sql, @config && @config[:adapter])
113
-
114
- host = nil
115
- port_path_or_id = nil
116
- database = nil
117
-
118
- if ActiveRecordHelper::InstanceIdentification.supported_adapter?(@config)
119
- host = ActiveRecordHelper::InstanceIdentification.host(@config)
120
- port_path_or_id = ActiveRecordHelper::InstanceIdentification.port_path_or_id(@config)
121
- database = @config && @config[:database]
122
- end
123
-
124
- segment = Tracer.start_datastore_segment product: product,
125
- operation: operation,
126
- collection: collection,
127
- host: host,
128
- port_path_or_id: port_path_or_id,
129
- database_name: database
130
-
131
- segment._notice_sql sql, @config, @explainer, payload[:binds], payload[:name]
132
- segment
105
+ def start_segment(config, payload)
106
+ sql = Helper.correctly_encoded payload[:sql]
107
+ product, operation, collection = ActiveRecordHelper.product_operation_collection_for(
108
+ payload[:name],
109
+ sql,
110
+ config && config[:adapter]
111
+ )
112
+
113
+ host = nil
114
+ port_path_or_id = nil
115
+ database = nil
116
+
117
+ if ActiveRecordHelper::InstanceIdentification.supported_adapter?(config)
118
+ host = ActiveRecordHelper::InstanceIdentification.host(config)
119
+ port_path_or_id = ActiveRecordHelper::InstanceIdentification.port_path_or_id(config)
120
+ database = config && config[:database]
133
121
  end
134
122
 
135
- def finish
136
- @segment.finish if @segment
137
- end
123
+ segment = Tracer.start_datastore_segment(product: product,
124
+ operation: operation,
125
+ collection: collection,
126
+ host: host,
127
+ port_path_or_id: port_path_or_id,
128
+ database_name: database)
138
129
 
139
- def state
140
- @state ||= NewRelic::Agent::Tracer.state
141
- end
142
-
143
- def sql
144
- @sql ||= Helper.correctly_encoded payload[:sql]
145
- end
130
+ segment._notice_sql sql, config, @explainer, payload[:binds], payload[:name]
131
+ segment
146
132
  end
147
133
  end
148
134
  end
@@ -1,12 +1,12 @@
1
1
  # encoding: utf-8
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
- require 'new_relic/agent/instrumentation/evented_subscriber'
4
+ require 'new_relic/agent/instrumentation/notifications_subscriber'
5
5
 
6
6
  module NewRelic
7
7
  module Agent
8
8
  module Instrumentation
9
- class ActiveStorageSubscriber < EventedSubscriber
9
+ class ActiveStorageSubscriber < NotificationsSubscriber
10
10
  def start name, id, payload
11
11
  return unless state.is_execution_traced?
12
12
  start_segment name, id, payload
@@ -25,11 +25,11 @@ module NewRelic
25
25
  segment = Tracer.start_segment name: metric_name(name, payload)
26
26
  segment.params[:key] = payload[:key]
27
27
  segment.params[:exist] = payload[:exist] if payload.key? :exist
28
- event_stack[id].push segment
28
+ push_segment id, segment
29
29
  end
30
30
 
31
31
  def finish_segment id
32
- segment = event_stack[id].pop
32
+ segment = pop_segment id
33
33
  segment.finish if segment
34
34
  end
35
35
 
@@ -133,9 +133,8 @@ DependencyDetection.defer do
133
133
  endpoint = env[::NewRelic::Agent::Instrumentation::GrapeInstrumentation::API_ENDPOINT]
134
134
  version = env[::NewRelic::Agent::Instrumentation::GrapeInstrumentation::API_VERSION]
135
135
 
136
- # Since 1.2.0, how to obtain the class name is changed.
137
- class_name = self.class.respond_to?(:base) ? self.class.base.name : self.class.name
138
- ::NewRelic::Agent::Instrumentation::GrapeInstrumentation.handle_transaction(endpoint, class_name, version)
136
+ api_class = (self.class.respond_to?(:base) && self.class.base) || self.class
137
+ ::NewRelic::Agent::Instrumentation::GrapeInstrumentation.handle_transaction(endpoint, api_class.name, version)
139
138
  rescue => e
140
139
  ::NewRelic::Agent.logger.warn("Error in Grape instrumentation", e)
141
140
  end
@@ -5,7 +5,7 @@
5
5
  module NewRelic
6
6
  module Agent
7
7
  module Instrumentation
8
- class EventedSubscriber
8
+ class NotificationsSubscriber
9
9
  def initialize
10
10
  @queue_key = ['NewRelic', self.class.name, object_id].join('-')
11
11
  end
@@ -46,16 +46,6 @@ module NewRelic
46
46
  end
47
47
  end
48
48
 
49
- def start(name, id, payload)
50
- event = ActiveSupport::Notifications::Event.new(name, Time.now, nil, id, payload)
51
- push_event(event)
52
- return event
53
- end
54
-
55
- def finish(name, id, payload)
56
- pop_event(id)
57
- end
58
-
59
49
  def log_notification_error(error, name, event_type)
60
50
  # These are important enough failures that we want the backtraces
61
51
  # logged at error level, hence the explicit log_exception call.
@@ -63,30 +53,16 @@ module NewRelic
63
53
  NewRelic::Agent.logger.log_exception(:error, error)
64
54
  end
65
55
 
66
- def push_event(event)
67
- parent = event_stack[event.transaction_id].last
68
- if parent && event.respond_to?(:parent=)
69
- event.parent = parent
70
- parent << event
71
- end
72
- event_stack[event.transaction_id].push event
56
+ def push_segment(id, segment)
57
+ segment_stack[id].push segment
73
58
  end
74
59
 
75
- def pop_event(transaction_id)
76
- event = event_stack[transaction_id].pop
77
-
78
- if event.respond_to?(:finish!)
79
- # ActiveSupport version 6 and greater use a finish! method rather
80
- # that allowing us to set the end directly
81
- event.finish!
82
- else
83
- event.end = Time.now
84
- end
85
-
86
- return event
60
+ def pop_segment(id)
61
+ segment = segment_stack[id].pop
62
+ segment
87
63
  end
88
64
 
89
- def event_stack
65
+ def segment_stack
90
66
  Thread.current[@queue_key] ||= Hash.new {|h,id| h[id] = [] }
91
67
  end
92
68
 
@@ -95,41 +71,6 @@ module NewRelic
95
71
  end
96
72
  end
97
73
 
98
- # Taken from ActiveSupport::Notifications::Event, pasted here
99
- # with a couple minor additions so we don't have a hard
100
- # dependency on ActiveSupport::Notifications.
101
- #
102
- # Represents an instrumentation event, provides timing and metric
103
- # name information useful when recording metrics.
104
- class Event
105
- attr_reader :name, :time, :transaction_id, :payload, :children
106
- attr_accessor :end, :parent, :frame
107
-
108
- def initialize(name, start, ending, transaction_id, payload)
109
- @name = name
110
- @payload = payload.dup
111
- @time = start
112
- @transaction_id = transaction_id
113
- @end = ending
114
- @children = []
115
- end
116
-
117
- def metric_name
118
- raise NotImplementedError
119
- end
120
-
121
- def duration
122
- self.end - time
123
- end
124
-
125
- def <<(event)
126
- @children << event
127
- end
128
-
129
- def parent_of?(event)
130
- @children.include? event
131
- end
132
- end
133
74
  end
134
75
  end
135
76
  end