opentrace 0.17.0 → 0.17.1

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: '0785fe05f95bd64567435b2bb20ed18d4882a14ac765351a741cf322dc8d6ade'
4
- data.tar.gz: b656ded61cf12de7b5657d69234d11fe52ffb7b9eb9aee2cc6568b33baeaa16a
3
+ metadata.gz: a52fdd745f23752d86ae494048fb8b6395374ec08f7ba6b9e3edccd0bea80036
4
+ data.tar.gz: b9b3aaab811c9997681a535a1b50d7c9ad0e567c872cb0075c509abd7567f339
5
5
  SHA512:
6
- metadata.gz: ce7a3567bb634e3859218b7be7b57ede064ebdad47943855fc4758c764eea74a13608e2c5983e965e793f0f36786043146c00dfa65c8b5bcb85ebf4e499567d4
7
- data.tar.gz: 9c01f33f3b5416e9fea909b2c3ac841742fdb6ed4b85feb156e8166585790a76d373e2e2714ea67afc9bb5d8ec2d24f040b4c53e6c7646389d55b3165f759427
6
+ metadata.gz: 7dc954766e198906d4c16448b49be2e0dc26aca08e5f8fa3031d3a6f6c6d9c98f6278e2febbc3f717680522b06807c756a80f3b84dbf69c1c8c20e8ca1c99b6b
7
+ data.tar.gz: 0f0a49079c6bef6317208325361dfa4edd07cc509043a7e10dbceadd67ecda35311e306c2e5fb64115bf4e6fab111e23fac05ccbe5bcddb5324aad7325d4a06c
@@ -43,14 +43,34 @@ module OpenTrace
43
43
  # Guard 2: skip if this IS an OpenTrace dispatch call (prevent infinite recursion)
44
44
  return super if Fiber[:opentrace_http_tracking_disabled]
45
45
 
46
- # Inject trace context into outgoing request headers
47
- inject_trace_context(req) if OpenTrace.config.trace_propagation
46
+ # Trace context injection is bookkeeping — must never raise to the host.
47
+ begin
48
+ inject_trace_context(req) if OpenTrace.config.trace_propagation
49
+ rescue StandardError
50
+ end
48
51
 
49
- collector = Fiber[:opentrace_collector]
50
52
  start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
51
53
 
52
- response = super
54
+ begin
55
+ response = super
56
+ rescue IOError, SystemCallError, OpenSSL::SSL::SSLError, Timeout::Error, Net::ProtocolError => e
57
+ # Real network error from the host's HTTP call. Record it, then re-raise
58
+ # so the host app sees the error it's expecting to handle.
59
+ record_http_failure(req, e, start_time) rescue nil
60
+ raise
61
+ end
62
+
63
+ # Bookkeeping for a successful response. Any bug here (NoMethodError on
64
+ # a streaming body, a payload builder regression, etc.) must NOT bubble
65
+ # into host code — swallow and move on.
66
+ record_http_success(req, response, start_time) rescue nil
67
+
68
+ response
69
+ end
53
70
 
71
+ private
72
+
73
+ def record_http_success(req, response, start_time)
54
74
  duration_ms = (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) * 1000
55
75
  host = address
56
76
  port_str = (port == 443 || port == 80) ? "" : ":#{port}"
@@ -58,18 +78,11 @@ module OpenTrace
58
78
  safe_path = req.path.to_s.split("?").first
59
79
  url = "#{scheme}://#{host}#{port_str}#{safe_path}"
60
80
 
61
- # Capture request body (if present and under size limit)
62
- req_body = nil
63
- if req.body && req.body.is_a?(String) && req.body.bytesize < MAX_BODY_CAPTURE_BYTES
64
- req_body = req.body
65
- end
66
-
67
- # Capture response body (if under size limit)
68
- resp_body = nil
69
- if response.body && response.body.is_a?(String) && response.body.bytesize < MAX_BODY_CAPTURE_BYTES
70
- resp_body = response.body
71
- end
81
+ req_body = capturable_body(req.body)
82
+ resp_body = capturable_body(response.body)
83
+ resp_size = body_size(response)
72
84
 
85
+ collector = Fiber[:opentrace_collector]
73
86
  if collector
74
87
  collector.record_http(
75
88
  method: req.method,
@@ -90,22 +103,23 @@ module OpenTrace
90
103
  vendor: vendor,
91
104
  status: response.code.to_i,
92
105
  duration_ms: duration_ms,
93
- request_headers: nil, # skip headers for now to save memory
106
+ request_headers: nil,
94
107
  request_body: req_body,
95
108
  response_headers: nil,
96
109
  response_body: resp_body,
97
- response_size: response.body&.bytesize,
110
+ response_size: resp_size,
98
111
  retry_attempt: 0,
99
112
  error_class: nil
100
113
  )
101
114
  buffer.record_timeline(type: :http, name: "#{req.method} #{host}", duration_ms: duration_ms)
102
115
  end
116
+ end
103
117
 
104
- response
105
- rescue IOError, SystemCallError, OpenSSL::SSL::SSLError, Timeout::Error, Net::ProtocolError => e
106
- # Record the failed HTTP call, then re-raise
118
+ def record_http_failure(req, error, start_time)
107
119
  duration_ms = start_time ? (Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time) * 1000 : 0
120
+ req_body = req ? capturable_body(req.body) : nil
108
121
 
122
+ collector = Fiber[:opentrace_collector]
109
123
  if collector
110
124
  collector.record_http(
111
125
  method: req&.method,
@@ -113,7 +127,7 @@ module OpenTrace
113
127
  host: address,
114
128
  status: 0,
115
129
  duration_ms: duration_ms,
116
- error: e.class.name
130
+ error: error.class.name
117
131
  )
118
132
  end
119
133
 
@@ -130,14 +144,25 @@ module OpenTrace
130
144
  request_body: req_body,
131
145
  response_body: nil,
132
146
  response_size: nil,
133
- error_class: e.class.name
147
+ error_class: error.class.name
134
148
  )
135
149
  end
150
+ end
136
151
 
137
- raise # ALWAYS re-raise — never swallow app errors
152
+ def capturable_body(body)
153
+ return nil unless body.is_a?(String)
154
+ return nil if body.bytesize >= MAX_BODY_CAPTURE_BYTES
155
+ body
138
156
  end
139
157
 
140
- private
158
+ # Response body size when it can be determined without re-reading the stream.
159
+ # Streaming responses (Net::ReadAdapter) can't be re-read, so we fall back
160
+ # to Content-Length when present, otherwise nil.
161
+ def body_size(response)
162
+ return response.body.bytesize if response.body.is_a?(String)
163
+ len = response["Content-Length"]
164
+ len ? len.to_i : nil
165
+ end
141
166
 
142
167
  def inject_trace_context(req)
143
168
  trace_id = Fiber[:opentrace_trace_id]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenTrace
4
- VERSION = "0.17.0"
4
+ VERSION = "0.17.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentrace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.0
4
+ version: 0.17.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTrace