opentelemetry-instrumentation-excon 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 +8 -0
- data/README.md +1 -2
- data/lib/opentelemetry/instrumentation/excon/http_helper.rb +134 -0
- data/lib/opentelemetry/instrumentation/excon/middlewares/dup/tracer_middleware.rb +4 -16
- data/lib/opentelemetry/instrumentation/excon/middlewares/old/tracer_middleware.rb +4 -15
- data/lib/opentelemetry/instrumentation/excon/middlewares/stable/tracer_middleware.rb +9 -22
- data/lib/opentelemetry/instrumentation/excon/version.rb +1 -1
- data/lib/opentelemetry/instrumentation/excon.rb +1 -0
- metadata +5 -4
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 56072eb6e3eb2dc4a87e0d792c504d99c7b8846cdc7a4ec346552b03da298edf
|
|
4
|
+
data.tar.gz: 50015488653810bc9aa10318ff028852f7a470ba2b4b6089491fe16c50767e9b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0ea4be43d901a377d226b16b71bffcf3fdb30e418019d55757f572ac58496c281099fdfa87827266acc6cacdd654b1148241beaa934947b81850bb78a204eb95
|
|
7
|
+
data.tar.gz: 1fb3ca5e68f13767cf1b432e43c6e3577a2677d4667e8e801264baf5d37a60a29b26f133ca967f6089189beec5d7c634a3f41692abb816f51a93dcfc18850a64
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Release History: opentelemetry-instrumentation-excon
|
|
2
2
|
|
|
3
|
+
### v0.27.0 / 2026-01-13
|
|
4
|
+
|
|
5
|
+
* ADDED: HTTP Client Semconv v1.17 Span Naming
|
|
6
|
+
|
|
7
|
+
### v0.26.1 / 2025-11-25
|
|
8
|
+
|
|
9
|
+
* FIXED: Update support for unknown HTTP methods to match semantic conventions
|
|
10
|
+
|
|
3
11
|
### v0.26.0 / 2025-10-22
|
|
4
12
|
|
|
5
13
|
* BREAKING CHANGE: Min Ruby Version 3.2
|
data/README.md
CHANGED
|
@@ -49,7 +49,6 @@ The `opentelemetry-instrumentation-all` gem is distributed under the Apache 2.0
|
|
|
49
49
|
[slack-channel]: https://cloud-native.slack.com/archives/C01NWKKMKMY
|
|
50
50
|
[discussions-url]: https://github.com/open-telemetry/opentelemetry-ruby/discussions
|
|
51
51
|
|
|
52
|
-
|
|
53
52
|
## HTTP semantic convention stability
|
|
54
53
|
|
|
55
54
|
In the OpenTelemetry ecosystem, HTTP semantic conventions have now reached a stable state. However, the initial Excon instrumentation was introduced before this stability was achieved, which resulted in HTTP attributes being based on an older version of the semantic conventions.
|
|
@@ -64,4 +63,4 @@ When setting the value for `OTEL_SEMCONV_STABILITY_OPT_IN`, you can specify whic
|
|
|
64
63
|
|
|
65
64
|
During the transition from old to stable conventions, Excon instrumentation code comes in three patch versions: `dup`, `old`, and `stable`. These versions are identical except for the attributes they send. Any changes to Excon instrumentation should consider all three patches.
|
|
66
65
|
|
|
67
|
-
For additional information on migration, please refer to our [documentation](https://opentelemetry.io/docs/specs/semconv/non-normative/http-migration/).
|
|
66
|
+
For additional information on migration, please refer to our [documentation](https://opentelemetry.io/docs/specs/semconv/non-normative/http-migration/).
|
|
@@ -0,0 +1,134 @@
|
|
|
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 Excon
|
|
10
|
+
# Utility module for HTTP-related helper methods
|
|
11
|
+
# @api private
|
|
12
|
+
module HttpHelper
|
|
13
|
+
# Lightweight struct to hold span creation data
|
|
14
|
+
SpanCreationAttributes = Struct.new(:span_name, :attributes, 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
|
+
private_constant :METHOD_CACHE
|
|
48
|
+
|
|
49
|
+
OLD_SPAN_NAMES_BY_METHOD = METHOD_CACHE.values.uniq.each_with_object({}) do |method, hash|
|
|
50
|
+
hash[method] = "HTTP #{method}"
|
|
51
|
+
end.freeze
|
|
52
|
+
|
|
53
|
+
private_constant :OLD_SPAN_NAMES_BY_METHOD
|
|
54
|
+
|
|
55
|
+
# Prepares span data using old semantic conventions
|
|
56
|
+
# @param method [String, Symbol] The HTTP method
|
|
57
|
+
# @return [SpanCreationAttributes] struct containing span_name and attributes hash
|
|
58
|
+
def self.span_attrs_for_old(method)
|
|
59
|
+
client_context_attrs = OpenTelemetry::Common::HTTP::ClientContext.attributes
|
|
60
|
+
normalized = METHOD_CACHE[method]
|
|
61
|
+
attributes = client_context_attrs.dup
|
|
62
|
+
|
|
63
|
+
# Determine base span name and method value
|
|
64
|
+
if normalized
|
|
65
|
+
span_name = OLD_SPAN_NAMES_BY_METHOD[normalized]
|
|
66
|
+
method_value = normalized
|
|
67
|
+
else
|
|
68
|
+
span_name = 'HTTP'
|
|
69
|
+
method_value = '_OTHER'
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
attributes['http.method'] ||= method_value
|
|
73
|
+
|
|
74
|
+
SpanCreationAttributes.new(span_name: span_name, attributes: attributes)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Prepares span data using stable semantic conventions
|
|
78
|
+
# @param method [String, Symbol] The HTTP method
|
|
79
|
+
# @return [SpanCreationAttributes] struct containing span_name and attributes hash
|
|
80
|
+
def self.span_attrs_for_stable(method)
|
|
81
|
+
client_context_attrs = OpenTelemetry::Common::HTTP::ClientContext.attributes
|
|
82
|
+
url_template = client_context_attrs['url.template']
|
|
83
|
+
normalized = METHOD_CACHE[method]
|
|
84
|
+
attributes = client_context_attrs.dup
|
|
85
|
+
|
|
86
|
+
# Determine base span name and method value
|
|
87
|
+
if normalized
|
|
88
|
+
base_name = normalized
|
|
89
|
+
method_value = normalized
|
|
90
|
+
original = nil
|
|
91
|
+
else
|
|
92
|
+
base_name = 'HTTP'
|
|
93
|
+
method_value = '_OTHER'
|
|
94
|
+
original = method.to_s
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
span_name = url_template ? "#{base_name} #{url_template}" : base_name
|
|
98
|
+
attributes['http.request.method'] ||= method_value
|
|
99
|
+
attributes['http.request.method_original'] ||= original if original
|
|
100
|
+
|
|
101
|
+
SpanCreationAttributes.new(span_name: span_name, attributes: attributes)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# Prepares span data using both old and stable semantic conventions
|
|
105
|
+
# @param method [String, Symbol] The HTTP method
|
|
106
|
+
# @return [SpanCreationAttributes] struct containing span_name and attributes hash
|
|
107
|
+
def self.span_attrs_for_dup(method)
|
|
108
|
+
client_context_attrs = OpenTelemetry::Common::HTTP::ClientContext.attributes
|
|
109
|
+
url_template = client_context_attrs['url.template']
|
|
110
|
+
normalized = METHOD_CACHE[method]
|
|
111
|
+
attributes = client_context_attrs.dup
|
|
112
|
+
|
|
113
|
+
# Determine base span name and method value
|
|
114
|
+
if normalized
|
|
115
|
+
base_name = normalized
|
|
116
|
+
method_value = normalized
|
|
117
|
+
original = nil
|
|
118
|
+
else
|
|
119
|
+
base_name = 'HTTP'
|
|
120
|
+
method_value = '_OTHER'
|
|
121
|
+
original = method.to_s
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
span_name = url_template ? "#{base_name} #{url_template}" : base_name
|
|
125
|
+
attributes['http.method'] ||= method_value
|
|
126
|
+
attributes['http.request.method'] ||= method_value
|
|
127
|
+
attributes['http.request.method_original'] ||= original if original
|
|
128
|
+
|
|
129
|
+
SpanCreationAttributes.new(span_name: span_name, attributes: attributes)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -11,34 +11,22 @@ module OpenTelemetry
|
|
|
11
11
|
module Dup
|
|
12
12
|
# Excon middleware for instrumentation
|
|
13
13
|
class TracerMiddleware < ::Excon::Middleware::Base
|
|
14
|
-
HTTP_METHODS_TO_UPPERCASE = %w[connect delete get head options patch post put trace].each_with_object({}) do |method, hash|
|
|
15
|
-
uppercase_method = method.upcase
|
|
16
|
-
hash[method] = uppercase_method
|
|
17
|
-
hash[method.to_sym] = uppercase_method
|
|
18
|
-
hash[uppercase_method] = uppercase_method
|
|
19
|
-
end.freeze
|
|
20
|
-
|
|
21
|
-
HTTP_METHODS_TO_SPAN_NAMES = HTTP_METHODS_TO_UPPERCASE.values.each_with_object({}) do |uppercase_method, hash|
|
|
22
|
-
hash[uppercase_method] ||= uppercase_method
|
|
23
|
-
end.freeze
|
|
24
|
-
|
|
25
14
|
# Constant for the HTTP status range
|
|
26
15
|
HTTP_STATUS_SUCCESS_RANGE = (100..399)
|
|
27
16
|
|
|
28
17
|
def request_call(datum)
|
|
29
18
|
return @stack.request_call(datum) if untraced?(datum)
|
|
30
19
|
|
|
31
|
-
|
|
20
|
+
span_data = HttpHelper.span_attrs_for_dup(datum[:method])
|
|
21
|
+
|
|
32
22
|
cleansed_url = OpenTelemetry::Common::Utilities.cleanse_url(::Excon::Utils.request_uri(datum))
|
|
33
23
|
attributes = {
|
|
34
24
|
OpenTelemetry::SemanticConventions::Trace::HTTP_HOST => datum[:host],
|
|
35
|
-
OpenTelemetry::SemanticConventions::Trace::HTTP_METHOD => http_method,
|
|
36
25
|
OpenTelemetry::SemanticConventions::Trace::HTTP_SCHEME => datum[:scheme],
|
|
37
26
|
OpenTelemetry::SemanticConventions::Trace::HTTP_TARGET => datum[:path],
|
|
38
27
|
OpenTelemetry::SemanticConventions::Trace::HTTP_URL => cleansed_url,
|
|
39
28
|
OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME => datum[:hostname],
|
|
40
29
|
OpenTelemetry::SemanticConventions::Trace::NET_PEER_PORT => datum[:port],
|
|
41
|
-
'http.request.method' => http_method,
|
|
42
30
|
'url.scheme' => datum[:scheme],
|
|
43
31
|
'url.path' => datum[:path],
|
|
44
32
|
'url.full' => cleansed_url,
|
|
@@ -48,8 +36,8 @@ module OpenTelemetry
|
|
|
48
36
|
attributes['url.query'] = datum[:query] if datum[:query]
|
|
49
37
|
peer_service = Excon::Instrumentation.instance.config[:peer_service]
|
|
50
38
|
attributes[OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = peer_service if peer_service
|
|
51
|
-
attributes.merge!(
|
|
52
|
-
span = tracer.start_span(
|
|
39
|
+
attributes.merge!(span_data.attributes)
|
|
40
|
+
span = tracer.start_span(span_data.span_name, attributes: attributes, kind: :client)
|
|
53
41
|
ctx = OpenTelemetry::Trace.context_with_span(span)
|
|
54
42
|
datum[:otel_span] = span
|
|
55
43
|
datum[:otel_token] = OpenTelemetry::Context.attach(ctx)
|
|
@@ -11,27 +11,16 @@ module OpenTelemetry
|
|
|
11
11
|
module Old
|
|
12
12
|
# Excon middleware for instrumentation
|
|
13
13
|
class TracerMiddleware < ::Excon::Middleware::Base
|
|
14
|
-
HTTP_METHODS_TO_UPPERCASE = %w[connect delete get head options patch post put trace].each_with_object({}) do |method, hash|
|
|
15
|
-
uppercase_method = method.upcase
|
|
16
|
-
hash[method] = uppercase_method
|
|
17
|
-
hash[method.to_sym] = uppercase_method
|
|
18
|
-
hash[uppercase_method] = uppercase_method
|
|
19
|
-
end.freeze
|
|
20
|
-
|
|
21
|
-
HTTP_METHODS_TO_SPAN_NAMES = HTTP_METHODS_TO_UPPERCASE.values.each_with_object({}) do |uppercase_method, hash|
|
|
22
|
-
hash[uppercase_method] ||= "HTTP #{uppercase_method}"
|
|
23
|
-
end.freeze
|
|
24
|
-
|
|
25
14
|
# Constant for the HTTP status range
|
|
26
15
|
HTTP_STATUS_SUCCESS_RANGE = (100..399)
|
|
27
16
|
|
|
28
17
|
def request_call(datum)
|
|
29
18
|
return @stack.request_call(datum) if untraced?(datum)
|
|
30
19
|
|
|
31
|
-
|
|
20
|
+
span_data = HttpHelper.span_attrs_for_old(datum[:method])
|
|
21
|
+
|
|
32
22
|
attributes = {
|
|
33
23
|
OpenTelemetry::SemanticConventions::Trace::HTTP_HOST => datum[:host],
|
|
34
|
-
OpenTelemetry::SemanticConventions::Trace::HTTP_METHOD => http_method,
|
|
35
24
|
OpenTelemetry::SemanticConventions::Trace::HTTP_SCHEME => datum[:scheme],
|
|
36
25
|
OpenTelemetry::SemanticConventions::Trace::HTTP_TARGET => datum[:path],
|
|
37
26
|
OpenTelemetry::SemanticConventions::Trace::HTTP_URL => OpenTelemetry::Common::Utilities.cleanse_url(::Excon::Utils.request_uri(datum)),
|
|
@@ -40,8 +29,8 @@ module OpenTelemetry
|
|
|
40
29
|
}
|
|
41
30
|
peer_service = Excon::Instrumentation.instance.config[:peer_service]
|
|
42
31
|
attributes[OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = peer_service if peer_service
|
|
43
|
-
attributes.merge!(
|
|
44
|
-
span = tracer.start_span(
|
|
32
|
+
attributes.merge!(span_data.attributes)
|
|
33
|
+
span = tracer.start_span(span_data.span_name, attributes: attributes, kind: :client)
|
|
45
34
|
ctx = OpenTelemetry::Trace.context_with_span(span)
|
|
46
35
|
datum[:otel_span] = span
|
|
47
36
|
datum[:otel_token] = OpenTelemetry::Context.attach(ctx)
|
|
@@ -11,37 +11,24 @@ module OpenTelemetry
|
|
|
11
11
|
module Stable
|
|
12
12
|
# Excon middleware for instrumentation
|
|
13
13
|
class TracerMiddleware < ::Excon::Middleware::Base
|
|
14
|
-
HTTP_METHODS_TO_UPPERCASE = %w[connect delete get head options patch post put trace].each_with_object({}) do |method, hash|
|
|
15
|
-
uppercase_method = method.upcase
|
|
16
|
-
hash[method] = uppercase_method
|
|
17
|
-
hash[method.to_sym] = uppercase_method
|
|
18
|
-
hash[uppercase_method] = uppercase_method
|
|
19
|
-
end.freeze
|
|
20
|
-
|
|
21
|
-
HTTP_METHODS_TO_SPAN_NAMES = HTTP_METHODS_TO_UPPERCASE.values.each_with_object({}) do |uppercase_method, hash|
|
|
22
|
-
hash[uppercase_method] ||= uppercase_method
|
|
23
|
-
end.freeze
|
|
24
|
-
|
|
25
14
|
# Constant for the HTTP status range
|
|
26
15
|
HTTP_STATUS_SUCCESS_RANGE = (100..399)
|
|
27
16
|
|
|
28
17
|
def request_call(datum)
|
|
29
18
|
return @stack.request_call(datum) if untraced?(datum)
|
|
30
19
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
'server.port' => datum[:port]
|
|
39
|
-
}
|
|
20
|
+
span_data = HttpHelper.span_attrs_for_stable(datum[:method])
|
|
21
|
+
|
|
22
|
+
attributes = { 'url.scheme' => datum[:scheme],
|
|
23
|
+
'url.path' => datum[:path],
|
|
24
|
+
'url.full' => OpenTelemetry::Common::Utilities.cleanse_url(::Excon::Utils.request_uri(datum)),
|
|
25
|
+
'server.address' => datum[:hostname],
|
|
26
|
+
'server.port' => datum[:port] }
|
|
40
27
|
attributes['url.query'] = datum[:query] if datum[:query]
|
|
41
28
|
peer_service = Excon::Instrumentation.instance.config[:peer_service]
|
|
42
29
|
attributes[OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = peer_service if peer_service
|
|
43
|
-
attributes.merge!(
|
|
44
|
-
span = tracer.start_span(
|
|
30
|
+
attributes.merge!(span_data.attributes)
|
|
31
|
+
span = tracer.start_span(span_data.span_name, attributes: attributes, kind: :client)
|
|
45
32
|
ctx = OpenTelemetry::Trace.context_with_span(span)
|
|
46
33
|
datum[:otel_span] = span
|
|
47
34
|
datum[:otel_token] = OpenTelemetry::Context.attach(ctx)
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: opentelemetry-instrumentation-excon
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.27.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- OpenTelemetry Authors
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-01-13 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: opentelemetry-instrumentation-base
|
|
@@ -39,6 +39,7 @@ files:
|
|
|
39
39
|
- lib/opentelemetry/instrumentation.rb
|
|
40
40
|
- lib/opentelemetry/instrumentation/concerns/untraced_hosts.rb
|
|
41
41
|
- lib/opentelemetry/instrumentation/excon.rb
|
|
42
|
+
- lib/opentelemetry/instrumentation/excon/http_helper.rb
|
|
42
43
|
- lib/opentelemetry/instrumentation/excon/instrumentation.rb
|
|
43
44
|
- lib/opentelemetry/instrumentation/excon/middlewares/dup/tracer_middleware.rb
|
|
44
45
|
- lib/opentelemetry/instrumentation/excon/middlewares/old/tracer_middleware.rb
|
|
@@ -51,10 +52,10 @@ homepage: https://github.com/open-telemetry/opentelemetry-ruby-contrib
|
|
|
51
52
|
licenses:
|
|
52
53
|
- Apache-2.0
|
|
53
54
|
metadata:
|
|
54
|
-
changelog_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-excon/0.
|
|
55
|
+
changelog_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-excon/0.27.0/file/CHANGELOG.md
|
|
55
56
|
source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation/excon
|
|
56
57
|
bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/issues
|
|
57
|
-
documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-excon/0.
|
|
58
|
+
documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-excon/0.27.0
|
|
58
59
|
post_install_message:
|
|
59
60
|
rdoc_options: []
|
|
60
61
|
require_paths:
|