newrelic-infinite_tracing 8.9.0 → 8.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +0 -1
- data/Rakefile +5 -1
- data/lib/infinite_tracing/agent_integrations/agent.rb +6 -6
- data/lib/infinite_tracing/agent_integrations/datastore_segment.rb +1 -2
- data/lib/infinite_tracing/agent_integrations/external_request_segment.rb +1 -2
- data/lib/infinite_tracing/agent_integrations/segment.rb +1 -2
- data/lib/infinite_tracing/agent_integrations.rb +2 -3
- data/lib/infinite_tracing/channel.rb +23 -14
- data/lib/infinite_tracing/client.rb +38 -27
- data/lib/infinite_tracing/config.rb +31 -6
- data/lib/infinite_tracing/connection.rb +30 -15
- data/lib/infinite_tracing/constants.rb +0 -1
- data/lib/infinite_tracing/proto/infinite_tracing_pb.rb +0 -1
- data/lib/infinite_tracing/proto/infinite_tracing_services_pb.rb +0 -2
- data/lib/infinite_tracing/proto.rb +0 -1
- data/lib/infinite_tracing/record_status_handler.rb +28 -23
- data/lib/infinite_tracing/streaming_buffer.rb +31 -20
- data/lib/infinite_tracing/suspended_streaming_buffer.rb +4 -5
- data/lib/infinite_tracing/transformer.rb +3 -4
- data/lib/infinite_tracing/version.rb +0 -1
- data/lib/infinite_tracing/worker.rb +12 -9
- data/lib/newrelic/infinite_tracing.rb +36 -3
- data/lib/proto/infinite_tracing.proto +1 -2
- data/newrelic-infinite_tracing.gemspec +8 -8
- data/tasks/all.rb +1 -1
- data/tasks/helpers/license.rb +25 -0
- data/tasks/proto.rake +10 -30
- metadata +21 -8
- data/lib/infinite_tracing.rb +0 -40
- data/lib/new_relic/infinite_tracing.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ef58ccd55c212b9f5de2fb32b7574ecbdfdb8d82794fccf628de4c76ae17cb5f
|
4
|
+
data.tar.gz: '0868bd0fc973b1a0562701b966a29e62636ed9558fe8710f0148be6239bd5433'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f5570f978e5a18bb7e7f6f9c9a06676ed4d3edc2fb874fbcfde6a19a8778806023af125a850e053479b6a2245a2d6d7da3a5718ba4a14a9eaa1a804954a158e
|
7
|
+
data.tar.gz: 6aead156960e0785cda78807c50e74dbf802b02a5e96e4b0073ad6593347dedfc3a53934d4345682a2de7f41bf5840c37f8b1a3300ac0df76cc6cb1a762541e9
|
data/Gemfile
CHANGED
data/Rakefile
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
# This file is distributed under New Relic's license terms.
|
2
|
+
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
3
|
+
# frozen_string_literal: true
|
4
|
+
|
1
5
|
require 'rubygems'
|
2
6
|
require 'rake/testtask'
|
3
7
|
require "#{File.dirname(__FILE__)}/tasks/all.rb"
|
@@ -12,7 +16,7 @@ task :console do
|
|
12
16
|
end
|
13
17
|
|
14
18
|
Rake::TestTask.new do |t|
|
15
|
-
ROOT = File.join
|
19
|
+
ROOT = File.join(File.dirname(__FILE__))
|
16
20
|
$LOAD_PATH << ROOT
|
17
21
|
|
18
22
|
file_pattern = "#{ROOT}/**/*_test.rb"
|
@@ -1,10 +1,9 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
# This file is distributed under New Relic's license terms.
|
3
2
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
3
|
# frozen_string_literal: true
|
5
4
|
|
6
5
|
module NewRelic::Agent
|
7
|
-
NewRelic::Agent.logger.debug
|
6
|
+
NewRelic::Agent.logger.debug("Installing Infinite Tracer in Agent")
|
8
7
|
|
9
8
|
Agent.class_eval do
|
10
9
|
def new_infinite_tracer
|
@@ -12,7 +11,7 @@ module NewRelic::Agent
|
|
12
11
|
# entire start up process for the Agent.
|
13
12
|
InfiniteTracing::Client.new.tap do |client|
|
14
13
|
@infinite_tracer_thread = InfiniteTracing::Worker.new(:infinite_tracer) do
|
15
|
-
NewRelic::Agent.logger.debug
|
14
|
+
NewRelic::Agent.logger.debug("Opening Infinite Tracer Stream with gRPC server")
|
16
15
|
client.start_streaming
|
17
16
|
end
|
18
17
|
end
|
@@ -22,18 +21,19 @@ module NewRelic::Agent
|
|
22
21
|
# this clears the data, clears connection attempts, and
|
23
22
|
# waits a while to reconnect.
|
24
23
|
def handle_force_restart(error)
|
25
|
-
::NewRelic::Agent.logger.debug
|
24
|
+
::NewRelic::Agent.logger.debug(error.message)
|
26
25
|
drop_buffered_data
|
27
26
|
@service.force_restart if @service
|
28
27
|
@connect_state = :pending
|
29
28
|
close_infinite_tracer
|
30
|
-
sleep
|
29
|
+
sleep(30)
|
31
30
|
end
|
32
31
|
|
33
32
|
# Whenever we reconnect, close and restart
|
34
33
|
def close_infinite_tracer
|
35
|
-
NewRelic::Agent.logger.debug
|
34
|
+
NewRelic::Agent.logger.debug("Closing infinite tracer threads")
|
36
35
|
return unless @infinite_tracer_thread
|
36
|
+
|
37
37
|
@infinite_tracer_thread.join
|
38
38
|
@infinite_tracer_thread.stop
|
39
39
|
@infinite_tracer_thread = nil
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
# This file is distributed under New Relic's license terms.
|
3
2
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
3
|
# frozen_string_literal: true
|
@@ -12,7 +11,7 @@ module NewRelic
|
|
12
11
|
return if transaction.ignore?
|
13
12
|
|
14
13
|
tracer = ::NewRelic::Agent.agent.infinite_tracer
|
15
|
-
tracer <<
|
14
|
+
tracer << proc { SpanEventPrimitive.for_datastore_segment(self) }
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
# This file is distributed under New Relic's license terms.
|
3
2
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
3
|
# frozen_string_literal: true
|
@@ -12,7 +11,7 @@ module NewRelic
|
|
12
11
|
return if transaction.ignore?
|
13
12
|
|
14
13
|
tracer = ::NewRelic::Agent.agent.infinite_tracer
|
15
|
-
tracer <<
|
14
|
+
tracer << proc { SpanEventPrimitive.for_external_request_segment(self) }
|
16
15
|
end
|
17
16
|
end
|
18
17
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
# This file is distributed under New Relic's license terms.
|
3
2
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
3
|
# frozen_string_literal: true
|
@@ -16,7 +15,7 @@ module NewRelic
|
|
16
15
|
return if transaction.ignore?
|
17
16
|
|
18
17
|
tracer = ::NewRelic::Agent.agent.infinite_tracer
|
19
|
-
tracer <<
|
18
|
+
tracer << proc { SpanEventPrimitive.for_segment(self) }
|
20
19
|
end
|
21
20
|
end
|
22
21
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
# This file is distributed under New Relic's license terms.
|
3
2
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
3
|
# frozen_string_literal: true
|
@@ -6,7 +5,7 @@
|
|
6
5
|
module NewRelic::Agent
|
7
6
|
module InfiniteTracing
|
8
7
|
if Config.enabled? || Config.test_framework?
|
9
|
-
NewRelic::Agent.logger.debug
|
8
|
+
NewRelic::Agent.logger.debug("Integrating Infinite Tracer with Agent")
|
10
9
|
|
11
10
|
require_relative 'agent_integrations/agent'
|
12
11
|
require_relative 'agent_integrations/segment'
|
@@ -14,7 +13,7 @@ module NewRelic::Agent
|
|
14
13
|
require_relative 'agent_integrations/external_request_segment'
|
15
14
|
|
16
15
|
else
|
17
|
-
NewRelic::Agent.logger.debug
|
16
|
+
NewRelic::Agent.logger.debug("Skipped Integrating Infinite Tracer with Agent")
|
18
17
|
end
|
19
18
|
end
|
20
19
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
# This file is distributed under New Relic's license terms.
|
3
2
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
3
|
# frozen_string_literal: true
|
@@ -6,33 +5,43 @@
|
|
6
5
|
module NewRelic::Agent
|
7
6
|
module InfiniteTracing
|
8
7
|
class Channel
|
8
|
+
SETTINGS_BASE = {'grpc.enable_deadline_checking' => 0}.freeze
|
9
|
+
SETTINGS_COMPRESSION_DISABLED = SETTINGS_BASE.merge({'grpc.minimal_stack' => 1}).freeze
|
10
|
+
|
9
11
|
def stub
|
10
|
-
NewRelic::Agent.logger.debug
|
12
|
+
NewRelic::Agent.logger.debug("Infinite Tracer Opening Channel to #{host_and_port}")
|
11
13
|
|
12
|
-
Com::Newrelic::Trace::V1::IngestService::Stub.new \
|
14
|
+
Com::Newrelic::Trace::V1::IngestService::Stub.new( \
|
13
15
|
host_and_port,
|
14
16
|
credentials,
|
15
|
-
channel_override: channel
|
17
|
+
channel_override: channel,
|
18
|
+
channel_args: channel_args
|
19
|
+
)
|
16
20
|
end
|
17
21
|
|
18
|
-
def
|
19
|
-
|
22
|
+
def host_and_port
|
23
|
+
Config.trace_observer_host_and_port
|
20
24
|
end
|
21
25
|
|
22
26
|
def credentials
|
23
|
-
|
24
|
-
GRPC::Core::ChannelCredentials.new
|
27
|
+
@credentials ||= GRPC::Core::ChannelCredentials.new
|
25
28
|
end
|
26
29
|
|
27
|
-
def
|
28
|
-
|
30
|
+
def channel
|
31
|
+
GRPC::Core::Channel.new(host_and_port, settings, credentials)
|
29
32
|
end
|
30
33
|
|
31
34
|
def settings
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
35
|
+
return channel_args.merge(SETTINGS_COMPRESSION_DISABLED).freeze unless Config.compression_enabled?
|
36
|
+
|
37
|
+
channel_args.merge(SETTINGS_BASE).freeze
|
38
|
+
end
|
39
|
+
|
40
|
+
def channel_args
|
41
|
+
return NewRelic::EMPTY_HASH unless Config.compression_enabled?
|
42
|
+
|
43
|
+
GRPC::Core::CompressionOptions.new(default_algorithm: :gzip,
|
44
|
+
default_level: Config.compression_level).to_channel_arg_hash
|
36
45
|
end
|
37
46
|
end
|
38
47
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
# This file is distributed under New Relic's license terms.
|
3
2
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
3
|
# frozen_string_literal: true
|
@@ -22,15 +21,20 @@ module NewRelic::Agent
|
|
22
21
|
@lock = Mutex.new
|
23
22
|
end
|
24
23
|
|
25
|
-
def <<
|
24
|
+
def <<(segment)
|
26
25
|
buffer << segment
|
27
26
|
end
|
28
27
|
|
28
|
+
def batching_enabled?
|
29
|
+
NewRelic::Agent.config[:'infinite_tracing.batching']
|
30
|
+
end
|
31
|
+
|
29
32
|
# Transfers spans in streaming buffer from previous
|
30
33
|
# client (if any) and returns self (so we chain the call)
|
31
|
-
def transfer
|
34
|
+
def transfer(previous_client)
|
32
35
|
return self unless previous_client
|
33
|
-
|
36
|
+
|
37
|
+
previous_client.buffer.transfer(buffer)
|
34
38
|
self
|
35
39
|
end
|
36
40
|
|
@@ -38,7 +42,7 @@ module NewRelic::Agent
|
|
38
42
|
# client is currently suspended.
|
39
43
|
def new_streaming_buffer
|
40
44
|
buffer_class = suspended? ? SuspendedStreamingBuffer : StreamingBuffer
|
41
|
-
buffer_class.new
|
45
|
+
buffer_class.new(Config.span_events_queue_size)
|
42
46
|
end
|
43
47
|
|
44
48
|
def buffer
|
@@ -50,30 +54,30 @@ module NewRelic::Agent
|
|
50
54
|
end
|
51
55
|
|
52
56
|
# Turns camelcase base class name into upper snake case version of the name.
|
53
|
-
def formatted_class_name
|
57
|
+
def formatted_class_name(class_name)
|
54
58
|
class_name = class_name.split(":")[-1]
|
55
59
|
(class_name.gsub!(/(.)([A-Z])/, '\1_\2') || class_name).upcase
|
56
60
|
end
|
57
61
|
|
58
62
|
# Literal codes are all mapped to unique class names, so we can deduce the
|
59
63
|
# name of the error to report in the metric from the error's class name.
|
60
|
-
def grpc_error_metric_name
|
64
|
+
def grpc_error_metric_name(error)
|
61
65
|
GRPC_ERROR_NAME_METRIC % formatted_class_name(error.class.name)
|
62
66
|
end
|
63
67
|
|
64
68
|
# 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
|
69
|
+
def record_error_metrics_and_log(error)
|
70
|
+
NewRelic::Agent.record_metric(RESPONSE_ERROR_METRIC, 0.0)
|
71
|
+
if error.is_a?(GRPC::BadStatus)
|
72
|
+
NewRelic::Agent.record_metric(grpc_error_metric_name(error), 0.0)
|
69
73
|
else
|
70
|
-
NewRelic::Agent.record_metric
|
74
|
+
NewRelic::Agent.record_metric(GRPC_OTHER_ERROR_METRIC, 0.0)
|
71
75
|
end
|
72
|
-
NewRelic::Agent.logger.warn
|
76
|
+
NewRelic::Agent.logger.warn("gRPC response error received.", error)
|
73
77
|
end
|
74
78
|
|
75
|
-
def handle_error
|
76
|
-
record_error_metrics_and_log
|
79
|
+
def handle_error(error)
|
80
|
+
record_error_metrics_and_log(error)
|
77
81
|
|
78
82
|
case error
|
79
83
|
when GRPC::Unavailable then restart
|
@@ -81,7 +85,7 @@ module NewRelic::Agent
|
|
81
85
|
when GRPC::Unimplemented then suspend
|
82
86
|
else
|
83
87
|
# Set exponential backoff to false so we'll reconnect at periodic (15 second) intervals instead
|
84
|
-
start_streaming
|
88
|
+
start_streaming(false)
|
85
89
|
end
|
86
90
|
end
|
87
91
|
|
@@ -95,8 +99,8 @@ module NewRelic::Agent
|
|
95
99
|
# server and re-establish the gRPC bi-directional stream. Useful for the server
|
96
100
|
# to initiate a load-balancing scheme.
|
97
101
|
def handle_close
|
98
|
-
NewRelic::Agent.logger.debug
|
99
|
-
"Restarting the stream."
|
102
|
+
NewRelic::Agent.logger.debug("The gRPC Trace Observer closed the stream with OK response. " \
|
103
|
+
"Restarting the stream.")
|
100
104
|
start_streaming
|
101
105
|
end
|
102
106
|
|
@@ -105,11 +109,12 @@ module NewRelic::Agent
|
|
105
109
|
# The Suspended Streaming Buffer will be installed in this state.
|
106
110
|
def suspend
|
107
111
|
return if suspended?
|
112
|
+
|
108
113
|
@lock.synchronize do
|
109
114
|
@suspended = true
|
110
115
|
@buffer = new_streaming_buffer
|
111
|
-
NewRelic::Agent.logger.warn
|
112
|
-
"No more span events will be sent during this session."
|
116
|
+
NewRelic::Agent.logger.warn("The Trace Observer host signaled to suspend streaming span events. " \
|
117
|
+
"No more span events will be sent during this session.")
|
113
118
|
end
|
114
119
|
end
|
115
120
|
|
@@ -123,7 +128,7 @@ module NewRelic::Agent
|
|
123
128
|
@lock.synchronize do
|
124
129
|
old_buffer = @buffer
|
125
130
|
@buffer = new_streaming_buffer
|
126
|
-
old_buffer.transfer
|
131
|
+
old_buffer.transfer(@buffer)
|
127
132
|
end
|
128
133
|
end
|
129
134
|
|
@@ -135,24 +140,30 @@ module NewRelic::Agent
|
|
135
140
|
|
136
141
|
def stop
|
137
142
|
return unless @response_handler
|
143
|
+
|
138
144
|
@lock.synchronize do
|
139
145
|
@response_handler.stop
|
140
146
|
@response_handler = nil
|
141
147
|
end
|
142
148
|
end
|
143
149
|
|
144
|
-
def start_streaming
|
150
|
+
def start_streaming(exponential_backoff = true)
|
145
151
|
return if suspended?
|
152
|
+
|
146
153
|
Connection.instance.wait_for_agent_connect
|
147
|
-
@lock.synchronize {
|
154
|
+
@lock.synchronize { response_handler(exponential_backoff) }
|
155
|
+
end
|
156
|
+
|
157
|
+
def record_spans(exponential_backoff)
|
158
|
+
RecordStatusHandler.new(self, Connection.record_spans(self, buffer.enumerator, exponential_backoff))
|
148
159
|
end
|
149
160
|
|
150
|
-
def
|
151
|
-
RecordStatusHandler.new
|
161
|
+
def record_span_batches(exponential_backoff)
|
162
|
+
RecordStatusHandler.new(self, Connection.record_span_batches(self, buffer.batch_enumerator, exponential_backoff))
|
152
163
|
end
|
153
164
|
|
154
|
-
def
|
155
|
-
|
165
|
+
def response_handler(backoff)
|
166
|
+
@response_handler = batching_enabled? ? record_span_batches(backoff) : record_spans(backoff)
|
156
167
|
end
|
157
168
|
end
|
158
169
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
# This file is distributed under New Relic's license terms.
|
3
2
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
3
|
# frozen_string_literal: true
|
@@ -8,6 +7,9 @@ module NewRelic::Agent
|
|
8
7
|
module Config
|
9
8
|
extend self
|
10
9
|
|
10
|
+
COMPRESSION_LEVEL_DISABLED = :none
|
11
|
+
COMPRESSION_LEVEL_DEFAULT = :high
|
12
|
+
COMPRESSION_LEVEL_LIST = %i[none low medium high].freeze
|
11
13
|
TRACE_OBSERVER_NOT_CONFIGURED_ERROR = "Trace Observer host not configured!"
|
12
14
|
|
13
15
|
# We only want to load the infinite tracing gem's files when
|
@@ -48,18 +50,18 @@ module NewRelic::Agent
|
|
48
50
|
end
|
49
51
|
|
50
52
|
# removes the scheme and port from a host entry.
|
51
|
-
def without_scheme_or_port
|
53
|
+
def without_scheme_or_port(url)
|
52
54
|
url.gsub(%r{^https?://|:\d+$}, '')
|
53
55
|
end
|
54
56
|
|
55
57
|
def trace_observer_host
|
56
|
-
without_scheme_or_port
|
58
|
+
without_scheme_or_port(NewRelic::Agent.config[:'infinite_tracing.trace_observer.host'])
|
57
59
|
end
|
58
60
|
|
59
61
|
# If the port is declared on the host entry, it overrides the port entry because otherwise
|
60
62
|
# we'd need to figure out if user supplied the port or if the default source config set
|
61
63
|
# the port. To help with debugging configuration issues, we log whenever the port entry
|
62
|
-
# is
|
64
|
+
# is overridden by the presence of the port on the host entry.
|
63
65
|
def port_from_host_entry
|
64
66
|
port_str = NewRelic::Agent.config[:'infinite_tracing.trace_observer.host'].scan(%r{:(\d+)$}).flatten
|
65
67
|
if port = (port_str[0] and port_str[0].to_i)
|
@@ -75,7 +77,7 @@ module NewRelic::Agent
|
|
75
77
|
end
|
76
78
|
|
77
79
|
# The scheme is based on whether the Trace Observer is running locally or remotely.
|
78
|
-
# Remote unsecure (
|
80
|
+
# Remote unsecure (unencrypted) streaming is disallowed!
|
79
81
|
def trace_observer_scheme
|
80
82
|
local? ? NewRelic::HTTP : NewRelic::HTTPS
|
81
83
|
end
|
@@ -85,7 +87,7 @@ module NewRelic::Agent
|
|
85
87
|
if trace_observer_configured?
|
86
88
|
URI("#{trace_observer_scheme}://#{trace_observer_host_and_port}")
|
87
89
|
else
|
88
|
-
NewRelic::Agent.logger.error
|
90
|
+
NewRelic::Agent.logger.error(TRACE_OBSERVER_NOT_CONFIGURED_ERROR)
|
89
91
|
raise TRACE_OBSERVER_NOT_CONFIGURED_ERROR
|
90
92
|
end
|
91
93
|
end
|
@@ -110,6 +112,29 @@ module NewRelic::Agent
|
|
110
112
|
def trace_observer_configured?
|
111
113
|
trace_observer_host != NewRelic::EMPTY_STR
|
112
114
|
end
|
115
|
+
|
116
|
+
def compression_enabled?
|
117
|
+
compression_level != COMPRESSION_LEVEL_DISABLED
|
118
|
+
end
|
119
|
+
|
120
|
+
def compression_level
|
121
|
+
@compression_level ||= begin
|
122
|
+
level = if COMPRESSION_LEVEL_LIST.include?(configured_compression_level)
|
123
|
+
configured_compression_level
|
124
|
+
else
|
125
|
+
NewRelic::Agent.logger.error("Invalid compression level '#{configured_compression_level}' specified! " \
|
126
|
+
"Must be one of #{COMPRESSION_LEVEL_LIST.join('|')}. Using default level " \
|
127
|
+
"of '#{COMPRESSION_LEVEL_DEFAULT}'")
|
128
|
+
COMPRESSION_LEVEL_DEFAULT
|
129
|
+
end
|
130
|
+
NewRelic::Agent.logger.debug("Infinite Tracer compression level set to #{level}")
|
131
|
+
level
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def configured_compression_level
|
136
|
+
NewRelic::Agent.config[:'infinite_tracing.compression_level']
|
137
|
+
end
|
113
138
|
end
|
114
139
|
end
|
115
140
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
# This file is distributed under New Relic's license terms.
|
3
2
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
3
|
# frozen_string_literal: true
|
@@ -18,6 +17,12 @@
|
|
18
17
|
module NewRelic::Agent
|
19
18
|
module InfiniteTracing
|
20
19
|
class Connection
|
20
|
+
GZIP_METADATA = {'grpc-internal-encoding-request' => 'gzip',
|
21
|
+
'grpc-encoding' => 'gzip',
|
22
|
+
'grpc-accept-encoding' => ['gzip'],
|
23
|
+
'content-coding' => 'gzip',
|
24
|
+
'content-encoding' => 'gzip'}.freeze
|
25
|
+
|
21
26
|
# listens for server side configurations added to the agent. When a new config is
|
22
27
|
# added, we have a new agent run token and need to restart the client's RPC stream
|
23
28
|
# with the new metadata information.
|
@@ -25,9 +30,10 @@ module NewRelic::Agent
|
|
25
30
|
begin
|
26
31
|
Connection.instance.notify_agent_started
|
27
32
|
rescue => error
|
28
|
-
NewRelic::Agent.logger.error \
|
33
|
+
NewRelic::Agent.logger.error( \
|
29
34
|
"Error during notify :server_source_configuration_added event",
|
30
35
|
error
|
36
|
+
)
|
31
37
|
end
|
32
38
|
end
|
33
39
|
|
@@ -43,15 +49,15 @@ module NewRelic::Agent
|
|
43
49
|
# RPC calls will pass the calling client instance in. We track this
|
44
50
|
# so we're able to signal the client to restart when connectivity to the
|
45
51
|
# server is disrupted.
|
46
|
-
def record_spans
|
47
|
-
instance.record_spans
|
52
|
+
def record_spans(client, enumerator, exponential_backoff)
|
53
|
+
instance.record_spans(client, enumerator, exponential_backoff)
|
48
54
|
end
|
49
55
|
|
50
56
|
# RPC calls will pass the calling client instance in. We track this
|
51
57
|
# so we're able to signal the client to restart when connectivity to the
|
52
58
|
# server is disrupted.
|
53
|
-
def record_span_batches
|
54
|
-
instance.
|
59
|
+
def record_span_batches(client, enumerator, exponential_backoff)
|
60
|
+
instance.record_span_batches(client, enumerator, exponential_backoff)
|
55
61
|
end
|
56
62
|
|
57
63
|
def metadata
|
@@ -61,17 +67,17 @@ module NewRelic::Agent
|
|
61
67
|
|
62
68
|
# We attempt to connect and record spans with reconnection backoff in order to deal with
|
63
69
|
# unavailable errors coming from the stub being created and record_span call
|
64
|
-
def record_spans
|
70
|
+
def record_spans(client, enumerator, exponential_backoff)
|
65
71
|
@active_clients[client] = client
|
66
|
-
with_reconnection_backoff(exponential_backoff) { rpc.record_span
|
72
|
+
with_reconnection_backoff(exponential_backoff) { rpc.record_span(enumerator, metadata: metadata) }
|
67
73
|
end
|
68
74
|
|
69
75
|
# RPC calls will pass the calling client instance in. We track this
|
70
76
|
# so we're able to signal the client to restart when connectivity to the
|
71
77
|
# server is disrupted.
|
72
|
-
def record_span_batches
|
78
|
+
def record_span_batches(client, enumerator, exponential_backoff)
|
73
79
|
@active_clients[client] = client
|
74
|
-
with_reconnection_backoff(exponential_backoff) { rpc.record_span_batch
|
80
|
+
with_reconnection_backoff(exponential_backoff) { rpc.record_span_batch(enumerator, metadata: metadata) }
|
75
81
|
end
|
76
82
|
|
77
83
|
# Acquires the new channel stub for the RPC calls.
|
@@ -100,9 +106,18 @@ module NewRelic::Agent
|
|
100
106
|
"agent_run_token" => agent_id
|
101
107
|
}
|
102
108
|
@metadata.merge!(request_headers_map)
|
109
|
+
merge_gzip_metadata
|
103
110
|
end
|
104
111
|
end
|
105
112
|
|
113
|
+
# If (gzip based) compression is enabled, explicitly provide all
|
114
|
+
# relevant metadata
|
115
|
+
def merge_gzip_metadata
|
116
|
+
return @metadata unless Config.compression_enabled?
|
117
|
+
|
118
|
+
@metadata.merge!(GZIP_METADATA)
|
119
|
+
end
|
120
|
+
|
106
121
|
# Initializes rpc so we can get a Channel and Stub (connect to gRPC server)
|
107
122
|
# Initializes metadata so we use newest values in establishing channel
|
108
123
|
# Sets the agent_connected flag and signals the agent started so any
|
@@ -147,21 +162,21 @@ module NewRelic::Agent
|
|
147
162
|
end
|
148
163
|
|
149
164
|
# Continues retrying the connection at backoff intervals until a successful connection is made
|
150
|
-
def with_reconnection_backoff
|
165
|
+
def with_reconnection_backoff(exponential_backoff = true, &block)
|
151
166
|
@connection_attempts = 0
|
152
167
|
begin
|
153
168
|
yield
|
154
169
|
rescue => exception
|
155
170
|
retry_connection_period = retry_connection_period(exponential_backoff)
|
156
|
-
::NewRelic::Agent.logger.error
|
157
|
-
::NewRelic::Agent.logger.info
|
158
|
-
sleep
|
171
|
+
::NewRelic::Agent.logger.error("Error establishing connection with infinite tracing service:", exception)
|
172
|
+
::NewRelic::Agent.logger.info("Will re-attempt infinite tracing connection in #{retry_connection_period} seconds")
|
173
|
+
sleep(retry_connection_period)
|
159
174
|
note_connect_failure
|
160
175
|
retry
|
161
176
|
end
|
162
177
|
end
|
163
178
|
|
164
|
-
def retry_connection_period
|
179
|
+
def retry_connection_period(exponential_backoff = true)
|
165
180
|
if exponential_backoff
|
166
181
|
NewRelic::CONNECT_RETRY_PERIODS[@connection_attempts] || NewRelic::MAX_RETRY_PERIOD
|
167
182
|
else
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
# This file is distributed under New Relic's license terms.
|
3
2
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
4
3
|
# frozen_string_literal: true
|
@@ -6,7 +5,6 @@
|
|
6
5
|
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
7
6
|
# Source: infinite_tracing.proto for package 'com.newrelic.trace.v1'
|
8
7
|
# Original file comments:
|
9
|
-
# encoding: utf-8
|
10
8
|
# This file is distributed under New Relic's license terms.
|
11
9
|
# See https://github.com/newrelic/newrelic-ruby-agent/blob/main/LICENSE for complete details.
|
12
10
|
#
|