opentelemetry-instrumentation-rack 0.26.0 → 0.27.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/CHANGELOG.md +22 -18
- data/README.md +17 -1
- data/lib/opentelemetry/instrumentation/rack/instrumentation.rb +49 -7
- data/lib/opentelemetry/instrumentation/rack/middlewares/dup/event_handler.rb +281 -0
- data/lib/opentelemetry/instrumentation/rack/middlewares/dup/tracer_middleware.rb +214 -0
- data/lib/opentelemetry/instrumentation/rack/middlewares/old/event_handler.rb +270 -0
- data/lib/opentelemetry/instrumentation/rack/middlewares/old/tracer_middleware.rb +205 -0
- data/lib/opentelemetry/instrumentation/rack/middlewares/stable/event_handler.rb +269 -0
- data/lib/opentelemetry/instrumentation/rack/middlewares/stable/tracer_middleware.rb +206 -0
- data/lib/opentelemetry/instrumentation/rack/version.rb +1 -1
- metadata +10 -188
- data/lib/opentelemetry/instrumentation/rack/middlewares/event_handler.rb +0 -268
- data/lib/opentelemetry/instrumentation/rack/middlewares/tracer_middleware.rb +0 -203
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc9a992d78dc638729e4aedee6f1ad68e8b78cb821e87f40a0e6cbd36f0fe342
|
4
|
+
data.tar.gz: a9dc3e570b412ece3e0aa7639ccd5ad4fc492eb684cfa22637381a9db2e6b637
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 93eb31f83a0397672772a83029e78c191297c2c1ee40a0714350266322e27d9d1fb2bb4ba5b16db5f3510eb26f0fadbb66e6c9fa813b2eeb1cdda09d7cf63647
|
7
|
+
data.tar.gz: fadb07f473254bf14c9e3a85e3a792ad7c37e89d194562bcebd8a9179809f873da1efc1a4b4064e3a9c5a5db17b834a5db8df3ac5b2150fe1f5b3d5541e17327
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Release History: opentelemetry-instrumentation-rack
|
2
2
|
|
3
|
+
### v0.27.0 / 2025-08-19
|
4
|
+
|
5
|
+
* ADDED: Add `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable compatibility [#1594](https://github.com/open-telemetry/opentelemetry-ruby-contrib/pull/1594)
|
6
|
+
|
3
7
|
### v0.26.0 / 2025-01-16
|
4
8
|
|
5
9
|
* BREAKING CHANGE: Set minimum supported version to Ruby 3.1
|
@@ -59,21 +63,21 @@
|
|
59
63
|
|
60
64
|
### v0.23.1 / 2023-06-05
|
61
65
|
|
62
|
-
* FIXED: Base config options
|
66
|
+
* FIXED: Base config options
|
63
67
|
|
64
68
|
### v0.23.0 / 2023-04-17
|
65
69
|
|
66
|
-
* BREAKING CHANGE: Remove retain_middleware_names Rack Option
|
67
|
-
* BREAKING CHANGE: Drop support for EoL Ruby 2.7
|
70
|
+
* BREAKING CHANGE: Remove retain_middleware_names Rack Option
|
71
|
+
* BREAKING CHANGE: Drop support for EoL Ruby 2.7
|
68
72
|
|
69
|
-
* ADDED: Remove retain_middleware_names Rack Option
|
70
|
-
* ADDED: Drop support for EoL Ruby 2.7
|
71
|
-
* ADDED: Use Rack::Events for instrumentation
|
73
|
+
* ADDED: Remove retain_middleware_names Rack Option
|
74
|
+
* ADDED: Drop support for EoL Ruby 2.7
|
75
|
+
* ADDED: Use Rack::Events for instrumentation
|
72
76
|
|
73
77
|
### v0.22.1 / 2023-01-14
|
74
78
|
|
75
|
-
* DOCS: Fix gem homepage
|
76
|
-
* DOCS: More gem documentation fixes
|
79
|
+
* DOCS: Fix gem homepage
|
80
|
+
* DOCS: More gem documentation fixes
|
77
81
|
|
78
82
|
### v0.22.0 / 2022-11-16
|
79
83
|
|
@@ -86,17 +90,17 @@
|
|
86
90
|
### v0.21.0 / 2022-06-09
|
87
91
|
|
88
92
|
* Upgrading Base dependency version
|
89
|
-
* FIXED: Broken test file requirements
|
93
|
+
* FIXED: Broken test file requirements
|
90
94
|
|
91
95
|
### v0.20.2 / 2022-05-02
|
92
96
|
|
93
|
-
* FIXED: Update server instrumentation to not reflect 400 status as error
|
97
|
+
* FIXED: Update server instrumentation to not reflect 400 status as error
|
94
98
|
|
95
99
|
### v0.20.1 / 2021-12-01
|
96
100
|
|
97
|
-
* FIXED: [Instrumentation Rack] Log content type http header
|
98
|
-
* FIXED: Use monotonic clock where possible
|
99
|
-
* FIXED: Rack to stop using api env getter
|
101
|
+
* FIXED: [Instrumentation Rack] Log content type http header
|
102
|
+
* FIXED: Use monotonic clock where possible
|
103
|
+
* FIXED: Rack to stop using api env getter
|
100
104
|
|
101
105
|
### v0.20.0 / 2021-10-06
|
102
106
|
|
@@ -114,18 +118,18 @@ forwards the uri path. More details on this is available in the readme.
|
|
114
118
|
|
115
119
|
### v0.19.2 / 2021-08-18
|
116
120
|
|
117
|
-
* FIXED: Rack middleware assuming script_name presence
|
121
|
+
* FIXED: Rack middleware assuming script_name presence
|
118
122
|
|
119
123
|
### v0.19.1 / 2021-08-12
|
120
124
|
|
121
|
-
* DOCS: Update docs to rely more on environment variable configuration
|
125
|
+
* DOCS: Update docs to rely more on environment variable configuration
|
122
126
|
|
123
127
|
### v0.19.0 / 2021-06-23
|
124
128
|
|
125
|
-
* BREAKING CHANGE: Total order constraint on span.status=
|
129
|
+
* BREAKING CHANGE: Total order constraint on span.status=
|
126
130
|
|
127
|
-
* ADDED: Add Tracer.non_recording_span to API
|
128
|
-
* FIXED: Total order constraint on span.status=
|
131
|
+
* ADDED: Add Tracer.non_recording_span to API
|
132
|
+
* FIXED: Total order constraint on span.status=
|
129
133
|
|
130
134
|
### v0.18.0 / 2021-05-21
|
131
135
|
|
data/README.md
CHANGED
@@ -81,7 +81,7 @@ end
|
|
81
81
|
|
82
82
|
## Examples
|
83
83
|
|
84
|
-
Example usage can be seen in the `./example/trace_demonstration.rb` file
|
84
|
+
Example usage can be seen in the [`./example/trace_demonstration.rb` file](https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/instrumentation/rack/example/trace_demonstration.rb)
|
85
85
|
|
86
86
|
## How can I get involved?
|
87
87
|
|
@@ -101,3 +101,19 @@ The `opentelemetry-instrumentation-rack` gem is distributed under the Apache 2.0
|
|
101
101
|
[community-meetings]: https://github.com/open-telemetry/community#community-meetings
|
102
102
|
[slack-channel]: https://cloud-native.slack.com/archives/C01NWKKMKMY
|
103
103
|
[discussions-url]: https://github.com/open-telemetry/opentelemetry-ruby/discussions
|
104
|
+
|
105
|
+
## HTTP semantic convention stability
|
106
|
+
|
107
|
+
In the OpenTelemetry ecosystem, HTTP semantic conventions have now reached a stable state. However, the initial Rack instrumentation was introduced before this stability was achieved, which resulted in HTTP attributes being based on an older version of the semantic conventions.
|
108
|
+
|
109
|
+
To facilitate the migration to stable semantic conventions, you can use the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable. This variable allows you to opt-in to the new stable conventions, ensuring compatibility and future-proofing your instrumentation.
|
110
|
+
|
111
|
+
When setting the value for `OTEL_SEMCONV_STABILITY_OPT_IN`, you can specify which conventions you wish to adopt:
|
112
|
+
|
113
|
+
- `http` - Emits the stable HTTP and networking conventions and ceases emitting the old conventions previously emitted by the instrumentation.
|
114
|
+
- `http/dup` - Emits both the old and stable HTTP and networking conventions, enabling a phased rollout of the stable semantic conventions.
|
115
|
+
- Default behavior (in the absence of either value) is to continue emitting the old HTTP and networking conventions the instrumentation previously emitted.
|
116
|
+
|
117
|
+
During the transition from old to stable conventions, Rack instrumentation code comes in three patch versions: `dup`, `old`, and `stable`. These versions are identical except for the attributes they send. Any changes to Rack instrumentation should consider all three patches.
|
118
|
+
|
119
|
+
For additional information on migration, please refer to our [documentation](https://opentelemetry.io/docs/specs/semconv/non-normative/http-migration/).
|
@@ -13,7 +13,8 @@ module OpenTelemetry
|
|
13
13
|
# instrumentation
|
14
14
|
class Instrumentation < OpenTelemetry::Instrumentation::Base
|
15
15
|
install do |_config|
|
16
|
-
|
16
|
+
patch_type = determine_semconv
|
17
|
+
send(:"require_dependencies_#{patch_type}")
|
17
18
|
end
|
18
19
|
|
19
20
|
present do
|
@@ -40,18 +41,59 @@ module OpenTelemetry
|
|
40
41
|
# end
|
41
42
|
# @return [Array] consisting of a middleware and arguments used in rack builders
|
42
43
|
def middleware_args
|
43
|
-
if config.fetch(:use_rack_events, false) == true && defined?(OpenTelemetry::Instrumentation::Rack::Middlewares::EventHandler)
|
44
|
-
[::Rack::Events, [OpenTelemetry::Instrumentation::Rack::Middlewares::EventHandler.new]]
|
44
|
+
if config.fetch(:use_rack_events, false) == true && defined?(OpenTelemetry::Instrumentation::Rack::Middlewares::Old::EventHandler)
|
45
|
+
[::Rack::Events, [OpenTelemetry::Instrumentation::Rack::Middlewares::Old::EventHandler.new]]
|
45
46
|
else
|
46
|
-
[OpenTelemetry::Instrumentation::Rack::Middlewares::TracerMiddleware]
|
47
|
+
[OpenTelemetry::Instrumentation::Rack::Middlewares::Old::TracerMiddleware]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
alias middleware_args_old middleware_args
|
52
|
+
|
53
|
+
def middleware_args_dup
|
54
|
+
if config.fetch(:use_rack_events, false) == true && defined?(OpenTelemetry::Instrumentation::Rack::Middlewares::Dup::EventHandler)
|
55
|
+
[::Rack::Events, [OpenTelemetry::Instrumentation::Rack::Middlewares::Dup::EventHandler.new]]
|
56
|
+
else
|
57
|
+
[OpenTelemetry::Instrumentation::Rack::Middlewares::Dup::TracerMiddleware]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def middleware_args_stable
|
62
|
+
if config.fetch(:use_rack_events, false) == true && defined?(OpenTelemetry::Instrumentation::Rack::Middlewares::Stable::EventHandler)
|
63
|
+
[::Rack::Events, [OpenTelemetry::Instrumentation::Rack::Middlewares::Stable::EventHandler.new]]
|
64
|
+
else
|
65
|
+
[OpenTelemetry::Instrumentation::Rack::Middlewares::Stable::TracerMiddleware]
|
47
66
|
end
|
48
67
|
end
|
49
68
|
|
50
69
|
private
|
51
70
|
|
52
|
-
def
|
53
|
-
|
54
|
-
|
71
|
+
def determine_semconv
|
72
|
+
stability_opt_in = ENV.fetch('OTEL_SEMCONV_STABILITY_OPT_IN', '')
|
73
|
+
values = stability_opt_in.split(',').map(&:strip)
|
74
|
+
|
75
|
+
if values.include?('http/dup')
|
76
|
+
'dup'
|
77
|
+
elsif values.include?('http')
|
78
|
+
'stable'
|
79
|
+
else
|
80
|
+
'old'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def require_dependencies_old
|
85
|
+
require_relative 'middlewares/old/event_handler' if defined?(::Rack::Events)
|
86
|
+
require_relative 'middlewares/old/tracer_middleware'
|
87
|
+
end
|
88
|
+
|
89
|
+
def require_dependencies_stable
|
90
|
+
require_relative 'middlewares/stable/event_handler' if defined?(::Rack::Events)
|
91
|
+
require_relative 'middlewares/stable/tracer_middleware'
|
92
|
+
end
|
93
|
+
|
94
|
+
def require_dependencies_dup
|
95
|
+
require_relative 'middlewares/dup/event_handler' if defined?(::Rack::Events)
|
96
|
+
require_relative 'middlewares/dup/tracer_middleware'
|
55
97
|
end
|
56
98
|
|
57
99
|
def config_options(user_config)
|
@@ -0,0 +1,281 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright The OpenTelemetry Authors
|
4
|
+
#
|
5
|
+
# SPDX-License-Identifier: Apache-2.0
|
6
|
+
|
7
|
+
require_relative '../../util'
|
8
|
+
require 'opentelemetry/trace/status'
|
9
|
+
|
10
|
+
module OpenTelemetry
|
11
|
+
module Instrumentation
|
12
|
+
module Rack
|
13
|
+
module Middlewares
|
14
|
+
module Dup
|
15
|
+
# OTel Rack Event Handler
|
16
|
+
#
|
17
|
+
# This seeds the root context for this service with the server span as the `current_span`
|
18
|
+
# allowing for callers later in the stack to reference it using {OpenTelemetry::Trace.current_span}
|
19
|
+
#
|
20
|
+
# It also registers the server span in a context dedicated to this instrumentation that users may look up
|
21
|
+
# using {OpenTelemetry::Instrumentation::Rack.current_span}, which makes it possible for users to mutate the span,
|
22
|
+
# e.g. add events or update the span name like in the {ActionPack} instrumentation.
|
23
|
+
#
|
24
|
+
# @example Rack App Using BodyProxy
|
25
|
+
# GLOBAL_LOGGER = Logger.new($stderr)
|
26
|
+
# APP_TRACER = OpenTelemetry.tracer_provider.tracer('my-app', '1.0.0')
|
27
|
+
#
|
28
|
+
# Rack::Builder.new do
|
29
|
+
# use Rack::Events, [OpenTelemetry::Instrumentation::Rack::Middlewares::EventHandler.new]
|
30
|
+
# run lambda { |_arg|
|
31
|
+
# APP_TRACER.in_span('hello-world') do |_span|
|
32
|
+
# body = Rack::BodyProxy.new(['hello world!']) do
|
33
|
+
# rack_span = OpenTelemetry::Instrumentation::Rack.current_span
|
34
|
+
# GLOBAL_LOGGER.info("otel.trace_id=#{rack_span.context.hex_trace_id} otel.span_id=#{rack_span.context.hex_span_id}")
|
35
|
+
# end
|
36
|
+
# [200, { 'Content-Type' => 'text/plain' }, body]
|
37
|
+
# end
|
38
|
+
# }
|
39
|
+
# end
|
40
|
+
#
|
41
|
+
# @see Rack::Events
|
42
|
+
# @see OpenTelemetry::Instrumentation::Rack.current_span
|
43
|
+
class EventHandler
|
44
|
+
include ::Rack::Events::Abstract
|
45
|
+
|
46
|
+
OTEL_TOKEN_AND_SPAN = 'otel.rack.token_and_span'
|
47
|
+
EMPTY_HASH = {}.freeze
|
48
|
+
|
49
|
+
# Creates a server span for this current request using the incoming parent context
|
50
|
+
# and registers them as the {current_span}
|
51
|
+
#
|
52
|
+
# @param [Rack::Request] The current HTTP request
|
53
|
+
# @param [Rack::Response] This is nil in practice
|
54
|
+
# @return [void]
|
55
|
+
def on_start(request, _)
|
56
|
+
parent_context = if untraced_request?(request.env)
|
57
|
+
extract_remote_context(request, OpenTelemetry::Common::Utilities.untraced)
|
58
|
+
else
|
59
|
+
extract_remote_context(request)
|
60
|
+
end
|
61
|
+
|
62
|
+
span = create_span(parent_context, request)
|
63
|
+
span_ctx = OpenTelemetry::Trace.context_with_span(span, parent_context: parent_context)
|
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]
|
66
|
+
rescue StandardError => e
|
67
|
+
OpenTelemetry.handle_error(exception: e)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Optionally adds debugging response headers injected from {response_propagators}
|
71
|
+
#
|
72
|
+
# @param [Rack::Request] The current HTTP request
|
73
|
+
# @param [Rack::Response] This current HTTP response
|
74
|
+
# @return [void]
|
75
|
+
def on_commit(request, response)
|
76
|
+
span = OpenTelemetry::Instrumentation::Rack.current_span
|
77
|
+
return unless span.recording?
|
78
|
+
|
79
|
+
response_propagators&.each do |propagator|
|
80
|
+
propagator.inject(response.headers)
|
81
|
+
rescue StandardError => e
|
82
|
+
OpenTelemetry.handle_error(message: 'Unable to inject response propagation headers', exception: e)
|
83
|
+
end
|
84
|
+
rescue StandardError => e
|
85
|
+
OpenTelemetry.handle_error(exception: e)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Records Unexpected Exceptions on the Rack span and set the Span Status to Error
|
89
|
+
#
|
90
|
+
# @note does nothing if the span is a non-recording span
|
91
|
+
# @param [Rack::Request] The current HTTP request
|
92
|
+
# @param [Rack::Response] The current HTTP response
|
93
|
+
# @param [Exception] An unxpected error raised by the application
|
94
|
+
def on_error(request, _, error)
|
95
|
+
span = OpenTelemetry::Instrumentation::Rack.current_span
|
96
|
+
return unless span.recording?
|
97
|
+
|
98
|
+
span.record_exception(error)
|
99
|
+
span.status = OpenTelemetry::Trace::Status.error(error.class.name)
|
100
|
+
rescue StandardError => e
|
101
|
+
OpenTelemetry.handle_error(exception: e)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Finishes the span making it eligible to be exported and cleans up existing contexts
|
105
|
+
#
|
106
|
+
# @note does nothing if the span is a non-recording span
|
107
|
+
# @param [Rack::Request] The current HTTP request
|
108
|
+
# @param [Rack::Response] The current HTTP response
|
109
|
+
def on_finish(request, response)
|
110
|
+
span = OpenTelemetry::Instrumentation::Rack.current_span
|
111
|
+
return unless span.recording?
|
112
|
+
|
113
|
+
add_response_attributes(span, response) if response
|
114
|
+
rescue StandardError => e
|
115
|
+
OpenTelemetry.handle_error(exception: e)
|
116
|
+
ensure
|
117
|
+
detach_context(request)
|
118
|
+
end
|
119
|
+
|
120
|
+
private
|
121
|
+
|
122
|
+
def extract_request_headers(env)
|
123
|
+
return EMPTY_HASH if allowed_request_headers.empty?
|
124
|
+
|
125
|
+
allowed_request_headers.each_with_object({}) do |(key, value), result|
|
126
|
+
result[value] = env[key] if env.key?(key)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def extract_response_attributes(response)
|
131
|
+
attributes = {
|
132
|
+
'http.status_code' => response.status.to_i,
|
133
|
+
'http.response.status_code' => response.status.to_i
|
134
|
+
}
|
135
|
+
attributes.merge!(extract_response_headers(response.headers))
|
136
|
+
attributes
|
137
|
+
end
|
138
|
+
|
139
|
+
def extract_response_headers(headers)
|
140
|
+
return EMPTY_HASH if allowed_response_headers.empty?
|
141
|
+
|
142
|
+
allowed_response_headers.each_with_object({}) do |(key, value), result|
|
143
|
+
if headers.key?(key)
|
144
|
+
result[value] = headers[key]
|
145
|
+
else
|
146
|
+
# do case-insensitive match:
|
147
|
+
headers.each do |k, v|
|
148
|
+
if k.upcase == key
|
149
|
+
result[value] = v
|
150
|
+
break
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def untraced_request?(env)
|
158
|
+
return true if untraced_endpoints.include?(env['PATH_INFO'])
|
159
|
+
return true if untraced_requests&.call(env)
|
160
|
+
|
161
|
+
false
|
162
|
+
end
|
163
|
+
|
164
|
+
# https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/data-http.md#name
|
165
|
+
#
|
166
|
+
# recommendation: span.name(s) should be low-cardinality (e.g.,
|
167
|
+
# strip off query param value, keep param name)
|
168
|
+
#
|
169
|
+
# see http://github.com/open-telemetry/opentelemetry-specification/pull/416/files
|
170
|
+
def create_request_span_name(request)
|
171
|
+
# NOTE: dd-trace-rb has implemented 'quantization' (which lowers url cardinality)
|
172
|
+
# see Datadog::Quantization::HTTP.url
|
173
|
+
|
174
|
+
if (implementation = url_quantization)
|
175
|
+
request_uri_or_path_info = request.env['REQUEST_URI'] || request.path_info
|
176
|
+
implementation.call(request_uri_or_path_info, request.env)
|
177
|
+
else
|
178
|
+
request.request_method.to_s
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
def extract_remote_context(request, context = Context.current)
|
183
|
+
OpenTelemetry.propagation.extract(
|
184
|
+
request.env,
|
185
|
+
context: context,
|
186
|
+
getter: OpenTelemetry::Common::Propagation.rack_env_getter
|
187
|
+
)
|
188
|
+
end
|
189
|
+
|
190
|
+
def request_span_attributes(env)
|
191
|
+
attributes = {
|
192
|
+
'http.method' => env['REQUEST_METHOD'],
|
193
|
+
'http.host' => env['HTTP_HOST'] || 'unknown',
|
194
|
+
'server.address' => env['HTTP_HOST'] || 'unknown',
|
195
|
+
'http.scheme' => env['rack.url_scheme'],
|
196
|
+
'http.target' => env['QUERY_STRING'].empty? ? env['PATH_INFO'] : "#{env['PATH_INFO']}?#{env['QUERY_STRING']}",
|
197
|
+
'http.request.method' => env['REQUEST_METHOD'],
|
198
|
+
'url.scheme' => env['rack.url_scheme'],
|
199
|
+
'url.path' => env['PATH_INFO']
|
200
|
+
}
|
201
|
+
|
202
|
+
attributes['url.query'] = env['QUERY_STRING'] unless env['QUERY_STRING'].empty?
|
203
|
+
if env['HTTP_USER_AGENT']
|
204
|
+
attributes['http.user_agent'] = env['HTTP_USER_AGENT']
|
205
|
+
attributes['user_agent.original'] = env['HTTP_USER_AGENT']
|
206
|
+
end
|
207
|
+
attributes.merge!(extract_request_headers(env))
|
208
|
+
attributes
|
209
|
+
end
|
210
|
+
|
211
|
+
def detach_context(request)
|
212
|
+
return nil unless request.env[OTEL_TOKEN_AND_SPAN]
|
213
|
+
|
214
|
+
token, span = request.env[OTEL_TOKEN_AND_SPAN]
|
215
|
+
span.finish
|
216
|
+
OpenTelemetry::Context.detach(token)
|
217
|
+
rescue StandardError => e
|
218
|
+
OpenTelemetry.handle_error(exception: e)
|
219
|
+
end
|
220
|
+
|
221
|
+
def add_response_attributes(span, response)
|
222
|
+
span.status = OpenTelemetry::Trace::Status.error if response.server_error?
|
223
|
+
attributes = extract_response_attributes(response)
|
224
|
+
span.add_attributes(attributes)
|
225
|
+
rescue StandardError => e
|
226
|
+
OpenTelemetry.handle_error(exception: e)
|
227
|
+
end
|
228
|
+
|
229
|
+
def record_frontend_span?
|
230
|
+
config[:record_frontend_span] == true
|
231
|
+
end
|
232
|
+
|
233
|
+
def untraced_endpoints
|
234
|
+
config[:untraced_endpoints]
|
235
|
+
end
|
236
|
+
|
237
|
+
def untraced_requests
|
238
|
+
config[:untraced_requests]
|
239
|
+
end
|
240
|
+
|
241
|
+
def url_quantization
|
242
|
+
config[:url_quantization]
|
243
|
+
end
|
244
|
+
|
245
|
+
def response_propagators
|
246
|
+
config[:response_propagators]
|
247
|
+
end
|
248
|
+
|
249
|
+
def allowed_request_headers
|
250
|
+
config[:allowed_rack_request_headers]
|
251
|
+
end
|
252
|
+
|
253
|
+
def allowed_response_headers
|
254
|
+
config[:allowed_rack_response_headers]
|
255
|
+
end
|
256
|
+
|
257
|
+
def tracer
|
258
|
+
OpenTelemetry::Instrumentation::Rack::Instrumentation.instance.tracer
|
259
|
+
end
|
260
|
+
|
261
|
+
def config
|
262
|
+
OpenTelemetry::Instrumentation::Rack::Instrumentation.instance.config
|
263
|
+
end
|
264
|
+
|
265
|
+
def create_span(parent_context, request)
|
266
|
+
span = tracer.start_span(
|
267
|
+
create_request_span_name(request),
|
268
|
+
with_parent: parent_context,
|
269
|
+
kind: :server,
|
270
|
+
attributes: request_span_attributes(request.env)
|
271
|
+
)
|
272
|
+
request_start_time = OpenTelemetry::Instrumentation::Rack::Util::QueueTime.get_request_start(request.env)
|
273
|
+
span.add_event('http.proxy.request.started', timestamp: request_start_time) unless request_start_time.nil?
|
274
|
+
span
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
281
|
+
end
|