newrelic-infinite_tracing 8.7.0 → 8.10.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d72145b32a77f242716bca17abc09e77ad863495b706e83a11193c7d54982c83
4
- data.tar.gz: 10bac6d2ef2bafd679302637c8377b28f7675f6b6aae9852ec2b3ac5f6fe6711
3
+ metadata.gz: 82175bbdb36620845384d5a1d9ed84eafe35e4e0b822b92760dd96b30ab5064a
4
+ data.tar.gz: 8478c0cf1d539a3d618989d0dd436bcf8d5f3f81360c2b1bd005fc37ddefd057
5
5
  SHA512:
6
- metadata.gz: ea9037fd90628f92ba636fd3c63f5196dbfd259fd30dca766f19f2eb16e30b241e8d5c38b1e52ed81bf11f22e95181e22e9809c19b3ded06bade82fabc78a8e2
7
- data.tar.gz: 012b46335b457d7c025e21e8d36ba8b359521eefbfce003f04ea6fa38ed20d134c858ff9abdfd1e09e7bd2e7d487f98ca23fc7aa40f56e5f49c4c7e35ab0e909
6
+ metadata.gz: 8cd2e71a2508bac59ac35fd8eacc1a8176e44351299808a883b6bd0a6cadca7ffc4c2741005e90647f5d03b197dd40d08ecc97a0468fc1f85744adccc944bdeb
7
+ data.tar.gz: 9bf7c047221d6d6f3eeabe1ea4381906dbb0dc511dd22638875d6b7d923b80373fcfbaf2afc0516e77bc983773afc08b4616e2c0059ce8990c9671518580d6e7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # New Relic Infinite Tracing for Ruby Agent Release Notes #
2
2
 
3
+ ## v8.9.0
4
+
5
+ * **Bugfix: Infinite Tracing hung on connection restart**
6
+
7
+ Previously, when using infinite tracing, the agent would intermittently encounter a deadlock when attempting to restart the infinite tracing connection. This bug would prevent the agent from sending all data types, including non-infinite-tracing-related data. This change reworks how we restart infinite tracing to prevent potential deadlocks.
8
+
3
9
  ## v7.0.0
4
10
  * Bugfix: Fixes an intermittent bug where the agent was unable to start when infinite tracing was enabled.
5
11
 
data/Rakefile CHANGED
@@ -1,3 +1,8 @@
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
+
1
6
  require 'rubygems'
2
7
  require 'rake/testtask'
3
8
  require "#{File.dirname(__FILE__)}/tasks/all.rb"
@@ -12,7 +17,7 @@ task :console do
12
17
  end
13
18
 
14
19
  Rake::TestTask.new do |t|
15
- ROOT = File.join File.dirname(__FILE__)
20
+ ROOT = File.join(File.dirname(__FILE__))
16
21
  $LOAD_PATH << ROOT
17
22
 
18
23
  file_pattern = "#{ROOT}/**/*_test.rb"
@@ -4,7 +4,7 @@
4
4
  # frozen_string_literal: true
5
5
 
6
6
  module NewRelic::Agent
7
- NewRelic::Agent.logger.debug "Installing Infinite Tracer in Agent"
7
+ NewRelic::Agent.logger.debug("Installing Infinite Tracer in Agent")
8
8
 
9
9
  Agent.class_eval do
10
10
  def new_infinite_tracer
@@ -12,13 +12,27 @@ module NewRelic::Agent
12
12
  # entire start up process for the Agent.
13
13
  InfiniteTracing::Client.new.tap do |client|
14
14
  @infinite_tracer_thread = InfiniteTracing::Worker.new(:infinite_tracer) do
15
- NewRelic::Agent.logger.debug "Opening Infinite Tracer Stream with gRPC server"
15
+ NewRelic::Agent.logger.debug("Opening Infinite Tracer Stream with gRPC server")
16
16
  client.start_streaming
17
17
  end
18
18
  end
19
19
  end
20
20
 
21
+ # Handles the case where the server tells us to restart -
22
+ # this clears the data, clears connection attempts, and
23
+ # waits a while to reconnect.
24
+ def handle_force_restart(error)
25
+ ::NewRelic::Agent.logger.debug(error.message)
26
+ drop_buffered_data
27
+ @service.force_restart if @service
28
+ @connect_state = :pending
29
+ close_infinite_tracer
30
+ sleep(30)
31
+ end
32
+
33
+ # Whenever we reconnect, close and restart
21
34
  def close_infinite_tracer
35
+ NewRelic::Agent.logger.debug("Closing infinite tracer threads")
22
36
  return unless @infinite_tracer_thread
23
37
  @infinite_tracer_thread.join
24
38
  @infinite_tracer_thread.stop
@@ -12,7 +12,7 @@ module NewRelic
12
12
  return if transaction.ignore?
13
13
 
14
14
  tracer = ::NewRelic::Agent.agent.infinite_tracer
15
- tracer << Proc.new { SpanEventPrimitive.for_datastore_segment self }
15
+ tracer << Proc.new { SpanEventPrimitive.for_datastore_segment(self) }
16
16
  end
17
17
  end
18
18
  end
@@ -12,7 +12,7 @@ module NewRelic
12
12
  return if transaction.ignore?
13
13
 
14
14
  tracer = ::NewRelic::Agent.agent.infinite_tracer
15
- tracer << Proc.new { SpanEventPrimitive.for_external_request_segment self }
15
+ tracer << Proc.new { SpanEventPrimitive.for_external_request_segment(self) }
16
16
  end
17
17
  end
18
18
  end
@@ -16,7 +16,7 @@ module NewRelic
16
16
  return if transaction.ignore?
17
17
 
18
18
  tracer = ::NewRelic::Agent.agent.infinite_tracer
19
- tracer << Proc.new { SpanEventPrimitive.for_segment self }
19
+ tracer << Proc.new { SpanEventPrimitive.for_segment(self) }
20
20
  end
21
21
  end
22
22
  end
@@ -6,7 +6,7 @@
6
6
  module NewRelic::Agent
7
7
  module InfiniteTracing
8
8
  if Config.enabled? || Config.test_framework?
9
- NewRelic::Agent.logger.debug "Integrating Infinite Tracer with Agent"
9
+ NewRelic::Agent.logger.debug("Integrating Infinite Tracer with Agent")
10
10
 
11
11
  require_relative 'agent_integrations/agent'
12
12
  require_relative 'agent_integrations/segment'
@@ -14,7 +14,7 @@ module NewRelic::Agent
14
14
  require_relative 'agent_integrations/external_request_segment'
15
15
 
16
16
  else
17
- NewRelic::Agent.logger.debug "Skipped Integrating Infinite Tracer with Agent"
17
+ NewRelic::Agent.logger.debug("Skipped Integrating Infinite Tracer with Agent")
18
18
  end
19
19
  end
20
20
  end
@@ -7,12 +7,13 @@ module NewRelic::Agent
7
7
  module InfiniteTracing
8
8
  class Channel
9
9
  def stub
10
- NewRelic::Agent.logger.debug "Infinite Tracer Opening Channel to #{host_and_port}"
10
+ NewRelic::Agent.logger.debug("Infinite Tracer Opening Channel to #{host_and_port}")
11
11
 
12
- Com::Newrelic::Trace::V1::IngestService::Stub.new \
12
+ Com::Newrelic::Trace::V1::IngestService::Stub.new( \
13
13
  host_and_port,
14
14
  credentials,
15
15
  channel_override: channel
16
+ )
16
17
  end
17
18
 
18
19
  def channel
@@ -20,12 +21,8 @@ module NewRelic::Agent
20
21
  end
21
22
 
22
23
  def credentials
23
- if Config.local?
24
- :this_channel_is_insecure
25
- else
26
- # Uses system configured certificates by default
27
- GRPC::Core::ChannelCredentials.new
28
- end
24
+ # Uses system configured certificates by default
25
+ GRPC::Core::ChannelCredentials.new
29
26
  end
30
27
 
31
28
  def host_and_port
@@ -22,15 +22,15 @@ module NewRelic::Agent
22
22
  @lock = Mutex.new
23
23
  end
24
24
 
25
- def << segment
25
+ def <<(segment)
26
26
  buffer << segment
27
27
  end
28
28
 
29
29
  # Transfers spans in streaming buffer from previous
30
30
  # client (if any) and returns self (so we chain the call)
31
- def transfer previous_client
31
+ def transfer(previous_client)
32
32
  return self unless previous_client
33
- previous_client.buffer.transfer buffer
33
+ previous_client.buffer.transfer(buffer)
34
34
  self
35
35
  end
36
36
 
@@ -38,7 +38,7 @@ module NewRelic::Agent
38
38
  # client is currently suspended.
39
39
  def new_streaming_buffer
40
40
  buffer_class = suspended? ? SuspendedStreamingBuffer : StreamingBuffer
41
- buffer_class.new Config.span_events_queue_size
41
+ buffer_class.new(Config.span_events_queue_size)
42
42
  end
43
43
 
44
44
  def buffer
@@ -50,30 +50,30 @@ module NewRelic::Agent
50
50
  end
51
51
 
52
52
  # Turns camelcase base class name into upper snake case version of the name.
53
- def formatted_class_name class_name
53
+ def formatted_class_name(class_name)
54
54
  class_name = class_name.split(":")[-1]
55
- formatted_class_name = (class_name.gsub!(/(.)([A-Z])/, '\1_\2') || class_name).upcase
55
+ (class_name.gsub!(/(.)([A-Z])/, '\1_\2') || class_name).upcase
56
56
  end
57
57
 
58
58
  # Literal codes are all mapped to unique class names, so we can deduce the
59
59
  # name of the error to report in the metric from the error's class name.
60
- def grpc_error_metric_name error
60
+ def grpc_error_metric_name(error)
61
61
  GRPC_ERROR_NAME_METRIC % formatted_class_name(error.class.name)
62
62
  end
63
63
 
64
64
  # Reports AND logs general response metric along with a more specific error metric
65
- def record_error_metrics_and_log error
66
- NewRelic::Agent.record_metric RESPONSE_ERROR_METRIC, 0.0
67
- if error.is_a? GRPC::BadStatus
68
- NewRelic::Agent.record_metric grpc_error_metric_name(error), 0.0
65
+ def record_error_metrics_and_log(error)
66
+ NewRelic::Agent.record_metric(RESPONSE_ERROR_METRIC, 0.0)
67
+ if error.is_a?(GRPC::BadStatus)
68
+ NewRelic::Agent.record_metric(grpc_error_metric_name(error), 0.0)
69
69
  else
70
- NewRelic::Agent.record_metric GRPC_OTHER_ERROR_METRIC, 0.0
70
+ NewRelic::Agent.record_metric(GRPC_OTHER_ERROR_METRIC, 0.0)
71
71
  end
72
- NewRelic::Agent.logger.warn "gRPC response error received.", error
72
+ NewRelic::Agent.logger.warn("gRPC response error received.", error)
73
73
  end
74
74
 
75
- def handle_error error
76
- record_error_metrics_and_log error
75
+ def handle_error(error)
76
+ record_error_metrics_and_log(error)
77
77
 
78
78
  case error
79
79
  when GRPC::Unavailable then restart
@@ -81,7 +81,7 @@ module NewRelic::Agent
81
81
  when GRPC::Unimplemented then suspend
82
82
  else
83
83
  # Set exponential backoff to false so we'll reconnect at periodic (15 second) intervals instead
84
- start_streaming false
84
+ start_streaming(false)
85
85
  end
86
86
  end
87
87
 
@@ -95,8 +95,8 @@ module NewRelic::Agent
95
95
  # server and re-establish the gRPC bi-directional stream. Useful for the server
96
96
  # to initiate a load-balancing scheme.
97
97
  def handle_close
98
- NewRelic::Agent.logger.debug "The gRPC Trace Observer closed the stream with OK response. " \
99
- "Restarting the stream."
98
+ NewRelic::Agent.logger.debug("The gRPC Trace Observer closed the stream with OK response. " \
99
+ "Restarting the stream.")
100
100
  start_streaming
101
101
  end
102
102
 
@@ -108,8 +108,8 @@ module NewRelic::Agent
108
108
  @lock.synchronize do
109
109
  @suspended = true
110
110
  @buffer = new_streaming_buffer
111
- NewRelic::Agent.logger.warn "The Trace Observer host signaled to suspend streaming span events. " \
112
- "No more span events will be sent during this session."
111
+ NewRelic::Agent.logger.warn("The Trace Observer host signaled to suspend streaming span events. " \
112
+ "No more span events will be sent during this session.")
113
113
  end
114
114
  end
115
115
 
@@ -123,7 +123,7 @@ module NewRelic::Agent
123
123
  @lock.synchronize do
124
124
  old_buffer = @buffer
125
125
  @buffer = new_streaming_buffer
126
- old_buffer.transfer @buffer
126
+ old_buffer.transfer(@buffer)
127
127
  end
128
128
  end
129
129
 
@@ -141,18 +141,18 @@ module NewRelic::Agent
141
141
  end
142
142
  end
143
143
 
144
- def start_streaming exponential_backoff = true
144
+ def start_streaming(exponential_backoff = true)
145
145
  return if suspended?
146
146
  Connection.instance.wait_for_agent_connect
147
- @lock.synchronize { @response_handler = record_spans exponential_backoff }
147
+ @lock.synchronize { @response_handler = record_spans(exponential_backoff) }
148
148
  end
149
149
 
150
- def record_spans exponential_backoff
151
- RecordStatusHandler.new self, Connection.record_spans(self, buffer.enumerator, exponential_backoff)
150
+ def record_spans(exponential_backoff)
151
+ RecordStatusHandler.new(self, Connection.record_spans(self, buffer.enumerator, exponential_backoff))
152
152
  end
153
153
 
154
- def record_span_batches exponential_backoff
155
- RecordStatusHandler.new self, Connection.record_span_batches(self, buffer.batch_enumerator, exponential_backoff)
154
+ def record_span_batches(exponential_backoff)
155
+ RecordStatusHandler.new(self, Connection.record_span_batches(self, buffer.batch_enumerator, exponential_backoff))
156
156
  end
157
157
  end
158
158
  end
@@ -48,12 +48,12 @@ module NewRelic::Agent
48
48
  end
49
49
 
50
50
  # removes the scheme and port from a host entry.
51
- def without_scheme_or_port url
51
+ def without_scheme_or_port(url)
52
52
  url.gsub(%r{^https?://|:\d+$}, '')
53
53
  end
54
54
 
55
55
  def trace_observer_host
56
- without_scheme_or_port NewRelic::Agent.config[:'infinite_tracing.trace_observer.host']
56
+ without_scheme_or_port(NewRelic::Agent.config[:'infinite_tracing.trace_observer.host'])
57
57
  end
58
58
 
59
59
  # If the port is declared on the host entry, it overrides the port entry because otherwise
@@ -85,7 +85,7 @@ module NewRelic::Agent
85
85
  if trace_observer_configured?
86
86
  URI("#{trace_observer_scheme}://#{trace_observer_host_and_port}")
87
87
  else
88
- NewRelic::Agent.logger.error TRACE_OBSERVER_NOT_CONFIGURED_ERROR
88
+ NewRelic::Agent.logger.error(TRACE_OBSERVER_NOT_CONFIGURED_ERROR)
89
89
  raise TRACE_OBSERVER_NOT_CONFIGURED_ERROR
90
90
  end
91
91
  end
@@ -25,9 +25,10 @@ module NewRelic::Agent
25
25
  begin
26
26
  Connection.instance.notify_agent_started
27
27
  rescue => error
28
- NewRelic::Agent.logger.error \
28
+ NewRelic::Agent.logger.error( \
29
29
  "Error during notify :server_source_configuration_added event",
30
30
  error
31
+ )
31
32
  end
32
33
  end
33
34
 
@@ -43,15 +44,15 @@ module NewRelic::Agent
43
44
  # RPC calls will pass the calling client instance in. We track this
44
45
  # so we're able to signal the client to restart when connectivity to the
45
46
  # server is disrupted.
46
- def record_spans client, enumerator, exponential_backoff
47
- instance.record_spans client, enumerator, exponential_backoff
47
+ def record_spans(client, enumerator, exponential_backoff)
48
+ instance.record_spans(client, enumerator, exponential_backoff)
48
49
  end
49
50
 
50
51
  # RPC calls will pass the calling client instance in. We track this
51
52
  # so we're able to signal the client to restart when connectivity to the
52
53
  # server is disrupted.
53
- def record_span_batches client, enumerator, exponential_backoff
54
- instance.record_span_batch client, enumerator, exponential_backoff
54
+ def record_span_batches(client, enumerator, exponential_backoff)
55
+ instance.record_span_batch(client, enumerator, exponential_backoff)
55
56
  end
56
57
 
57
58
  def metadata
@@ -61,17 +62,17 @@ module NewRelic::Agent
61
62
 
62
63
  # We attempt to connect and record spans with reconnection backoff in order to deal with
63
64
  # unavailable errors coming from the stub being created and record_span call
64
- def record_spans client, enumerator, exponential_backoff
65
+ def record_spans(client, enumerator, exponential_backoff)
65
66
  @active_clients[client] = client
66
- with_reconnection_backoff(exponential_backoff) { rpc.record_span enumerator, metadata: metadata }
67
+ with_reconnection_backoff(exponential_backoff) { rpc.record_span(enumerator, metadata: metadata) }
67
68
  end
68
69
 
69
70
  # RPC calls will pass the calling client instance in. We track this
70
71
  # so we're able to signal the client to restart when connectivity to the
71
72
  # server is disrupted.
72
- def record_span_batches client, enumerator, exponential_backoff
73
+ def record_span_batches(client, enumerator, exponential_backoff)
73
74
  @active_clients[client] = client
74
- with_reconnection_backoff(exponential_backoff) { rpc.record_span_batch enumerator, metadata: metadata }
75
+ with_reconnection_backoff(exponential_backoff) { rpc.record_span_batch(enumerator, metadata: metadata) }
75
76
  end
76
77
 
77
78
  # Acquires the new channel stub for the RPC calls.
@@ -114,7 +115,6 @@ module NewRelic::Agent
114
115
  @agent_connected = true
115
116
  @agent_started.signal
116
117
  end
117
- @active_clients.each_value(&:restart)
118
118
  end
119
119
 
120
120
  private
@@ -148,21 +148,21 @@ module NewRelic::Agent
148
148
  end
149
149
 
150
150
  # Continues retrying the connection at backoff intervals until a successful connection is made
151
- def with_reconnection_backoff exponential_backoff = true, &block
151
+ def with_reconnection_backoff(exponential_backoff = true, &block)
152
152
  @connection_attempts = 0
153
153
  begin
154
154
  yield
155
155
  rescue => exception
156
156
  retry_connection_period = retry_connection_period(exponential_backoff)
157
- ::NewRelic::Agent.logger.error "Error establishing connection with infinite tracing service:", exception
158
- ::NewRelic::Agent.logger.info "Will re-attempt infinte tracing connection in #{retry_connection_period} seconds"
159
- sleep retry_connection_period
157
+ ::NewRelic::Agent.logger.error("Error establishing connection with infinite tracing service:", exception)
158
+ ::NewRelic::Agent.logger.info("Will re-attempt infinte tracing connection in #{retry_connection_period} seconds")
159
+ sleep(retry_connection_period)
160
160
  note_connect_failure
161
161
  retry
162
162
  end
163
163
  end
164
164
 
165
- def retry_connection_period exponential_backoff = true
165
+ def retry_connection_period(exponential_backoff = true)
166
166
  if exponential_backoff
167
167
  NewRelic::CONNECT_RETRY_PERIODS[@connection_attempts] || NewRelic::MAX_RETRY_PERIOD
168
168
  else
@@ -6,7 +6,7 @@
6
6
  module NewRelic::Agent
7
7
  module InfiniteTracing
8
8
  class RecordStatusHandler
9
- def initialize client, enumerator
9
+ def initialize(client, enumerator)
10
10
  @client = client
11
11
  @enumerator = enumerator
12
12
  @messages_seen = nil
@@ -19,29 +19,29 @@ module NewRelic::Agent
19
19
  end
20
20
 
21
21
  def start_handler
22
- Worker.new self.class.name do
22
+ Worker.new(self.class.name) do
23
23
  begin
24
24
  @enumerator.each do |response|
25
25
  break if response.nil? || response.is_a?(Exception)
26
26
  @lock.synchronize do
27
27
  @messages_seen = response
28
- NewRelic::Agent.logger.debug "gRPC Infinite Tracer Observer saw #{messages_seen} messages"
28
+ NewRelic::Agent.logger.debug("gRPC Infinite Tracer Observer saw #{messages_seen} messages")
29
29
  end
30
30
  end
31
- NewRelic::Agent.logger.debug "gRPC Infinite Tracer Observer closed the stream"
31
+ NewRelic::Agent.logger.debug("gRPC Infinite Tracer Observer closed the stream")
32
32
  @client.handle_close
33
33
  rescue => error
34
- @client.handle_error error
34
+ @client.handle_error(error)
35
35
  end
36
36
  end
37
37
  rescue => error
38
- NewRelic::Agent.logger.error "gRPC Worker Error", error
38
+ NewRelic::Agent.logger.error("gRPC Worker Error", error)
39
39
  end
40
40
 
41
41
  def stop
42
42
  return if @worker.nil?
43
43
  @lock.synchronize do
44
- NewRelic::Agent.logger.debug "gRPC Stopping Response Handler"
44
+ NewRelic::Agent.logger.debug("gRPC Stopping Response Handler")
45
45
  @worker.stop
46
46
  @worker = nil
47
47
  end
@@ -21,7 +21,7 @@ module NewRelic::Agent
21
21
 
22
22
  attr_reader :queue
23
23
 
24
- def initialize max_size = DEFAULT_QUEUE_SIZE
24
+ def initialize(max_size = DEFAULT_QUEUE_SIZE)
25
25
  @max_size = max_size
26
26
  @lock = Mutex.new
27
27
  @queue = Queue.new
@@ -30,9 +30,9 @@ module NewRelic::Agent
30
30
 
31
31
  # Dumps the contents of this streaming buffer onto
32
32
  # the given buffer and closes the queue
33
- def transfer new_buffer
33
+ def transfer(new_buffer)
34
34
  @lock.synchronize do
35
- until @queue.empty? do new_buffer.push @queue.pop end
35
+ until @queue.empty? do new_buffer.push(@queue.pop) end
36
36
  @queue.close
37
37
  end
38
38
  end
@@ -45,11 +45,11 @@ module NewRelic::Agent
45
45
  # When a restart signal is received, the queue is
46
46
  # locked with a mutex, blocking the push until
47
47
  # the queue has restarted.
48
- def << segment
48
+ def <<(segment)
49
49
  @lock.synchronize do
50
50
  clear_queue if @queue.size >= @max_size
51
- NewRelic::Agent.increment_metric SPANS_SEEN_METRIC
52
- @queue.push segment
51
+ NewRelic::Agent.increment_metric(SPANS_SEEN_METRIC)
52
+ @queue.push(segment)
53
53
  end
54
54
  end
55
55
 
@@ -57,19 +57,19 @@ module NewRelic::Agent
57
57
  # supportability metric for the event.
58
58
  def clear_queue
59
59
  @queue.clear
60
- NewRelic::Agent.increment_metric QUEUE_DUMPED_METRIC
60
+ NewRelic::Agent.increment_metric(QUEUE_DUMPED_METRIC)
61
61
  end
62
62
 
63
63
  # Waits for the queue to be fully consumed or for the
64
64
  # waiting consumers to release.
65
65
  def flush_queue
66
- @queue.num_waiting.times { @queue.push nil }
66
+ @queue.num_waiting.times { @queue.push(nil) }
67
67
  close_queue
68
68
 
69
69
  # Logs if we're throwing away spans because nothing's
70
70
  # waiting to take them off the queue.
71
71
  if @queue.num_waiting == 0 && !@queue.empty?
72
- NewRelic::Agent.logger.warn "Discarding #{@queue.size} segments on Streaming Buffer"
72
+ NewRelic::Agent.logger.warn("Discarding #{@queue.size} segments on Streaming Buffer")
73
73
  return
74
74
  end
75
75
 
@@ -94,8 +94,8 @@ module NewRelic::Agent
94
94
  return enum_for(:enumerator) unless block_given?
95
95
  loop do
96
96
  if segment = @queue.pop(false)
97
- NewRelic::Agent.increment_metric SPANS_SENT_METRIC
98
- yield transform(segment)
97
+ NewRelic::Agent.increment_metric(SPANS_SENT_METRIC)
98
+ yield(transform(segment))
99
99
 
100
100
  else
101
101
  raise ClosedQueueError
@@ -120,15 +120,15 @@ module NewRelic::Agent
120
120
  return enum_for(:enumerator) unless block_given?
121
121
  loop do
122
122
  if proc_or_segment = @queue.pop(false)
123
- NewRelic::Agent.increment_metric SPANS_SENT_METRIC
123
+ NewRelic::Agent.increment_metric(SPANS_SENT_METRIC)
124
124
  @batch << transform(proc_or_segment)
125
125
  if @batch.size >= BATCH_SIZE
126
- yield SpanBatch.new(spans: @batch)
126
+ yield(SpanBatch.new(spans: @batch))
127
127
  @batch.clear
128
128
  end
129
129
 
130
130
  else
131
- yield SpanBatch.new(spans: @batch) unless @batch.empty?
131
+ yield(SpanBatch.new(spans: @batch)) unless @batch.empty?
132
132
  raise ClosedQueueError
133
133
  end
134
134
  end
@@ -136,7 +136,7 @@ module NewRelic::Agent
136
136
 
137
137
  private
138
138
 
139
- def span_event proc_or_segment
139
+ def span_event(proc_or_segment)
140
140
  if proc_or_segment.is_a?(Proc)
141
141
  proc_or_segment.call
142
142
  else
@@ -144,8 +144,8 @@ module NewRelic::Agent
144
144
  end
145
145
  end
146
146
 
147
- def transform proc_or_segment
148
- Span.new Transformer.transform(span_event proc_or_segment)
147
+ def transform(proc_or_segment)
148
+ Span.new(Transformer.transform(span_event(proc_or_segment)))
149
149
  end
150
150
  end
151
151
  end
@@ -13,16 +13,16 @@ module NewRelic::Agent
13
13
  extend Forwardable
14
14
  def_delegators :@empty_buffer, :empty?, :push
15
15
 
16
- def initialize max_size = DEFAULT_QUEUE_SIZE
16
+ def initialize(max_size = DEFAULT_QUEUE_SIZE)
17
17
  @empty_buffer = NewRelic::EMPTY_ARRAY
18
18
  end
19
19
 
20
20
  # updates the seen metric and discards the segment
21
- def << segment
22
- NewRelic::Agent.increment_metric SPANS_SEEN_METRIC
21
+ def <<(segment)
22
+ NewRelic::Agent.increment_metric(SPANS_SEEN_METRIC)
23
23
  end
24
24
 
25
- def transfer new_buffer
25
+ def transfer(new_buffer)
26
26
  # NOOP
27
27
  end
28
28
 
@@ -8,7 +8,7 @@ module NewRelic::Agent
8
8
  module Transformer
9
9
  extend self
10
10
 
11
- def transform span_event
11
+ def transform(span_event)
12
12
  intrinsics, user_attributes, agent_attributes = span_event
13
13
  {
14
14
  "trace_id" => intrinsics[NewRelic::Agent::SpanEventPrimitive::TRACE_ID_KEY],
@@ -34,17 +34,16 @@ module NewRelic::Agent
34
34
  KLASS_TO_ARG[BigDecimal] = :double_value
35
35
  end
36
36
 
37
- def safe_param_name value
37
+ def safe_param_name(value)
38
38
  KLASS_TO_ARG[value.class] || raise("Unhandled class #{value.class.name}")
39
39
  end
40
40
 
41
- def hash_to_attributes values
41
+ def hash_to_attributes(values)
42
42
  values.map do |key, value|
43
43
  begin
44
44
  [key, AttributeValue.new(safe_param_name(value) => value)]
45
45
  rescue => e
46
- puts e.inspect
47
- puts [key, value].inspect
46
+ NewRelic::Agent.logger.debug("Infinite tracing transformer error: #{e.inspect}")
48
47
  nil
49
48
  end
50
49
  end.to_h
@@ -12,7 +12,7 @@ module NewRelic::Agent
12
12
  class Worker
13
13
  attr_reader :name, :error
14
14
 
15
- def initialize name, &job
15
+ def initialize(name, &job)
16
16
  @name = name
17
17
  @job = job
18
18
  @error = nil
@@ -33,16 +33,16 @@ module NewRelic::Agent
33
33
  !!@error
34
34
  end
35
35
 
36
- def join timeout = nil
36
+ def join(timeout = nil)
37
37
  return unless @worker_thread
38
- NewRelic::Agent.logger.debug "joining worker #{@name} thread..."
39
- @worker_thread.join timeout
38
+ NewRelic::Agent.logger.debug("joining worker #{@name} thread...")
39
+ @worker_thread.join(timeout)
40
40
  end
41
41
 
42
42
  def stop
43
43
  @lock.synchronize do
44
44
  return unless @worker_thread
45
- NewRelic::Agent.logger.debug "stopping worker #{@name} thread..."
45
+ NewRelic::Agent.logger.debug("stopping worker #{@name} thread...")
46
46
  @worker_thread.kill
47
47
  @worker_thread = nil
48
48
  end
@@ -51,7 +51,7 @@ module NewRelic::Agent
51
51
  private
52
52
 
53
53
  def start_thread
54
- NewRelic::Agent.logger.debug "starting worker #{@name} thread..."
54
+ NewRelic::Agent.logger.debug("starting worker #{@name} thread...")
55
55
  @worker_thread = Thread.new do
56
56
  catch(:exit) do
57
57
  begin
@@ -63,7 +63,7 @@ module NewRelic::Agent
63
63
  end
64
64
  end
65
65
  @worker_thread.abort_on_exception = true
66
- if @worker_thread.respond_to? :report_on_exception
66
+ if @worker_thread.respond_to?(:report_on_exception)
67
67
  @worker_thread.report_on_exception = NewRelic::Agent.config[:log_level] == "debug"
68
68
  end
69
69
  end
@@ -7,7 +7,7 @@ require 'uri'
7
7
 
8
8
  require 'newrelic_rpm'
9
9
 
10
- NewRelic::Agent.logger.debug "Detected New Relic Infinite Tracing Gem"
10
+ NewRelic::Agent.logger.debug("Detected New Relic Infinite Tracing Gem")
11
11
 
12
12
  require 'infinite_tracing/version'
13
13
  require 'infinite_tracing/config'
@@ -20,7 +20,7 @@ DependencyDetection.defer do
20
20
  end
21
21
 
22
22
  executes do
23
- NewRelic::Agent.logger.debug "Loading New Relic Infinite Tracing Library"
23
+ NewRelic::Agent.logger.debug("Loading New Relic Infinite Tracing Library")
24
24
 
25
25
  require 'infinite_tracing/proto'
26
26
 
@@ -7,7 +7,7 @@ require 'uri'
7
7
 
8
8
  require 'newrelic_rpm'
9
9
 
10
- NewRelic::Agent.logger.debug "Detected New Relic Infinite Tracing Gem"
10
+ NewRelic::Agent.logger.debug("Detected New Relic Infinite Tracing Gem")
11
11
 
12
12
  require 'new_relic/infinite_tracing/version'
13
13
  require 'new_relic/infinite_tracing/config'
@@ -20,7 +20,7 @@ DependencyDetection.defer do
20
20
  end
21
21
 
22
22
  executes do
23
- NewRelic::Agent.logger.debug "Loading New Relic Infinite Tracing Library"
23
+ NewRelic::Agent.logger.debug("Loading New Relic Infinite Tracing Library")
24
24
 
25
25
  require 'new_relic/infinite_tracing/proto'
26
26
 
@@ -12,13 +12,13 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
12
12
  require 'new_relic/version'
13
13
 
14
14
  Gem::Specification.new do |s|
15
- def self.copy_files filelist
16
- subfolder = File.expand_path File.dirname(__FILE__)
15
+ def self.copy_files(filelist)
16
+ subfolder = File.expand_path(File.dirname(__FILE__))
17
17
 
18
18
  filelist.each do |filename|
19
19
  source_full_filename = File.expand_path(filename)
20
20
  dest_full_filename = File.join(subfolder, File.basename(filename))
21
- FileUtils.cp source_full_filename, dest_full_filename
21
+ FileUtils.cp(source_full_filename, dest_full_filename)
22
22
  end
23
23
  end
24
24
 
@@ -27,12 +27,12 @@ Gem::Specification.new do |s|
27
27
  "../CONTRIBUTING.md"
28
28
  ]
29
29
 
30
- self.copy_files shared_files
30
+ self.copy_files(shared_files)
31
31
 
32
32
  s.name = "newrelic-infinite_tracing"
33
33
  s.version = NewRelic::VERSION::STRING
34
34
  s.required_ruby_version = '>= 2.5.0'
35
- s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
35
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to?(:required_rubygems_version=)
36
36
  s.authors = ["Tanna McClure", "Kayla Reopelle", "James Bunch", "Hannah Ramadan"]
37
37
  s.licenses = ['Apache-2.0']
38
38
  s.description = <<-EOS
@@ -70,7 +70,6 @@ Gem or plugin, hosted on https://github.com/newrelic/newrelic-ruby-agent/
70
70
 
71
71
  s.homepage = "https://github.com/newrelic/newrelic-ruby-agent/tree/main/infinite_tracing"
72
72
  s.require_paths = ["lib", "infinite_tracing"]
73
- s.rubygems_version = Gem::VERSION
74
73
  s.summary = "New Relic Infinite Tracing for the Ruby agent"
75
74
 
76
75
  s.add_dependency 'newrelic_rpm', NewRelic::VERSION::STRING
@@ -85,8 +84,8 @@ Gem or plugin, hosted on https://github.com/newrelic/newrelic-ruby-agent/
85
84
  s.add_development_dependency 'pry-stack_explorer', '~> 0.4.9'
86
85
  s.add_development_dependency 'guard', '~> 2.16.0'
87
86
  s.add_development_dependency 'guard-minitest', '~> 2.4.0'
88
- s.add_development_dependency 'hometown', '~> 0.2.5'
89
87
  s.add_development_dependency 'bundler'
88
+ s.add_development_dependency 'simplecov'
90
89
 
91
90
  s.add_development_dependency 'grpc-tools', "~> 1.14"
92
91
  end
data/tasks/all.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
+ # frozen_string_literal: true
4
5
 
5
6
  # This is required to load in task definitions
6
7
  Dir.glob(File.join(File.dirname(__FILE__), '*.rake')) do |file|
data/tasks/proto.rake CHANGED
@@ -1,12 +1,13 @@
1
1
  # encoding: utf-8
2
2
  # This file is distributed under New Relic's license terms.
3
3
  # See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
4
+ # frozen_string_literal: true
4
5
 
5
6
  namespace :proto do
6
7
  desc "Generate proto files"
7
8
 
8
9
  task :generate do
9
- def extract_license_terms file_contents
10
+ def extract_license_terms(file_contents)
10
11
  text = []
11
12
  text << file_contents.shift while !file_contents.empty? && file_contents[0] =~ /^#/
12
13
  text << ""
@@ -15,11 +16,11 @@ namespace :proto do
15
16
 
16
17
  # adds the NewRelic License notice to the top of the generated files
17
18
  # Removes require lines since these are replicated in the proto.rb file.
18
- def add_license_preamble_and_remove_requires output_path
19
+ def add_license_preamble_and_remove_requires(output_path)
19
20
  gemspec_path = File.expand_path(File.join(output_path, '..', '..', '..', '..', '..'))
20
- license_terms = extract_license_terms File.readlines(File.join(gemspec_path, "Gemfile"))
21
- Dir.glob(File.join output_path, "*.rb") do |filename|
22
- contents = File.readlines filename
21
+ license_terms = extract_license_terms(File.readlines(File.join(gemspec_path, "Gemfile")))
22
+ Dir.glob(File.join(output_path, "*.rb")) do |filename|
23
+ contents = File.readlines(filename)
23
24
  contents.reject! { |r| r =~ /^\s*require\s.*$/ }
24
25
  File.open(filename, 'w') do |output|
25
26
  output.puts license_terms
@@ -28,11 +29,11 @@ namespace :proto do
28
29
  end
29
30
  end
30
31
 
31
- gem_folder = File.expand_path File.join(File.dirname(__FILE__), "..")
32
- proto_filename = File.join gem_folder, "lib", "new_relic", "proto", "infinite_tracing.proto"
33
- output_path = File.join gem_folder, "lib", "new_relic", "infinite_tracing", "proto"
32
+ gem_folder = File.expand_path(File.join(File.dirname(__FILE__), ".."))
33
+ proto_filename = File.join(gem_folder, "lib", "new_relic", "proto", "infinite_tracing.proto")
34
+ output_path = File.join(gem_folder, "lib", "new_relic", "infinite_tracing", "proto")
34
35
 
35
- FileUtils.mkdir_p output_path
36
+ FileUtils.mkdir_p(output_path)
36
37
  cmd = [
37
38
  "grpc_tools_ruby_protoc",
38
39
  "-I#{gem_folder}/lib/new_relic/proto",
@@ -40,7 +41,7 @@ namespace :proto do
40
41
  "--grpc_out=#{output_path} #{proto_filename}"
41
42
  ].join(" ")
42
43
 
43
- if system cmd
44
+ if system(cmd)
44
45
  puts "Proto file generated!"
45
46
  add_license_preamble_and_remove_requires output_path
46
47
  else
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: newrelic-infinite_tracing
3
3
  version: !ruby/object:Gem::Version
4
- version: 8.7.0
4
+ version: 8.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tanna McClure
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2022-05-03 00:00:00.000000000 Z
14
+ date: 2022-08-17 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: newrelic_rpm
@@ -19,14 +19,14 @@ dependencies:
19
19
  requirements:
20
20
  - - '='
21
21
  - !ruby/object:Gem::Version
22
- version: 8.7.0
22
+ version: 8.10.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - '='
28
28
  - !ruby/object:Gem::Version
29
- version: 8.7.0
29
+ version: 8.10.0
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: grpc
32
32
  requirement: !ruby/object:Gem::Requirement
@@ -168,21 +168,21 @@ dependencies:
168
168
  - !ruby/object:Gem::Version
169
169
  version: 2.4.0
170
170
  - !ruby/object:Gem::Dependency
171
- name: hometown
171
+ name: bundler
172
172
  requirement: !ruby/object:Gem::Requirement
173
173
  requirements:
174
- - - "~>"
174
+ - - ">="
175
175
  - !ruby/object:Gem::Version
176
- version: 0.2.5
176
+ version: '0'
177
177
  type: :development
178
178
  prerelease: false
179
179
  version_requirements: !ruby/object:Gem::Requirement
180
180
  requirements:
181
- - - "~>"
181
+ - - ">="
182
182
  - !ruby/object:Gem::Version
183
- version: 0.2.5
183
+ version: '0'
184
184
  - !ruby/object:Gem::Dependency
185
- name: bundler
185
+ name: simplecov
186
186
  requirement: !ruby/object:Gem::Requirement
187
187
  requirements:
188
188
  - - ">="