newrelic-infinite_tracing 8.9.0 → 8.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +6 -1
- data/lib/infinite_tracing/agent_integrations/agent.rb +5 -5
- data/lib/infinite_tracing/agent_integrations/datastore_segment.rb +1 -1
- data/lib/infinite_tracing/agent_integrations/external_request_segment.rb +1 -1
- data/lib/infinite_tracing/agent_integrations/segment.rb +1 -1
- data/lib/infinite_tracing/agent_integrations.rb +2 -2
- data/lib/infinite_tracing/channel.rb +3 -2
- data/lib/infinite_tracing/client.rb +26 -26
- data/lib/infinite_tracing/config.rb +3 -3
- data/lib/infinite_tracing/connection.rb +15 -14
- data/lib/infinite_tracing/record_status_handler.rb +7 -7
- data/lib/infinite_tracing/streaming_buffer.rb +17 -17
- data/lib/infinite_tracing/suspended_streaming_buffer.rb +4 -4
- data/lib/infinite_tracing/transformer.rb +3 -3
- data/lib/infinite_tracing/worker.rb +7 -7
- data/lib/infinite_tracing.rb +2 -2
- data/lib/new_relic/infinite_tracing.rb +2 -2
- data/newrelic-infinite_tracing.gemspec +5 -5
- data/tasks/all.rb +1 -0
- data/tasks/proto.rake +11 -10
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 82175bbdb36620845384d5a1d9ed84eafe35e4e0b822b92760dd96b30ab5064a
|
4
|
+
data.tar.gz: 8478c0cf1d539a3d618989d0dd436bcf8d5f3f81360c2b1bd005fc37ddefd057
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8cd2e71a2508bac59ac35fd8eacc1a8176e44351299808a883b6bd0a6cadca7ffc4c2741005e90647f5d03b197dd40d08ecc97a0468fc1f85744adccc944bdeb
|
7
|
+
data.tar.gz: 9bf7c047221d6d6f3eeabe1ea4381906dbb0dc511dd22638875d6b7d923b80373fcfbaf2afc0516e77bc983773afc08b4616e2c0059ce8990c9671518580d6e7
|
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
|
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
|
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,7 +12,7 @@ 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
|
15
|
+
NewRelic::Agent.logger.debug("Opening Infinite Tracer Stream with gRPC server")
|
16
16
|
client.start_streaming
|
17
17
|
end
|
18
18
|
end
|
@@ -22,17 +22,17 @@ module NewRelic::Agent
|
|
22
22
|
# this clears the data, clears connection attempts, and
|
23
23
|
# waits a while to reconnect.
|
24
24
|
def handle_force_restart(error)
|
25
|
-
::NewRelic::Agent.logger.debug
|
25
|
+
::NewRelic::Agent.logger.debug(error.message)
|
26
26
|
drop_buffered_data
|
27
27
|
@service.force_restart if @service
|
28
28
|
@connect_state = :pending
|
29
29
|
close_infinite_tracer
|
30
|
-
sleep
|
30
|
+
sleep(30)
|
31
31
|
end
|
32
32
|
|
33
33
|
# Whenever we reconnect, close and restart
|
34
34
|
def close_infinite_tracer
|
35
|
-
NewRelic::Agent.logger.debug
|
35
|
+
NewRelic::Agent.logger.debug("Closing infinite tracer threads")
|
36
36
|
return unless @infinite_tracer_thread
|
37
37
|
@infinite_tracer_thread.join
|
38
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
|
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
|
15
|
+
tracer << Proc.new { SpanEventPrimitive.for_external_request_segment(self) }
|
16
16
|
end
|
17
17
|
end
|
18
18
|
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
|
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
|
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
|
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
|
@@ -22,15 +22,15 @@ module NewRelic::Agent
|
|
22
22
|
@lock = Mutex.new
|
23
23
|
end
|
24
24
|
|
25
|
-
def <<
|
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
|
31
|
+
def transfer(previous_client)
|
32
32
|
return self unless previous_client
|
33
|
-
previous_client.buffer.transfer
|
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
|
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
|
53
|
+
def formatted_class_name(class_name)
|
54
54
|
class_name = class_name.split(":")[-1]
|
55
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
|
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
|
66
|
-
NewRelic::Agent.record_metric
|
67
|
-
if error.is_a?
|
68
|
-
NewRelic::Agent.record_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)
|
69
69
|
else
|
70
|
-
NewRelic::Agent.record_metric
|
70
|
+
NewRelic::Agent.record_metric(GRPC_OTHER_ERROR_METRIC, 0.0)
|
71
71
|
end
|
72
|
-
NewRelic::Agent.logger.warn
|
72
|
+
NewRelic::Agent.logger.warn("gRPC response error received.", error)
|
73
73
|
end
|
74
74
|
|
75
|
-
def handle_error
|
76
|
-
record_error_metrics_and_log
|
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
|
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
|
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
|
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
|
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
|
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
|
147
|
+
@lock.synchronize { @response_handler = record_spans(exponential_backoff) }
|
148
148
|
end
|
149
149
|
|
150
|
-
def record_spans
|
151
|
-
RecordStatusHandler.new
|
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
|
155
|
-
RecordStatusHandler.new
|
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
|
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
|
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
|
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
|
47
|
-
instance.record_spans
|
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
|
54
|
-
instance.record_span_batch
|
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
|
65
|
+
def record_spans(client, enumerator, exponential_backoff)
|
65
66
|
@active_clients[client] = client
|
66
|
-
with_reconnection_backoff(exponential_backoff) { rpc.record_span
|
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
|
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
|
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.
|
@@ -147,21 +148,21 @@ module NewRelic::Agent
|
|
147
148
|
end
|
148
149
|
|
149
150
|
# Continues retrying the connection at backoff intervals until a successful connection is made
|
150
|
-
def with_reconnection_backoff
|
151
|
+
def with_reconnection_backoff(exponential_backoff = true, &block)
|
151
152
|
@connection_attempts = 0
|
152
153
|
begin
|
153
154
|
yield
|
154
155
|
rescue => exception
|
155
156
|
retry_connection_period = retry_connection_period(exponential_backoff)
|
156
|
-
::NewRelic::Agent.logger.error
|
157
|
-
::NewRelic::Agent.logger.info
|
158
|
-
sleep
|
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)
|
159
160
|
note_connect_failure
|
160
161
|
retry
|
161
162
|
end
|
162
163
|
end
|
163
164
|
|
164
|
-
def retry_connection_period
|
165
|
+
def retry_connection_period(exponential_backoff = true)
|
165
166
|
if exponential_backoff
|
166
167
|
NewRelic::CONNECT_RETRY_PERIODS[@connection_attempts] || NewRelic::MAX_RETRY_PERIOD
|
167
168
|
else
|
@@ -6,7 +6,7 @@
|
|
6
6
|
module NewRelic::Agent
|
7
7
|
module InfiniteTracing
|
8
8
|
class RecordStatusHandler
|
9
|
-
def initialize
|
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
|
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
|
28
|
+
NewRelic::Agent.logger.debug("gRPC Infinite Tracer Observer saw #{messages_seen} messages")
|
29
29
|
end
|
30
30
|
end
|
31
|
-
NewRelic::Agent.logger.debug
|
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
|
34
|
+
@client.handle_error(error)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
rescue => error
|
38
|
-
NewRelic::Agent.logger.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
|
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
|
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
|
33
|
+
def transfer(new_buffer)
|
34
34
|
@lock.synchronize do
|
35
|
-
until @queue.empty? do new_buffer.push
|
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 <<
|
48
|
+
def <<(segment)
|
49
49
|
@lock.synchronize do
|
50
50
|
clear_queue if @queue.size >= @max_size
|
51
|
-
NewRelic::Agent.increment_metric
|
52
|
-
@queue.push
|
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
|
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
|
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
|
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
|
98
|
-
yield
|
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
|
123
|
+
NewRelic::Agent.increment_metric(SPANS_SENT_METRIC)
|
124
124
|
@batch << transform(proc_or_segment)
|
125
125
|
if @batch.size >= BATCH_SIZE
|
126
|
-
yield
|
126
|
+
yield(SpanBatch.new(spans: @batch))
|
127
127
|
@batch.clear
|
128
128
|
end
|
129
129
|
|
130
130
|
else
|
131
|
-
yield
|
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
|
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
|
148
|
-
Span.new
|
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
|
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 <<
|
22
|
-
NewRelic::Agent.increment_metric
|
21
|
+
def <<(segment)
|
22
|
+
NewRelic::Agent.increment_metric(SPANS_SEEN_METRIC)
|
23
23
|
end
|
24
24
|
|
25
|
-
def transfer
|
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
|
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,11 +34,11 @@ module NewRelic::Agent
|
|
34
34
|
KLASS_TO_ARG[BigDecimal] = :double_value
|
35
35
|
end
|
36
36
|
|
37
|
-
def safe_param_name
|
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
|
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)]
|
@@ -12,7 +12,7 @@ module NewRelic::Agent
|
|
12
12
|
class Worker
|
13
13
|
attr_reader :name, :error
|
14
14
|
|
15
|
-
def initialize
|
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
|
36
|
+
def join(timeout = nil)
|
37
37
|
return unless @worker_thread
|
38
|
-
NewRelic::Agent.logger.debug
|
39
|
-
@worker_thread.join
|
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
|
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
|
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?
|
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
|
data/lib/infinite_tracing.rb
CHANGED
@@ -7,7 +7,7 @@ require 'uri'
|
|
7
7
|
|
8
8
|
require 'newrelic_rpm'
|
9
9
|
|
10
|
-
NewRelic::Agent.logger.debug
|
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
|
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
|
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
|
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
|
16
|
-
subfolder = File.expand_path
|
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
|
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
|
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?
|
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
|
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
|
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
|
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
|
21
|
-
Dir.glob(File.join
|
22
|
-
contents = File.readlines
|
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
|
32
|
-
proto_filename = File.join
|
33
|
-
output_path = File.join
|
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
|
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
|
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.
|
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-
|
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.
|
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.
|
29
|
+
version: 8.10.0
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
31
|
name: grpc
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|