opentelemetry-instrumentation-rack 0.31.1 → 0.31.2

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: 274fb4ae57ba631bc86537a1e484a1f511580d547e5c3f7a7a92aa8a11caef43
4
- data.tar.gz: 77a79da1aa888c961c4bc507f713ed1b7b56ec5777cb9b49326eed4e02768317
3
+ metadata.gz: 8fee0acda7de18eada9a2c6f2dbed4a518f22bca85179d197d003991173dd70d
4
+ data.tar.gz: fbd322a82ad0ab67bf142835dcec558c688142caff4785e4c1ee7c2c18ae97a3
5
5
  SHA512:
6
- metadata.gz: ae91cc819975e211fc3e0ea5df0100cc81fa9f3e5cd82868e664db8d722ab5393e81383fb5fbde9514b06a68cdbfb11e39ccee2e1cdce1e4fe94c5be9a5672a3
7
- data.tar.gz: 3d0948ccc1dd3d67bc30fad67657e76cc8a8b314f3734f44aa5d3471cf76d26792f890175b0c55914cde9dbfffdeac506079bc796d5d7194ec5467879ea2ddbb
6
+ metadata.gz: 3fbf53b401c0592f1579bb0c02a047a4caae707e7509aa7654cf6274aaf04dec6ea9ad4c8e841c8bd3650ebd1c497c3d42db603da9b758a5d650e7938477a2e7
7
+ data.tar.gz: b70bb4e5dbbab7387ac043ea1cbdcd1aef82a3a57b1db9938da2dd73102c0cbdd5c63d523305bed24bf46b28d745c0b451e057cdc5134cbdffc20982048f69f9
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Release History: opentelemetry-instrumentation-rack
2
2
 
3
+ ## v0.31.2 / 2026-09-29
4
+
5
+ - FIXED: Fiber-safe context detachment in `EventHandler` (#2130)
6
+
3
7
  ## v0.31.1 / 2026-05-21
4
8
 
5
9
  - FIXED: Handle missing config in middleware when OTEL_SDK_DISABLED=true (#2231)
@@ -43,7 +43,7 @@ module OpenTelemetry
43
43
  class EventHandler
44
44
  include ::Rack::Events::Abstract
45
45
 
46
- OTEL_TOKEN_AND_SPAN = 'otel.rack.token_and_span'
46
+ OTEL_CONTEXT_INFO = 'otel.rack.context_info'
47
47
  EMPTY_HASH = {}.freeze
48
48
 
49
49
  # Creates a server span for this current request using the incoming parent context
@@ -62,7 +62,8 @@ module OpenTelemetry
62
62
  span = create_span(parent_context, request)
63
63
  span_ctx = OpenTelemetry::Trace.context_with_span(span, parent_context: parent_context)
64
64
  rack_ctx = OpenTelemetry::Instrumentation::Rack.context_with_span(span, parent_context: span_ctx)
65
- request.env[OTEL_TOKEN_AND_SPAN] = [OpenTelemetry::Context.attach(rack_ctx), span]
65
+ token = OpenTelemetry::Context.attach(rack_ctx)
66
+ (request.env[OTEL_CONTEXT_INFO] ||= {})[request] = [Fiber.current, token, span]
66
67
  rescue StandardError => e
67
68
  OpenTelemetry.handle_error(exception: e)
68
69
  end
@@ -107,14 +108,17 @@ module OpenTelemetry
107
108
  # @param [Rack::Request] The current HTTP request
108
109
  # @param [Rack::Response] The current HTTP response
109
110
  def on_finish(request, response)
110
- span = OpenTelemetry::Instrumentation::Rack.current_span
111
+ request_context = context_for_request(request)
112
+ return unless request_context
113
+
114
+ _, _, span = request_context
111
115
  return unless span.recording?
112
116
 
113
117
  add_response_attributes(span, response) if response
114
118
  rescue StandardError => e
115
119
  OpenTelemetry.handle_error(exception: e)
116
120
  ensure
117
- detach_context(request)
121
+ detach_context(request_context)
118
122
  end
119
123
 
120
124
  private
@@ -208,12 +212,24 @@ module OpenTelemetry
208
212
  attributes
209
213
  end
210
214
 
211
- def detach_context(request)
212
- return nil unless request.env[OTEL_TOKEN_AND_SPAN]
215
+ def context_for_request(request)
216
+ contexts = request.env[OTEL_CONTEXT_INFO]
217
+ return unless contexts
218
+
219
+ contexts.delete(request)
220
+ end
221
+
222
+ def detach_context(request_context)
223
+ return unless request_context
213
224
 
214
- token, span = request.env[OTEL_TOKEN_AND_SPAN]
225
+ original_fiber, token, span = request_context
215
226
  span.finish
216
- OpenTelemetry::Context.detach(token)
227
+
228
+ if Fiber.current.equal?(original_fiber)
229
+ OpenTelemetry::Context.detach(token)
230
+ else
231
+ OpenTelemetry.logger.debug { '[OpenTelemetry::Instrumentation::Rack] Skipping context detach: response processed in different fiber than request.' }
232
+ end
217
233
  rescue StandardError => e
218
234
  OpenTelemetry.handle_error(exception: e)
219
235
  end
@@ -43,7 +43,7 @@ module OpenTelemetry
43
43
  class EventHandler
44
44
  include ::Rack::Events::Abstract
45
45
 
46
- OTEL_TOKEN_AND_SPAN = 'otel.rack.token_and_span'
46
+ OTEL_CONTEXT_INFO = 'otel.rack.context_info'
47
47
  EMPTY_HASH = {}.freeze
48
48
 
49
49
  # Creates a server span for this current request using the incoming parent context
@@ -62,7 +62,8 @@ module OpenTelemetry
62
62
  span = create_span(parent_context, request)
63
63
  span_ctx = OpenTelemetry::Trace.context_with_span(span, parent_context: parent_context)
64
64
  rack_ctx = OpenTelemetry::Instrumentation::Rack.context_with_span(span, parent_context: span_ctx)
65
- request.env[OTEL_TOKEN_AND_SPAN] = [OpenTelemetry::Context.attach(rack_ctx), span]
65
+ token = OpenTelemetry::Context.attach(rack_ctx)
66
+ (request.env[OTEL_CONTEXT_INFO] ||= {})[request] = [Fiber.current, token, span]
66
67
  rescue StandardError => e
67
68
  OpenTelemetry.handle_error(exception: e)
68
69
  end
@@ -107,14 +108,17 @@ module OpenTelemetry
107
108
  # @param [Rack::Request] The current HTTP request
108
109
  # @param [Rack::Response] The current HTTP response
109
110
  def on_finish(request, response)
110
- span = OpenTelemetry::Instrumentation::Rack.current_span
111
+ request_context = context_for_request(request)
112
+ return unless request_context
113
+
114
+ _, _, span = request_context
111
115
  return unless span.recording?
112
116
 
113
117
  add_response_attributes(span, response) if response
114
118
  rescue StandardError => e
115
119
  OpenTelemetry.handle_error(exception: e)
116
120
  ensure
117
- detach_context(request)
121
+ detach_context(request_context)
118
122
  end
119
123
 
120
124
  private
@@ -197,12 +201,24 @@ module OpenTelemetry
197
201
  attributes
198
202
  end
199
203
 
200
- def detach_context(request)
201
- return nil unless request.env[OTEL_TOKEN_AND_SPAN]
204
+ def context_for_request(request)
205
+ contexts = request.env[OTEL_CONTEXT_INFO]
206
+ return unless contexts
207
+
208
+ contexts.delete(request)
209
+ end
210
+
211
+ def detach_context(request_context)
212
+ return unless request_context
202
213
 
203
- token, span = request.env[OTEL_TOKEN_AND_SPAN]
214
+ original_fiber, token, span = request_context
204
215
  span.finish
205
- OpenTelemetry::Context.detach(token)
216
+
217
+ if Fiber.current.equal?(original_fiber)
218
+ OpenTelemetry::Context.detach(token)
219
+ else
220
+ OpenTelemetry.logger.debug { '[OpenTelemetry::Instrumentation::Rack] Skipping context detach: response processed in different fiber than request.' }
221
+ end
206
222
  rescue StandardError => e
207
223
  OpenTelemetry.handle_error(exception: e)
208
224
  end
@@ -43,7 +43,7 @@ module OpenTelemetry
43
43
  class EventHandler
44
44
  include ::Rack::Events::Abstract
45
45
 
46
- OTEL_TOKEN_AND_SPAN = 'otel.rack.token_and_span'
46
+ OTEL_CONTEXT_INFO = 'otel.rack.context_info'
47
47
  EMPTY_HASH = {}.freeze
48
48
 
49
49
  # Creates a server span for this current request using the incoming parent context
@@ -62,7 +62,8 @@ module OpenTelemetry
62
62
  span = create_span(parent_context, request)
63
63
  span_ctx = OpenTelemetry::Trace.context_with_span(span, parent_context: parent_context)
64
64
  rack_ctx = OpenTelemetry::Instrumentation::Rack.context_with_span(span, parent_context: span_ctx)
65
- request.env[OTEL_TOKEN_AND_SPAN] = [OpenTelemetry::Context.attach(rack_ctx), span]
65
+ token = OpenTelemetry::Context.attach(rack_ctx)
66
+ (request.env[OTEL_CONTEXT_INFO] ||= {})[request] = [Fiber.current, token, span]
66
67
  rescue StandardError => e
67
68
  OpenTelemetry.handle_error(exception: e)
68
69
  end
@@ -107,14 +108,17 @@ module OpenTelemetry
107
108
  # @param [Rack::Request] The current HTTP request
108
109
  # @param [Rack::Response] The current HTTP response
109
110
  def on_finish(request, response)
110
- span = OpenTelemetry::Instrumentation::Rack.current_span
111
+ request_context = context_for_request(request)
112
+ return unless request_context
113
+
114
+ _, _, span = request_context
111
115
  return unless span.recording?
112
116
 
113
117
  add_response_attributes(span, response) if response
114
118
  rescue StandardError => e
115
119
  OpenTelemetry.handle_error(exception: e)
116
120
  ensure
117
- detach_context(request)
121
+ detach_context(request_context)
118
122
  end
119
123
 
120
124
  private
@@ -196,12 +200,24 @@ module OpenTelemetry
196
200
  attributes
197
201
  end
198
202
 
199
- def detach_context(request)
200
- return nil unless request.env[OTEL_TOKEN_AND_SPAN]
203
+ def context_for_request(request)
204
+ contexts = request.env[OTEL_CONTEXT_INFO]
205
+ return unless contexts
206
+
207
+ contexts.delete(request)
208
+ end
209
+
210
+ def detach_context(request_context)
211
+ return unless request_context
201
212
 
202
- token, span = request.env[OTEL_TOKEN_AND_SPAN]
213
+ original_fiber, token, span = request_context
203
214
  span.finish
204
- OpenTelemetry::Context.detach(token)
215
+
216
+ if Fiber.current.equal?(original_fiber)
217
+ OpenTelemetry::Context.detach(token)
218
+ else
219
+ OpenTelemetry.logger.debug { '[OpenTelemetry::Instrumentation::Rack] Skipping context detach: response processed in different fiber than request.' }
220
+ end
205
221
  rescue StandardError => e
206
222
  OpenTelemetry.handle_error(exception: e)
207
223
  end
@@ -7,7 +7,7 @@
7
7
  module OpenTelemetry
8
8
  module Instrumentation
9
9
  module Rack
10
- VERSION = '0.31.1'
10
+ VERSION = '0.31.2'
11
11
  end
12
12
  end
13
13
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentelemetry-instrumentation-rack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.31.1
4
+ version: 0.31.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTelemetry Authors
@@ -51,10 +51,10 @@ homepage: https://github.com/open-telemetry/opentelemetry-ruby-contrib
51
51
  licenses:
52
52
  - Apache-2.0
53
53
  metadata:
54
- changelog_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-rack/0.31.1/file/CHANGELOG.md
55
- source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/opentelemetry-instrumentation-rack/v0.31.1/instrumentation/rack
54
+ changelog_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-rack/0.31.2/file/CHANGELOG.md
55
+ source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/opentelemetry-instrumentation-rack/v0.31.2/instrumentation/rack
56
56
  bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/issues
57
- documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-rack/0.31.1
57
+ documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-rack/0.31.2
58
58
  rdoc_options: []
59
59
  require_paths:
60
60
  - lib
@@ -69,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
69
69
  - !ruby/object:Gem::Version
70
70
  version: '0'
71
71
  requirements: []
72
- rubygems_version: 4.0.6
72
+ rubygems_version: 4.0.16
73
73
  specification_version: 4
74
74
  summary: Rack instrumentation for the OpenTelemetry framework
75
75
  test_files: []