opentelemetry-instrumentation-ethon 0.25.0 → 0.25.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: 6b4ba483850fecd8e420adf8348dad13af09dd635665c5ce00ed170f07ad180f
4
- data.tar.gz: cfa2c41fc678ec3abe0e632d091547a58838e0fb12cacea83bafe7cd673c3b44
3
+ metadata.gz: e3d38acddca75c32c85aebe769251385e75afb4dd29f8ec503d73ed7787b80fb
4
+ data.tar.gz: 1f25008d580e084be409e52d4f801607ac6a2ad98484e02b4308fa8286147239
5
5
  SHA512:
6
- metadata.gz: e3908ca6cc0d5ea9bb08fa3abe4e04c53c7861cc2eb1a5c3331719d038406f50e0049a8353d6ae8dc14cf91fdc108d019b7b3ca928d339af21f6269663eb56d1
7
- data.tar.gz: 3018b5eec90868aa9cf7de2fa021feb6b335b0132dd898bd7e7882a342c17264165011fae39acf8d386764fbfd549af6d070955f7bc21565e5c97a7c988dada4
6
+ metadata.gz: 18b0937bcec74c6fbb8bd6dc7702958fba3375e9a1b7275ab670e2da60e00f0fd6f9c61de451504517b305758301d240033e2e139f89c23f11f73c537f1c12b3
7
+ data.tar.gz: efea330186112910e18e02928c816b4191d11fb264c162211b45f54434517425a2f02e7c14dab3d1d6ea0923359d7922a12cb97ae69490a7e4c82b8608c4edf2
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Release History: opentelemetry-instrumentation-ethon
2
2
 
3
+ ### v0.25.1 / 2025-11-25
4
+
5
+ * FIXED: Update support for unknown HTTP methods to match semantic conventions
6
+
3
7
  ### v0.25.0 / 2025-10-22
4
8
 
5
9
  * BREAKING CHANGE: Min Ruby Version 3.2
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright The OpenTelemetry Authors
4
+ #
5
+ # SPDX-License-Identifier: Apache-2.0
6
+
7
+ module OpenTelemetry
8
+ module Instrumentation
9
+ module Ethon
10
+ # Helper module for HTTP method normalization
11
+ # @api private
12
+ module HttpHelper
13
+ # Lightweight struct to hold span creation attributes
14
+ SpanCreationAttributes = Struct.new(:span_name, :normalized_method, :original_method, keyword_init: true)
15
+
16
+ # Pre-computed mapping to avoid string allocations during normalization
17
+ METHOD_CACHE = {
18
+ 'CONNECT' => 'CONNECT',
19
+ 'DELETE' => 'DELETE',
20
+ 'GET' => 'GET',
21
+ 'HEAD' => 'HEAD',
22
+ 'OPTIONS' => 'OPTIONS',
23
+ 'PATCH' => 'PATCH',
24
+ 'POST' => 'POST',
25
+ 'PUT' => 'PUT',
26
+ 'TRACE' => 'TRACE',
27
+ 'connect' => 'CONNECT',
28
+ 'delete' => 'DELETE',
29
+ 'get' => 'GET',
30
+ 'head' => 'HEAD',
31
+ 'options' => 'OPTIONS',
32
+ 'patch' => 'PATCH',
33
+ 'post' => 'POST',
34
+ 'put' => 'PUT',
35
+ 'trace' => 'TRACE',
36
+ :connect => 'CONNECT',
37
+ :delete => 'DELETE',
38
+ :get => 'GET',
39
+ :head => 'HEAD',
40
+ :options => 'OPTIONS',
41
+ :patch => 'PATCH',
42
+ :post => 'POST',
43
+ :put => 'PUT',
44
+ :trace => 'TRACE'
45
+ }.freeze
46
+
47
+ # Pre-computed span names for old semantic conventions to avoid allocations
48
+ OLD_SPAN_NAMES = {
49
+ 'CONNECT' => 'HTTP CONNECT',
50
+ 'DELETE' => 'HTTP DELETE',
51
+ 'GET' => 'HTTP GET',
52
+ 'HEAD' => 'HTTP HEAD',
53
+ 'OPTIONS' => 'HTTP OPTIONS',
54
+ 'PATCH' => 'HTTP PATCH',
55
+ 'POST' => 'HTTP POST',
56
+ 'PUT' => 'HTTP PUT',
57
+ 'TRACE' => 'HTTP TRACE'
58
+ }.freeze
59
+
60
+ private_constant :METHOD_CACHE, :OLD_SPAN_NAMES
61
+
62
+ # Prepares all span data for the specified semantic convention in a single call
63
+ # @param method [String, Symbol] The HTTP method
64
+ # @param semconv [Symbol] The semantic convention to use (:stable or :old)
65
+ # @return [SpanCreationAttributes] struct containing span_name, normalized_method, and original_method
66
+ def self.span_attrs_for(method, semconv: :stable)
67
+ normalized = METHOD_CACHE[method]
68
+ if normalized
69
+ span_name = semconv == :old ? OLD_SPAN_NAMES[normalized] : normalized
70
+ SpanCreationAttributes.new(
71
+ span_name: span_name,
72
+ normalized_method: normalized,
73
+ original_method: nil
74
+ )
75
+ else
76
+ SpanCreationAttributes.new(
77
+ span_name: semconv == :old ? 'HTTP N/A' : 'HTTP',
78
+ normalized_method: '_OTHER',
79
+ original_method: method.to_s
80
+ )
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -12,20 +12,11 @@ module OpenTelemetry
12
12
  module Dup
13
13
  # Ethon::Easy patch for instrumentation
14
14
  module Easy
15
- ACTION_NAMES_TO_HTTP_METHODS = Hash.new do |h, k|
16
- # #to_s is required because user input could be symbol or string
17
- h[k] = k.to_s.upcase
18
- end
19
- HTTP_METHODS_TO_SPAN_NAMES = Hash.new do |h, k|
20
- h[k] = k.to_s
21
- h[k] = 'HTTP' if k == '_OTHER'
22
- end
23
-
24
15
  # Constant for the HTTP status range
25
16
  HTTP_STATUS_SUCCESS_RANGE = (100..399)
26
17
 
27
18
  def http_request(url, action_name, options = {})
28
- @otel_method = ACTION_NAMES_TO_HTTP_METHODS[action_name]
19
+ @otel_method = action_name
29
20
  super
30
21
  end
31
22
 
@@ -77,12 +68,11 @@ module OpenTelemetry
77
68
  end
78
69
 
79
70
  def otel_before_request
80
- method = '_OTHER' # Could be GET or not HTTP at all
81
- method = @otel_method if instance_variable_defined?(:@otel_method) && !@otel_method.nil?
71
+ span_data = HttpHelper.span_attrs_for(@otel_method)
82
72
 
83
73
  @otel_span = tracer.start_span(
84
- HTTP_METHODS_TO_SPAN_NAMES[method],
85
- attributes: span_creation_attributes(method),
74
+ span_data.span_name,
75
+ attributes: span_creation_attributes(span_data),
86
76
  kind: :client
87
77
  )
88
78
 
@@ -99,12 +89,12 @@ module OpenTelemetry
99
89
 
100
90
  private
101
91
 
102
- def span_creation_attributes(method)
103
- http_method = (method == '_OTHER' ? 'N/A' : method)
92
+ def span_creation_attributes(span_data)
104
93
  instrumentation_attrs = {
105
- 'http.method' => http_method,
106
- 'http.request.method' => method
94
+ 'http.method' => span_data.normalized_method,
95
+ 'http.request.method' => span_data.normalized_method
107
96
  }
97
+ instrumentation_attrs['http.request.method_original'] = span_data.original_method if span_data.original_method
108
98
 
109
99
  uri = _otel_cleanse_uri(url)
110
100
  if uri
@@ -12,17 +12,11 @@ module OpenTelemetry
12
12
  module Old
13
13
  # Ethon::Easy patch for instrumentation
14
14
  module Easy
15
- ACTION_NAMES_TO_HTTP_METHODS = Hash.new do |h, k|
16
- # #to_s is required because user input could be symbol or string
17
- h[k] = k.to_s.upcase
18
- end
19
- HTTP_METHODS_TO_SPAN_NAMES = Hash.new { |h, k| h[k] = "HTTP #{k}" }
20
-
21
15
  # Constant for the HTTP status range
22
16
  HTTP_STATUS_SUCCESS_RANGE = (100..399)
23
17
 
24
18
  def http_request(url, action_name, options = {})
25
- @otel_method = ACTION_NAMES_TO_HTTP_METHODS[action_name]
19
+ @otel_method = action_name
26
20
  super
27
21
  end
28
22
 
@@ -73,12 +67,11 @@ module OpenTelemetry
73
67
  end
74
68
 
75
69
  def otel_before_request
76
- method = 'N/A' # Could be GET or not HTTP at all
77
- method = @otel_method if instance_variable_defined?(:@otel_method) && !@otel_method.nil?
70
+ span_data = HttpHelper.span_attrs_for(@otel_method, semconv: :old)
78
71
 
79
72
  @otel_span = tracer.start_span(
80
- HTTP_METHODS_TO_SPAN_NAMES[method],
81
- attributes: span_creation_attributes(method),
73
+ span_data.span_name,
74
+ attributes: span_creation_attributes(span_data),
82
75
  kind: :client
83
76
  )
84
77
 
@@ -95,9 +88,9 @@ module OpenTelemetry
95
88
 
96
89
  private
97
90
 
98
- def span_creation_attributes(method)
91
+ def span_creation_attributes(span_data)
99
92
  instrumentation_attrs = {
100
- 'http.method' => method
93
+ 'http.method' => span_data.normalized_method
101
94
  }
102
95
 
103
96
  uri = _otel_cleanse_uri(url)
@@ -12,20 +12,11 @@ module OpenTelemetry
12
12
  module Stable
13
13
  # Ethon::Easy patch for instrumentation
14
14
  module Easy
15
- ACTION_NAMES_TO_HTTP_METHODS = Hash.new do |h, k|
16
- # #to_s is required because user input could be symbol or string
17
- h[k] = k.to_s.upcase
18
- end
19
- HTTP_METHODS_TO_SPAN_NAMES = Hash.new do |h, k|
20
- h[k] = k.to_s
21
- h[k] = 'HTTP' if k == '_OTHER'
22
- end
23
-
24
15
  # Constant for the HTTP status range
25
16
  HTTP_STATUS_SUCCESS_RANGE = (100..399)
26
17
 
27
18
  def http_request(url, action_name, options = {})
28
- @otel_method = ACTION_NAMES_TO_HTTP_METHODS[action_name]
19
+ @otel_method = action_name
29
20
  super
30
21
  end
31
22
 
@@ -76,12 +67,11 @@ module OpenTelemetry
76
67
  end
77
68
 
78
69
  def otel_before_request
79
- method = '_OTHER' # Could be GET or not HTTP at all
80
- method = @otel_method if instance_variable_defined?(:@otel_method) && !@otel_method.nil?
70
+ span_data = HttpHelper.span_attrs_for(@otel_method)
81
71
 
82
72
  @otel_span = tracer.start_span(
83
- HTTP_METHODS_TO_SPAN_NAMES[method],
84
- attributes: span_creation_attributes(method),
73
+ span_data.span_name,
74
+ attributes: span_creation_attributes(span_data),
85
75
  kind: :client
86
76
  )
87
77
 
@@ -98,10 +88,11 @@ module OpenTelemetry
98
88
 
99
89
  private
100
90
 
101
- def span_creation_attributes(method)
91
+ def span_creation_attributes(span_data)
102
92
  instrumentation_attrs = {
103
- 'http.request.method' => method
93
+ 'http.request.method' => span_data.normalized_method
104
94
  }
95
+ instrumentation_attrs['http.request.method_original'] = span_data.original_method if span_data.original_method
105
96
 
106
97
  uri = _otel_cleanse_uri(url)
107
98
  if uri
@@ -7,7 +7,7 @@
7
7
  module OpenTelemetry
8
8
  module Instrumentation
9
9
  module Ethon
10
- VERSION = '0.25.0'
10
+ VERSION = '0.25.1'
11
11
  end
12
12
  end
13
13
  end
@@ -15,5 +15,6 @@ module OpenTelemetry
15
15
  end
16
16
  end
17
17
 
18
+ require_relative 'ethon/http_helper'
18
19
  require_relative 'ethon/instrumentation'
19
20
  require_relative 'ethon/version'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentelemetry-instrumentation-ethon
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.25.0
4
+ version: 0.25.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTelemetry Authors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-10-22 00:00:00.000000000 Z
11
+ date: 2025-11-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: opentelemetry-instrumentation-base
@@ -38,6 +38,7 @@ files:
38
38
  - lib/opentelemetry-instrumentation-ethon.rb
39
39
  - lib/opentelemetry/instrumentation.rb
40
40
  - lib/opentelemetry/instrumentation/ethon.rb
41
+ - lib/opentelemetry/instrumentation/ethon/http_helper.rb
41
42
  - lib/opentelemetry/instrumentation/ethon/instrumentation.rb
42
43
  - lib/opentelemetry/instrumentation/ethon/patches/dup/easy.rb
43
44
  - lib/opentelemetry/instrumentation/ethon/patches/multi.rb
@@ -48,10 +49,10 @@ homepage: https://github.com/open-telemetry/opentelemetry-ruby-contrib
48
49
  licenses:
49
50
  - Apache-2.0
50
51
  metadata:
51
- changelog_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-ethon/0.25.0/file/CHANGELOG.md
52
+ changelog_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-ethon/0.25.1/file/CHANGELOG.md
52
53
  source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation/ethon
53
54
  bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/issues
54
- documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-ethon/0.25.0
55
+ documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-ethon/0.25.1
55
56
  post_install_message:
56
57
  rdoc_options: []
57
58
  require_paths: