Skip to content

Commit 49a2982

Browse files
feat: Rack semantic stability opt in (#1594)
* feat: Rack semantic stability opt in * fix: add readme and rubocop fix * fix: rubocp edits * Apply suggestions from code review Co-authored-by: Kayla Reopelle <[email protected]> * Fix: Add Sinatra documentation & small refactor * Fix: spelling * Fix: refactors * Test middleware_args_* * Fix: rubocop * Sinatra testing * rubocop * alias middleware_args middleware_args_old * appease rubocop * revert grape changes * Update action_pack to use middleware alias * Rely on Rack semconv middlware alias for Sinatra instrumentation * Update action_pack changelog --------- Co-authored-by: Kayla Reopelle <[email protected]>
1 parent a9ff3d9 commit 49a2982

30 files changed

+4080
-517
lines changed

instrumentation/action_pack/README.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,21 @@ The `opentelemetry-instrumentation-action_pack` gem is distributed under the Apa
8989
[slack-channel]: https://cloud-native.slack.com/archives/C01NWKKMKMY
9090
[discussions-url]: https://github.com/open-telemetry/opentelemetry-ruby/discussions
9191
[rails-home]: https://rubyonrails.org/
92+
93+
## HTTP semantic convention stability
94+
95+
In the OpenTelemetry ecosystem, HTTP semantic conventions have now reached a stable state. However, the initial Rack instrumentation, which Action Pack relies on, was introduced before this stability was achieved, which resulted in HTTP attributes being based on an older version of the semantic conventions.
96+
97+
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.
98+
99+
Sinatra instrumentation installs Rack middleware, but the middleware version it installs depends on which `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable is set.
100+
101+
When setting the value for `OTEL_SEMCONV_STABILITY_OPT_IN`, you can specify which conventions you wish to adopt:
102+
103+
- `http` - Emits the stable HTTP and networking conventions and ceases emitting the old conventions previously emitted by the instrumentation.
104+
- `http/dup` - Emits both the old and stable HTTP and networking conventions, enabling a phased rollout of the stable semantic conventions.
105+
- Default behavior (in the absence of either value) is to continue emitting the old HTTP and networking conventions the instrumentation previously emitted.
106+
107+
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.
108+
109+
For additional information on migration, please refer to our [documentation](https://opentelemetry.io/docs/specs/semconv/non-normative/http-migration/).

instrumentation/action_pack/lib/opentelemetry/instrumentation/action_pack/railtie.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,20 @@ class Railtie < ::Rails::Railtie
1212
config.before_initialize do |app|
1313
OpenTelemetry::Instrumentation::Rack::Instrumentation.instance.install({})
1414

15+
stability_opt_in = ENV.fetch('OTEL_SEMCONV_STABILITY_OPT_IN', '')
16+
values = stability_opt_in.split(',').map(&:strip)
17+
18+
rack_middleware_args = if values.include?('http/dup')
19+
OpenTelemetry::Instrumentation::Rack::Instrumentation.instance.middleware_args_dup
20+
elsif values.include?('http')
21+
OpenTelemetry::Instrumentation::Rack::Instrumentation.instance.middleware_args_stable
22+
else
23+
OpenTelemetry::Instrumentation::Rack::Instrumentation.instance.middleware_args
24+
end
25+
1526
app.middleware.insert_before(
1627
0,
17-
*OpenTelemetry::Instrumentation::Rack::Instrumentation.instance.middleware_args
28+
*rack_middleware_args
1829
)
1930
end
2031
end

instrumentation/rack/Appraisals

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,31 @@
44
#
55
# SPDX-License-Identifier: Apache-2.0
66

7-
appraise 'rack-latest' do
8-
gem 'rack'
9-
end
7+
# To faclitate HTTP semantic convention stability migration, we are using
8+
# appraisal to test the different semantic convention modes along with different
9+
# HTTP gem versions. For more information on the semantic convention modes, see:
10+
# https://opentelemetry.io/docs/specs/semconv/non-normative/http-migration/
1011

11-
appraise 'rack-3.0' do
12-
gem 'rack', '~> 3.0.0'
13-
end
12+
semconv_stability = %w[stable old dup]
1413

15-
appraise 'rack-2.2.x' do
16-
gem 'rack', '~> 2.2.0'
17-
end
14+
semconv_stability.each do |mode|
15+
appraise "rack-latest-#{mode}" do
16+
gem 'rack'
17+
end
1818

19-
appraise 'rack-2.1' do
20-
gem 'rack', '~> 2.1.2'
21-
end
19+
appraise "rack-3.0-#{mode}" do
20+
gem 'rack', '~> 3.0.0'
21+
end
22+
23+
appraise "rack-2.2.x-#{mode}" do
24+
gem 'rack', '~> 2.2.0'
25+
end
26+
27+
appraise "rack-2.1-#{mode}" do
28+
gem 'rack', '~> 2.1.2'
29+
end
2230

23-
appraise 'rack-2.0' do
24-
gem 'rack', '~> 2.0.8'
31+
appraise "rack-2.0-#{mode}" do
32+
gem 'rack', '~> 2.0.8'
33+
end
2534
end

instrumentation/rack/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,19 @@ The `opentelemetry-instrumentation-rack` gem is distributed under the Apache 2.0
101101
[community-meetings]: https://github.com/open-telemetry/community#community-meetings
102102
[slack-channel]: https://cloud-native.slack.com/archives/C01NWKKMKMY
103103
[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/).

instrumentation/rack/lib/opentelemetry/instrumentation/rack/instrumentation.rb

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ module Rack
1313
# instrumentation
1414
class Instrumentation < OpenTelemetry::Instrumentation::Base
1515
install do |_config|
16-
require_dependencies
16+
patch_type = determine_semconv
17+
send(:"require_dependencies_#{patch_type}")
1718
end
1819

1920
present do
@@ -40,18 +41,59 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base
4041
# end
4142
# @return [Array] consisting of a middleware and arguments used in rack builders
4243
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]]
4546
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]
4766
end
4867
end
4968

5069
private
5170

52-
def require_dependencies
53-
require_relative 'middlewares/event_handler' if defined?(::Rack::Events)
54-
require_relative 'middlewares/tracer_middleware'
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'
5597
end
5698

5799
def config_options(user_config)

0 commit comments

Comments
 (0)