instana 2.8.0 → 2.9.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 +4 -4
- data/lib/instana/config.rb +75 -0
- data/lib/instana/instrumentation/excon.rb +8 -5
- data/lib/instana/instrumentation/net-http.rb +3 -3
- data/lib/instana/instrumentation/rest-client.rb +13 -1
- data/lib/instana/util.rb +35 -0
- data/lib/instana/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 52139723659935eb43ab59f60e5c0f7305d860d5457c9545d395f9e4576fc604
|
|
4
|
+
data.tar.gz: 223dcdbe22af35ceed817411b850114f9cf3e7eb5fce3b3fc1b4f5ffa29c00e1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0743a4a453182c90abb623189d4a6e5105cd03e3823b3b6cf9ee5269c80f14652d21bfc5481c914457a79a8a52633c718cfd1581d219122327996cb67c2b222f
|
|
7
|
+
data.tar.gz: 767f9eb2f714e83e045f27086061ef11ab3511574b8636c87740595f871a0051ccc977341e0e523f174d4f4d5a4575fbcd3d8b87ed1ab26b347198fbdb3d4d94
|
data/lib/instana/config.rb
CHANGED
|
@@ -80,6 +80,10 @@ module Instana
|
|
|
80
80
|
# W3C Trace Context Support
|
|
81
81
|
@config[:w3c_trace_correlation] = ENV.fetch('INSTANA_DISABLE_W3C_TRACE_CORRELATION', nil).nil?
|
|
82
82
|
|
|
83
|
+
# HTTP exit span 4xx error classification (opt-in, default: off)
|
|
84
|
+
# Priority: env vars > agent config > default (false / [])
|
|
85
|
+
read_http_exit_config
|
|
86
|
+
|
|
83
87
|
@config[:post_fork_proc] = proc { ::Instana.agent.spawn_background_thread }
|
|
84
88
|
|
|
85
89
|
@config[:action_controller] = { :enabled => true }
|
|
@@ -142,6 +146,8 @@ module Instana
|
|
|
142
146
|
read_span_stack_config_from_agent(tracing_config) if should_read_from_agent?(:back_trace)
|
|
143
147
|
# Read OTLP configuration from agent if not already set from YAML or env
|
|
144
148
|
read_otlp_config_from_agent(tracing_config) if should_read_from_agent?(:otlp)
|
|
149
|
+
# Read HTTP exit 4xx classification from agent if env vars did not already set it
|
|
150
|
+
read_http_exit_classification_from_agent(tracing_config) unless env_http_exit_classification_set?
|
|
145
151
|
# Read span filtering configuration from agent
|
|
146
152
|
::Instana.span_filtering_config&.read_config_from_agent(discovery)
|
|
147
153
|
rescue => e
|
|
@@ -256,6 +262,75 @@ module Instana
|
|
|
256
262
|
|
|
257
263
|
private
|
|
258
264
|
|
|
265
|
+
# Read HTTP exit 4xx error classification config (wrapper — same pattern as read_span_stack_config / read_otlp_config)
|
|
266
|
+
def read_http_exit_config
|
|
267
|
+
@config[:http_exit_classify_all_4xx_as_errors] = false
|
|
268
|
+
@config[:http_exit_classify_as_errors] = []
|
|
269
|
+
read_http_exit_classification_from_env
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
# Read HTTP exit 4xx classification from environment variables (highest priority).
|
|
273
|
+
def read_http_exit_classification_from_env
|
|
274
|
+
classify_codes_raw = ENV.fetch('INSTANA_TRACING_HTTP_EXIT_CLASSIFY_AS_ERRORS', nil)
|
|
275
|
+
if classify_codes_raw
|
|
276
|
+
codes = classify_codes_raw.split(',').filter_map do |part|
|
|
277
|
+
part = part.strip
|
|
278
|
+
if part.match?(/\A\d+\z/)
|
|
279
|
+
code = part.to_i
|
|
280
|
+
if (400..499).cover?(code)
|
|
281
|
+
code
|
|
282
|
+
else
|
|
283
|
+
msg = "Ignoring out-of-range value in INSTANA_TRACING_HTTP_EXIT_CLASSIFY_AS_ERRORS: #{code}, must be 400-499"
|
|
284
|
+
::Instana.logger.warn(msg)
|
|
285
|
+
nil
|
|
286
|
+
end
|
|
287
|
+
elsif part != ''
|
|
288
|
+
::Instana.logger.warn("Ignoring non-integer value in INSTANA_TRACING_HTTP_EXIT_CLASSIFY_AS_ERRORS: #{part}")
|
|
289
|
+
nil
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
@config[:http_exit_classify_as_errors] = codes unless codes.empty?
|
|
293
|
+
else
|
|
294
|
+
classify_all_raw = ENV.fetch('INSTANA_TRACING_HTTP_EXIT_CLASSIFY_ALL_4XX_AS_ERRORS', nil)
|
|
295
|
+
@config[:http_exit_classify_all_4xx_as_errors] = truthy?(classify_all_raw) if classify_all_raw
|
|
296
|
+
end
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
# Return true if env vars have already configured HTTP exit 4xx classification.
|
|
300
|
+
def env_http_exit_classification_set?
|
|
301
|
+
ENV.key?('INSTANA_TRACING_HTTP_EXIT_CLASSIFY_AS_ERRORS') ||
|
|
302
|
+
ENV.key?('INSTANA_TRACING_HTTP_EXIT_CLASSIFY_ALL_4XX_AS_ERRORS')
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
# Read HTTP exit 4xx classification from agent discovery response (lowest priority).
|
|
306
|
+
# @param tracing_config [Hash] the tracing sub-hash from the discovery payload
|
|
307
|
+
def read_http_exit_classification_from_agent(tracing_config)
|
|
308
|
+
http_cfg = tracing_config['http']
|
|
309
|
+
return unless http_cfg.is_a?(Hash)
|
|
310
|
+
|
|
311
|
+
exit_cfg = http_cfg['exit']
|
|
312
|
+
return unless exit_cfg.is_a?(Hash)
|
|
313
|
+
|
|
314
|
+
if exit_cfg.key?('classify-as-errors')
|
|
315
|
+
codes = Array(exit_cfg['classify-as-errors']).filter_map do |code|
|
|
316
|
+
if code.is_a?(Integer) && (400..499).cover?(code)
|
|
317
|
+
code
|
|
318
|
+
else
|
|
319
|
+
::Instana.logger.warn("Ignoring invalid value in agent config tracing.http.exit.classify-as-errors: #{code}")
|
|
320
|
+
nil
|
|
321
|
+
end
|
|
322
|
+
end
|
|
323
|
+
@config[:http_exit_classify_as_errors] = codes unless codes.empty?
|
|
324
|
+
elsif exit_cfg.key?('classify-all-4xx-as-errors')
|
|
325
|
+
val = exit_cfg['classify-all-4xx-as-errors']
|
|
326
|
+
if [true, false].include?(val)
|
|
327
|
+
@config[:http_exit_classify_all_4xx_as_errors] = val
|
|
328
|
+
else
|
|
329
|
+
::Instana.logger.warn("Ignoring non-boolean value in agent config tracing.http.exit.classify-all-4xx-as-errors: #{val}")
|
|
330
|
+
end
|
|
331
|
+
end
|
|
332
|
+
end
|
|
333
|
+
|
|
259
334
|
# Read OTLP configuration — precedence: YAML > env vars > defaults (agent handled separately)
|
|
260
335
|
def read_otlp_config
|
|
261
336
|
# Try YAML first
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# (c) Copyright IBM Corp. 2021
|
|
2
2
|
# (c) Copyright Instana Inc. 2016
|
|
3
3
|
|
|
4
|
+
require 'instana/util'
|
|
5
|
+
|
|
4
6
|
module Instana
|
|
5
7
|
module Instrumentation
|
|
6
8
|
class Excon < ::Excon::Middleware::Base
|
|
@@ -60,17 +62,18 @@ module Instana
|
|
|
60
62
|
status = datum[:response][:status]
|
|
61
63
|
end
|
|
62
64
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
65
|
+
http_kv = { status: status }
|
|
66
|
+
if ::Instana::Util.should_mark_http_exit_as_error?(status)
|
|
67
|
+
reason = ::Instana::Util.http_reason_phrase(status)
|
|
68
|
+
http_kv[:error] = reason ? "#{status} #{reason}" : status.to_s
|
|
66
69
|
::Instana.tracer.log_error(nil)
|
|
67
70
|
end
|
|
68
71
|
|
|
69
72
|
if datum[:pipeline] == true
|
|
70
73
|
# Pickup context of this async span from datum[:instana_span]
|
|
71
|
-
::Instana.tracer.log_async_exit(:excon, { :http =>
|
|
74
|
+
::Instana.tracer.log_async_exit(:excon, { :http => http_kv }, datum[:instana_span])
|
|
72
75
|
else
|
|
73
|
-
::Instana.tracer.log_exit(:excon, { :http =>
|
|
76
|
+
::Instana.tracer.log_exit(:excon, { :http => http_kv })
|
|
74
77
|
end
|
|
75
78
|
result
|
|
76
79
|
end
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
# (c) Copyright Instana Inc. 2016
|
|
3
3
|
|
|
4
4
|
require 'net/http'
|
|
5
|
+
require 'instana/util'
|
|
5
6
|
|
|
6
7
|
module Instana
|
|
7
8
|
module Instrumentation
|
|
@@ -51,9 +52,8 @@ module Instana
|
|
|
51
52
|
response = super(*args, &block)
|
|
52
53
|
|
|
53
54
|
kv_payload[:http][:status] = response.code
|
|
54
|
-
if response.code.to_i
|
|
55
|
-
|
|
56
|
-
# without a backtrace (no exception)
|
|
55
|
+
if ::Instana::Util.should_mark_http_exit_as_error?(response.code.to_i)
|
|
56
|
+
kv_payload[:http][:error] = "#{response.code} #{response.message}"
|
|
57
57
|
current_span.record_exception(nil)
|
|
58
58
|
end
|
|
59
59
|
extra_headers = ::Instana::Util.extra_header_tags(response)&.merge(::Instana::Util.extra_header_tags(request))
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# (c) Copyright IBM Corp. 2021
|
|
2
2
|
# (c) Copyright Instana Inc. 2016
|
|
3
3
|
|
|
4
|
+
require 'instana/util'
|
|
5
|
+
|
|
4
6
|
module Instana
|
|
5
7
|
module Instrumentation
|
|
6
8
|
module RestClientRequest
|
|
@@ -12,11 +14,21 @@ module Instana
|
|
|
12
14
|
|
|
13
15
|
Trace.with_span(span) { super(&block) }
|
|
14
16
|
rescue => e
|
|
15
|
-
span.record_exception(e)
|
|
17
|
+
span.record_exception(e) if error_span?(e)
|
|
16
18
|
raise
|
|
17
19
|
ensure
|
|
18
20
|
span.finish
|
|
19
21
|
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def error_span?(exception)
|
|
26
|
+
if exception.respond_to?(:response) && exception.response.respond_to?(:code)
|
|
27
|
+
::Instana::Util.should_mark_http_exit_as_error?(exception.response.code.to_i)
|
|
28
|
+
else
|
|
29
|
+
true
|
|
30
|
+
end
|
|
31
|
+
end
|
|
20
32
|
end
|
|
21
33
|
end
|
|
22
34
|
end
|
data/lib/instana/util.rb
CHANGED
|
@@ -194,6 +194,41 @@ module Instana
|
|
|
194
194
|
|
|
195
195
|
headers
|
|
196
196
|
end
|
|
197
|
+
|
|
198
|
+
# Return true if an HTTP exit span with +status_code+ should be marked as errored.
|
|
199
|
+
#
|
|
200
|
+
# Rules (in priority order):
|
|
201
|
+
# 1. status >= 500 → always an error.
|
|
202
|
+
# 2. 400 <= status <= 499 and +config[:http_exit_classify_as_errors]+ is non-empty
|
|
203
|
+
# → error only if +status_code+ is in that list.
|
|
204
|
+
# 3. 400 <= status <= 499 and +config[:http_exit_classify_all_4xx_as_errors]+ is true
|
|
205
|
+
# → error for every 4xx code.
|
|
206
|
+
# 4. Otherwise → not an error.
|
|
207
|
+
#
|
|
208
|
+
# Entry (server/rack) spans must never be passed here; this helper is for exit spans only.
|
|
209
|
+
def should_mark_http_exit_as_error?(status_code)
|
|
210
|
+
return true if status_code >= 500
|
|
211
|
+
|
|
212
|
+
if (400..499).cover?(status_code)
|
|
213
|
+
codes = ::Instana.config[:http_exit_classify_as_errors]
|
|
214
|
+
return codes.include?(status_code) if codes&.any?
|
|
215
|
+
|
|
216
|
+
return ::Instana.config[:http_exit_classify_all_4xx_as_errors]
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
false
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
# Return the HTTP reason phrase for a numeric status code, or nil if unknown.
|
|
223
|
+
# Uses Ruby stdlib Net::HTTPResponse::CODE_TO_OBJ to derive the phrase from
|
|
224
|
+
# the response class name (e.g. Net::HTTPUnauthorized → "Unauthorized").
|
|
225
|
+
def http_reason_phrase(status_code)
|
|
226
|
+
require 'net/http'
|
|
227
|
+
klass = Net::HTTPResponse::CODE_TO_OBJ[status_code.to_s]
|
|
228
|
+
return nil unless klass
|
|
229
|
+
|
|
230
|
+
klass.name.sub('Net::HTTP', '').gsub(/([A-Z])/, ' \1').strip
|
|
231
|
+
end
|
|
197
232
|
end
|
|
198
233
|
end
|
|
199
234
|
end
|
data/lib/instana/version.rb
CHANGED
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.
|
|
4
|
+
version: 2.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Peter Giacomo Lombardo
|
|
@@ -416,7 +416,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
416
416
|
- !ruby/object:Gem::Version
|
|
417
417
|
version: '0'
|
|
418
418
|
requirements: []
|
|
419
|
-
rubygems_version: 4.0.
|
|
419
|
+
rubygems_version: 4.0.21
|
|
420
420
|
specification_version: 4
|
|
421
421
|
summary: Ruby Distributed Tracing & Metrics Sensor for Instana
|
|
422
422
|
test_files: []
|