instana 2.6.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2ed5be149509491e2aca498aad54181889c7cfc2cf8e0e51a6efcc34536e8379
4
- data.tar.gz: 9d03560bb1a9524d95ab63f93073e08dcfccb41fe5f3dede35a857aa7e2b4ed9
3
+ metadata.gz: f74b1ab7c25266cacf29645d4c956432ded64f2eb127a0bf712d1d5e7a659ad3
4
+ data.tar.gz: 0d1747acb3f742d8e8a103a154f14a0470d908837d2c286dbbc5a096afe3e59b
5
5
  SHA512:
6
- metadata.gz: 449410b9cbacaa8e6e622cc2e0db673155f656095d6927fad27c8ed14b14f783821ecdd31579f4beeefd32c0fe5e7061644e2d709f67614f915b66f666518945
7
- data.tar.gz: 27e52307782096e8e8fc90ff67adfbc11a146f40f0a2fcf3b11d7ba695e9cd5b0201ffc4edcac8de34ec090c48867aa1cd9ac00c0d1e4ada978b9c7fe285d645
6
+ metadata.gz: 507b17514d60c8363a510c7867fbbc4b7fd7e21ebb13310e64f6fb73af21068b11de601974240ede3e489e5165bc38def5558b0218b10cc8b9c6f10b20849c23
7
+ data.tar.gz: bc50d01dfbd66fb31a6b2958d7185047869ccb03e2f70e246254f054cf56d9f093eff00ac3db3ccf8c785e0fd701d404f261e1d2a3447ecbf28c0b340995af17
@@ -11,7 +11,7 @@ module Instana
11
11
  TRACES_DATA_URL = "/com.instana.plugin.ruby/traces.%i".freeze
12
12
  TRACE_METRICS_URL = "/tracermetrics".freeze
13
13
 
14
- attr_reader :report_timer
14
+ attr_reader :metrics_timer, :traces_timer
15
15
 
16
16
  # @param [RequestClient] client used to make requests to the backend
17
17
  # @param [Concurrent::Atom] discovery object used to store discovery response in
@@ -19,22 +19,51 @@ module Instana
19
19
  @client = client
20
20
  @discovery = discovery
21
21
  @logger = logger
22
- @report_timer = timer_class.new(execution_interval: 1, run_now: true) { report_to_backend }
22
+ @timer_class = timer_class
23
23
  @nonce = Time.now
24
24
  @processor = processor
25
+
26
+ # Initialize timers with default 1 second interval
27
+ @metrics_timer = @timer_class.new(execution_interval: 1, run_now: true) { report_metrics_to_backend }
28
+ @traces_timer = @timer_class.new(execution_interval: 1, run_now: true) { report_traces_to_backend }
25
29
  end
26
30
 
27
31
  def update(time, _old_version, new_version)
28
32
  return unless time > @nonce
29
33
 
30
34
  @nonce = time
31
- new_version.nil? ? @report_timer.shutdown : @report_timer.execute
35
+
36
+ if new_version.nil?
37
+ @metrics_timer&.shutdown
38
+ @traces_timer&.shutdown
39
+ else
40
+ # Read poll_rate from discovery payload - it's nested under plugin.ruby.poll_rate
41
+ discovery = @discovery.value
42
+ poll_rate = discovery&.dig('plugin', 'ruby', 'poll_rate') || 1
43
+
44
+ # Only recreate metrics_timer if poll_rate is different from current interval
45
+ if @metrics_timer.nil? || @metrics_timer.execution_interval != poll_rate
46
+ @metrics_timer&.shutdown
47
+ @metrics_timer = @timer_class.new(execution_interval: poll_rate, run_now: true) { report_metrics_to_backend }
48
+ end
49
+ @metrics_timer.execute
50
+
51
+ # Traces timer always uses 1 second interval
52
+ @traces_timer&.shutdown
53
+ @traces_timer = @timer_class.new(execution_interval: 1, run_now: true) { report_traces_to_backend }
54
+ @traces_timer.execute
55
+ end
32
56
  end
33
57
 
34
58
  private
35
59
 
36
- def report_to_backend
60
+ def report_metrics_to_backend
37
61
  report_metrics if ::Instana.config[:metrics][:enabled]
62
+ rescue StandardError => e
63
+ @logger.error(%(#{e}\n#{e.backtrace.join("\n")}))
64
+ end
65
+
66
+ def report_traces_to_backend
38
67
  report_traces if ::Instana.config[:tracing][:enabled]
39
68
  report_trace_stats if ::Instana.config[:tracing][:enabled]
40
69
  rescue StandardError => e
@@ -38,7 +38,10 @@ module Instana
38
38
  timeout = Integer(ENV.fetch('INSTANA_TIMEOUT', 500))
39
39
  @host = host
40
40
  @port = port
41
- @client = Net::HTTP.start(host, port, use_ssl: use_ssl, read_timeout: timeout)
41
+ @use_ssl = use_ssl
42
+ @timeout = timeout
43
+ @client_mutex = Mutex.new
44
+ @client = nil
42
45
  end
43
46
 
44
47
  # Send a request to the backend. If data is a {Hash},
@@ -60,7 +63,10 @@ module Instana
60
63
  data
61
64
  end
62
65
  begin
63
- response = @client.send_request(method, path, body, headers)
66
+ response = @client_mutex.synchronize do
67
+ ensure_connection
68
+ @client.send_request(method, path, body, headers)
69
+ end
64
70
  Response.new(response)
65
71
  rescue Errno::ECONNREFUSED => e
66
72
  Instana.logger.debug("Connection refused to #{@host}:#{@port} - #{e.message}")
@@ -74,6 +80,11 @@ module Instana
74
80
  rescue SocketError => e
75
81
  Instana.logger.debug("Socket error connecting to #{@host}:#{@port} - #{e.message}")
76
82
  create_error_response('502', 'Socket Error', 'Socket error', e.message)
83
+ rescue IOError => e
84
+ Instana.logger.debug("IO error sending request to #{@host}:#{@port} - #{e.message}")
85
+ # Reset connection on IO errors and retry once
86
+ @client_mutex.synchronize { reset_connection }
87
+ create_error_response('500', 'IO Error', 'IOError', e.message)
77
88
  rescue StandardError => e
78
89
  Instana.logger.debug("Error sending request to #{@host}:#{@port} - #{e.class}: #{e.message}")
79
90
  create_error_response('500', 'Internal Error', e.class.to_s, e.message)
@@ -82,6 +93,22 @@ module Instana
82
93
 
83
94
  private
84
95
 
96
+ def ensure_connection
97
+ return if @client && !@client.instance_variable_get(:@socket).nil?
98
+
99
+ reset_connection
100
+ @client = Net::HTTP.start(@host, @port, use_ssl: @use_ssl, read_timeout: @timeout)
101
+ end
102
+
103
+ def reset_connection
104
+ begin
105
+ @client&.finish
106
+ rescue
107
+ nil
108
+ end
109
+ @client = nil
110
+ end
111
+
85
112
  def encode_body(data)
86
113
  # :nocov:
87
114
  INSTANA_USE_OJ ? Oj.dump(data, mode: :strict) : JSON.dump(data)
@@ -26,7 +26,7 @@ module Instana
26
26
  response = @handler.call(context)
27
27
 
28
28
  span_tags[:queue] = response.queue_url if response.respond_to?(:queue_url)
29
- span.set_tags(sqs: span_tags)
29
+ span.add_attributes(sqs: span_tags)
30
30
 
31
31
  response
32
32
  end
@@ -35,11 +35,11 @@ module Instana
35
35
  super(method, *others, **options)
36
36
  rescue => e
37
37
  kvs[:rpc][:error] = true
38
- current_span.set_tags(kvs)
38
+ current_span.add_attributes(kvs)
39
39
  current_span.record_exception(e)
40
40
  raise
41
41
  ensure
42
- current_span.finish
42
+ current_span&.finish
43
43
  end
44
44
  end
45
45
  end
@@ -79,11 +79,11 @@ module Instana
79
79
  super(active_call, mth, *others)
80
80
  rescue => e
81
81
  kvs[:rpc][:error] = true
82
- current_span.set_tags(kvs)
82
+ current_span.add_attributes(kvs)
83
83
  current_span.record_exception(e)
84
84
  raise
85
85
  ensure
86
- current_span.finish if ::Instana.tracer.tracing?
86
+ current_span&.finish
87
87
  end
88
88
  end
89
89
  end
@@ -25,7 +25,7 @@ module Instana
25
25
 
26
26
  def failed(event)
27
27
  span = @requests.delete(event.request_id)
28
- span.add_error(Exception.new(event.message))
28
+ span.record_exception(Exception.new(event.message))
29
29
 
30
30
  span.finish
31
31
  end
@@ -63,7 +63,7 @@ module Instana
63
63
  current_span&.record_exception(e)
64
64
  raise
65
65
  ensure
66
- current_span&.set_tags(kv_payload)
66
+ current_span&.add_attributes(kv_payload)
67
67
  current_span&.finish unless do_skip
68
68
  end
69
69
 
@@ -122,7 +122,7 @@ module Instana
122
122
 
123
123
  def finalize_trace(current_span, kvs, headers, trace_context)
124
124
  set_response_headers(headers, trace_context) if headers
125
- current_span.set_tags(kvs)
125
+ current_span.add_attributes(kvs)
126
126
  OpenTelemetry::Context.detach(@trace_token) if @trace_token
127
127
  current_span.finish
128
128
  end
@@ -36,7 +36,7 @@ module Instana
36
36
  result = yield
37
37
 
38
38
  if result && result['jid']
39
- span.set_tag(:'sidekiq-client', { job_id: result['jid'] })
39
+ span.set_attribute(:'sidekiq-client', { job_id: result['jid'] })
40
40
  end
41
41
 
42
42
  result
@@ -43,7 +43,7 @@ module Instana
43
43
  yield
44
44
  rescue => e
45
45
  kvs[:'sidekiq-worker'][:error] = true
46
- span.set_tags(kvs)
46
+ span.add_attributes(kvs)
47
47
  span.record_exception(e)
48
48
  raise
49
49
  end
@@ -67,7 +67,7 @@ module Instana
67
67
  else
68
68
  configure_custom(name)
69
69
  end
70
- set_tags(attributes)
70
+ add_attributes(attributes)
71
71
  ::Instana.processor.on_start(self)
72
72
  # Attach a backtrace to all exit spans
73
73
  add_stack if should_collect_stack_trace?
@@ -450,8 +450,7 @@ module Instana
450
450
  #
451
451
  # @return [self] returns itself
452
452
  def set_attribute(key, value)
453
- @attributes ||= {}
454
- @attributes[key] = value
453
+ set_tag(key, value)
455
454
  self
456
455
  end
457
456
  # alias []= set_attribute
@@ -470,8 +469,11 @@ module Instana
470
469
  #
471
470
  # @return [self] returns itself
472
471
  def add_attributes(attributes)
473
- @attributes ||= {}
474
- @attributes.merge!(attributes)
472
+ return unless attributes.is_a?(Hash)
473
+
474
+ attributes.each do |k, v|
475
+ set_tag(k, v)
476
+ end
475
477
  self
476
478
  end
477
479
 
@@ -124,7 +124,7 @@ module Instana
124
124
  Span.new(name)
125
125
  end
126
126
 
127
- current_span.set_tags(kvs) unless kvs.empty?
127
+ current_span.add_attributes(kvs) unless kvs.empty?
128
128
  current_span
129
129
  end
130
130
 
@@ -142,7 +142,7 @@ module Instana
142
142
  else
143
143
  Span.new(name, child_of)
144
144
  end
145
- new_span.set_tags(kvs) if kvs
145
+ new_span.add_attributes(kvs) if kvs
146
146
  self.current_span = new_span
147
147
  end
148
148
 
@@ -153,7 +153,7 @@ module Instana
153
153
  def log_info(kvs)
154
154
  return unless current_span
155
155
 
156
- current_span.set_tags(kvs)
156
+ current_span.add_attributes(kvs)
157
157
  end
158
158
 
159
159
  # Add an error to the current span
@@ -181,7 +181,7 @@ module Instana
181
181
  @logger.warn "Span mismatch: Attempt to end #{name} span but #{current_span.name} is active."
182
182
  end
183
183
 
184
- current_span.set_tags(kvs)
184
+ current_span.add_attributes(kvs)
185
185
  current_span.close
186
186
 
187
187
  self.current_span = current_span.parent || nil
@@ -203,7 +203,7 @@ module Instana
203
203
  @logger.warn "Span mismatch: Attempt to end #{name} span but #{current_span.name} is active."
204
204
  end
205
205
 
206
- current_span.set_tags(kvs)
206
+ current_span.add_attributes(kvs)
207
207
  current_span.close(end_time)
208
208
  self.current_span = nil
209
209
  end
@@ -225,7 +225,7 @@ module Instana
225
225
  return unless tracing?
226
226
 
227
227
  new_span = Span.new(name, current_span)
228
- new_span.set_tags(kvs) unless kvs.empty?
228
+ new_span.add_attributes(kvs) unless kvs.empty?
229
229
  new_span
230
230
  end
231
231
 
@@ -235,7 +235,7 @@ module Instana
235
235
  # @param span [Span] the span for this Async op (previously returned from `log_async_entry`)
236
236
  #
237
237
  def log_async_info(kvs, span)
238
- span.set_tags(kvs)
238
+ span.add_attributes(kvs)
239
239
  end
240
240
 
241
241
  # Add an error to an asynchronous span
@@ -254,7 +254,7 @@ module Instana
254
254
  # @param span [Span] the span for this Async op (previously returned from `log_async_entry`)
255
255
  #
256
256
  def log_async_exit(_name, kvs, span)
257
- span.set_tags(kvs) unless kvs.empty?
257
+ span.add_attributes(kvs) unless kvs.empty?
258
258
  span.close
259
259
  end
260
260
 
@@ -323,7 +323,7 @@ module Instana
323
323
  # with_parent=current context, start_timestamp=current time.
324
324
  #
325
325
  def start_span(name, with_parent: nil, attributes: nil, links: nil, start_timestamp: ::Instana::Util.now_in_ms, kind: nil) # rubocop:disable Metrics/ParameterLists
326
- return if !::Instana.agent.ready? || !::Instana.config[:tracing][:enabled]
326
+ return Instana::Trace.non_recording_span(with_parent) if !::Instana.agent.ready? || !::Instana.config[:tracing][:enabled]
327
327
 
328
328
  with_parent ||= OpenTelemetry::Context.current
329
329
  name ||= 'empty'
data/lib/instana/trace.rb CHANGED
@@ -63,7 +63,7 @@ module Instana
63
63
  #
64
64
  # @return [Span]
65
65
  def non_recording_span(span_context)
66
- Span.new(span_context: span_context)
66
+ OpenTelemetry::Trace::Span.new(span_context: span_context)
67
67
  end
68
68
  end
69
69
  end
data/lib/instana/util.rb CHANGED
@@ -27,25 +27,25 @@ module Instana
27
27
  def take_snapshot
28
28
  data = {}
29
29
 
30
- data[:sensorVersion] = ::Instana::VERSION
31
- data[:ruby_version] = RUBY_VERSION
30
+ data[:sensorVersion] = ::Instana::VERSION.dup
31
+ data[:ruby_version] = RUBY_VERSION.dup
32
32
  data[:rpl] = RUBY_PATCHLEVEL if defined?(RUBY_PATCHLEVEL)
33
33
 
34
34
  # Framework Detection
35
35
  if defined?(::RailsLts::VERSION)
36
- data[:framework] = "Rails on Rails LTS-#{::RailsLts::VERSION}"
36
+ data[:framework] = "Rails on Rails LTS-#{::RailsLts::VERSION}".dup
37
37
 
38
38
  elsif defined?(::Rails.version)
39
- data[:framework] = "Ruby on Rails #{::Rails.version}"
39
+ data[:framework] = "Ruby on Rails #{::Rails.version}".dup
40
40
 
41
41
  elsif defined?(::Grape::VERSION)
42
- data[:framework] = "Grape #{::Grape::VERSION}"
42
+ data[:framework] = "Grape #{::Grape::VERSION}".dup
43
43
 
44
44
  elsif defined?(::Padrino::VERSION)
45
- data[:framework] = "Padrino #{::Padrino::VERSION}"
45
+ data[:framework] = "Padrino #{::Padrino::VERSION}".dup
46
46
 
47
47
  elsif defined?(::Sinatra::VERSION)
48
- data[:framework] = "Sinatra #{::Sinatra::VERSION}"
48
+ data[:framework] = "Sinatra #{::Sinatra::VERSION}".dup
49
49
  end
50
50
 
51
51
  # Report Bundle
@@ -53,7 +53,7 @@ module Instana
53
53
  data[:versions] = {}
54
54
 
55
55
  Gem.loaded_specs.each do |k, v|
56
- data[:versions][k] = v.version.to_s
56
+ data[:versions][k.dup] = v.version.to_s.dup
57
57
  end
58
58
  end
59
59
 
@@ -2,6 +2,6 @@
2
2
  # (c) Copyright Instana Inc. 2016
3
3
 
4
4
  module Instana
5
- VERSION = "2.6.0"
5
+ VERSION = "2.7.0"
6
6
  VERSION_FULL = "instana-#{VERSION}"
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: instana
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.0
4
+ version: 2.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Giacomo Lombardo
@@ -362,7 +362,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
362
362
  - !ruby/object:Gem::Version
363
363
  version: '0'
364
364
  requirements: []
365
- rubygems_version: 4.0.9
365
+ rubygems_version: 4.0.11
366
366
  specification_version: 4
367
367
  summary: Ruby Distributed Tracing & Metrics Sensor for Instana
368
368
  test_files: []