opentelemetry-instrumentation-httpx 0.6.0 → 0.6.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: b345154080244595e374a9c5c73dc2bb6a3d3772c9e689aff17197d5d2745f00
4
- data.tar.gz: b2b03b233c59c2291e429a95838f2e7bbbf23a28374784f9bd969e3ec201a589
3
+ metadata.gz: 7f74f31524d99c5a0565edf84892292d068322376584c58b7dc4aabbdea724fd
4
+ data.tar.gz: 74cdecfb4c9c7a7e3fe0164ce3977d53e33d4fa96c140265629b401f1e0dce77
5
5
  SHA512:
6
- metadata.gz: fe41c4e43b96bef2caaf39830ab4a7d14ffb0ec5955f96fd71d3bb6039c06d74d9bd7fb5b8a7c547bb692a47d0e1b011fa42ea46ab76e24f705f12fe2f212c58
7
- data.tar.gz: ac11915108072d027abe9383e0eb4cccba42b9dd891772f4f93dd4dcfc87c261918c37447357c999bc49a80b0583dfacabd8ae404075a04b40c498032a2fd711
6
+ metadata.gz: 7f78e75c32d2fd6df5635ffac615ff7fdf7ff987b9ad93970d32d171887184ca2652f081569d843705dd45f715c6a08a592ef461186f02b1c610045a5ffabe11
7
+ data.tar.gz: efa536643cab0d4d878acb262d62ab2936bb0ce82e70368d2bd7c6367a2781afe327eedfaafb08fa6df1e5f4cb91eb63763008f416698b1130d8b834902e57df
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Release History: opentelemetry-instrumentation-httpx
2
2
 
3
+ ### v0.6.1 / 2026-02-27
4
+
5
+ * FIXED: Httpx support to ~> 1.6 adapt to request init_time (#2030)
6
+
3
7
  ### v0.6.0 / 2026-01-13
4
8
 
5
9
  * ADDED: HTTP Client Semconv v1.17 Span Naming
@@ -11,7 +15,6 @@
11
15
  ### v0.5.0 / 2025-10-22
12
16
 
13
17
  * BREAKING CHANGE: Min Ruby Version 3.2
14
-
15
18
  * ADDED: Min Ruby Version 3.2
16
19
 
17
20
  ### v0.4.1 / 2025-09-30
@@ -33,7 +36,6 @@
33
36
  ### v0.2.0 / 2025-01-16
34
37
 
35
38
  * BREAKING CHANGE: Set minimum supported version to Ruby 3.1
36
-
37
39
  * ADDED: Set minimum supported version to Ruby 3.1
38
40
 
39
41
  ### v0.1.3 / 2024-11-26
@@ -8,126 +8,107 @@ module OpenTelemetry
8
8
  module Instrumentation
9
9
  module HTTPX
10
10
  module Dup
11
+ # Dup Plugin
11
12
  module Plugin
12
- # Instruments around HTTPX's request/response lifecycle in order to generate
13
- # an OTEL trace.
14
- module RequestTracer
15
- module_function
13
+ def self.load_dependencies(klass)
14
+ require_relative '../plugin'
15
+ klass.plugin(HTTPX::Plugin)
16
16
 
17
- # initializes tracing on the +request+.
18
- def call(request)
19
- span = nil
17
+ HTTPX::Plugin.const_set(:RequestTracer, RequestTracer)
18
+ end
19
+ end
20
20
 
21
- # request objects are reused, when already buffered requests get rerouted to a different
22
- # connection due to connection issues, or when they already got a response, but need to
23
- # be retried. In such situations, the original span needs to be extended for the former,
24
- # while a new is required for the latter.
25
- request.on(:idle) do
26
- span = nil
27
- end
28
- # the span is initialized when the request is buffered in the parser, which is the closest
29
- # one gets to actually sending the request.
30
- request.on(:headers) do
31
- next if span
21
+ # Instruments around HTTPX's request/response lifecycle in order to generate
22
+ # an OTEL trace.
23
+ module RequestTracer
24
+ extend self
32
25
 
33
- span = initialize_span(request)
34
- end
26
+ # initializes tracing on the +request+.
27
+ def call(request)
28
+ span = nil
35
29
 
36
- request.on(:response) do |response|
37
- unless span
38
- next unless response.is_a?(::HTTPX::ErrorResponse) && response.error.respond_to?(:connection)
30
+ # request objects are reused, when already buffered requests get rerouted to a different
31
+ # connection due to connection issues, or when they already got a response, but need to
32
+ # be retried. In such situations, the original span needs to be extended for the former,
33
+ # while a new is required for the latter.
34
+ request.on(:idle) do
35
+ span = nil
36
+ end
37
+ # the span is initialized when the request is buffered in the parser, which is the closest
38
+ # one gets to actually sending the request.
39
+ request.on(:headers) do
40
+ next if span
39
41
 
40
- # handles the case when the +error+ happened during name resolution, which means
41
- # that the tracing start point hasn't been triggered yet; in such cases, the approximate
42
- # initial resolving time is collected from the connection, and used as span start time,
43
- # and the tracing object in inserted before the on response callback is called.
44
- span = initialize_span(request, response.error.connection.init_time)
42
+ span = initialize_span(request)
43
+ end
45
44
 
46
- end
45
+ request.on(:response) do |response|
46
+ span = initialize_span(request, request.init_time) if !span && request.init_time
47
47
 
48
- finish(response, span)
49
- end
48
+ finish(response, span)
50
49
  end
50
+ end
51
51
 
52
- def finish(response, span)
53
- if response.is_a?(::HTTPX::ErrorResponse)
54
- span.record_exception(response.error)
55
- span.status = Trace::Status.error(response.error.to_s)
56
- else
57
- span.set_attribute(OpenTelemetry::SemanticConventions::Trace::HTTP_STATUS_CODE, response.status)
58
- span.set_attribute('http.response.status_code', response.status)
59
-
60
- if response.status.between?(400, 599)
61
- err = ::HTTPX::HTTPError.new(response)
62
- span.record_exception(err)
63
- span.status = Trace::Status.error(err.to_s)
64
- end
65
- end
52
+ private
66
53
 
67
- span.finish
68
- end
54
+ def finish(response, span)
55
+ if response.is_a?(::HTTPX::ErrorResponse)
56
+ span.record_exception(response.error)
57
+ span.status = Trace::Status.error(response.error.to_s)
58
+ else
59
+ span.set_attribute(OpenTelemetry::SemanticConventions::Trace::HTTP_STATUS_CODE, response.status)
60
+ span.set_attribute('http.response.status_code', response.status)
69
61
 
70
- # return a span initialized with the +@request+ state.
71
- def initialize_span(request, start_time = ::Time.now)
72
- verb = request.verb
73
- uri = request.uri
74
-
75
- span_data = HttpHelper.span_attrs_for_dup(verb)
76
-
77
- config = HTTPX::Instrumentation.instance.config
78
-
79
- attributes = {
80
- OpenTelemetry::SemanticConventions::Trace::HTTP_HOST => uri.host,
81
- OpenTelemetry::SemanticConventions::Trace::HTTP_SCHEME => uri.scheme,
82
- OpenTelemetry::SemanticConventions::Trace::HTTP_TARGET => uri.path,
83
- OpenTelemetry::SemanticConventions::Trace::HTTP_URL => "#{uri.scheme}://#{uri.host}",
84
- OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME => uri.host,
85
- OpenTelemetry::SemanticConventions::Trace::NET_PEER_PORT => uri.port,
86
- 'url.scheme' => uri.scheme,
87
- 'url.path' => uri.path,
88
- 'url.full' => "#{uri.scheme}://#{uri.host}",
89
- 'server.address' => uri.host,
90
- 'server.port' => uri.port
91
- }
92
-
93
- attributes['url.query'] = uri.query unless uri.query.nil?
94
- attributes[OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = config[:peer_service] if config[:peer_service]
95
- attributes.merge!(span_data.attributes)
96
-
97
- span = tracer.start_span(span_data.span_name, attributes: attributes, kind: :client, start_timestamp: start_time)
98
-
99
- OpenTelemetry::Trace.with_span(span) do
100
- OpenTelemetry.propagation.inject(request.headers)
62
+ if response.status.between?(400, 599)
63
+ err = ::HTTPX::HTTPError.new(response)
64
+ span.record_exception(err)
65
+ span.status = Trace::Status.error(err.to_s)
101
66
  end
102
-
103
- span
104
- rescue StandardError => e
105
- OpenTelemetry.handle_error(exception: e)
106
67
  end
107
68
 
108
- def tracer
109
- HTTPX::Instrumentation.instance.tracer
110
- end
69
+ span.finish
111
70
  end
112
71
 
113
- # Request patch to initiate the trace on initialization.
114
- module RequestMethods
115
- def initialize(*)
116
- super
117
-
118
- RequestTracer.call(self)
72
+ # return a span initialized with the +@request+ state.
73
+ def initialize_span(request, start_time = ::Time.now)
74
+ verb = request.verb
75
+ uri = request.uri
76
+
77
+ span_data = HttpHelper.span_attrs_for_dup(verb)
78
+
79
+ config = HTTPX::Instrumentation.instance.config
80
+
81
+ attributes = {
82
+ OpenTelemetry::SemanticConventions::Trace::HTTP_HOST => uri.host,
83
+ OpenTelemetry::SemanticConventions::Trace::HTTP_SCHEME => uri.scheme,
84
+ OpenTelemetry::SemanticConventions::Trace::HTTP_TARGET => uri.path,
85
+ OpenTelemetry::SemanticConventions::Trace::HTTP_URL => "#{uri.scheme}://#{uri.host}",
86
+ OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME => uri.host,
87
+ OpenTelemetry::SemanticConventions::Trace::NET_PEER_PORT => uri.port,
88
+ 'url.scheme' => uri.scheme,
89
+ 'url.path' => uri.path,
90
+ 'url.full' => "#{uri.scheme}://#{uri.host}",
91
+ 'server.address' => uri.host,
92
+ 'server.port' => uri.port
93
+ }
94
+
95
+ attributes['url.query'] = uri.query unless uri.query.nil?
96
+ attributes[OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = config[:peer_service] if config[:peer_service]
97
+ attributes.merge!(span_data.attributes)
98
+
99
+ span = tracer.start_span(span_data.span_name, attributes: attributes, kind: :client, start_timestamp: start_time)
100
+
101
+ OpenTelemetry::Trace.with_span(span) do
102
+ OpenTelemetry.propagation.inject(request.headers)
119
103
  end
120
- end
121
-
122
- # Connection patch to start monitoring on initialization.
123
- module ConnectionMethods
124
- attr_reader :init_time
125
104
 
126
- def initialize(*)
127
- super
105
+ span
106
+ rescue StandardError => e
107
+ OpenTelemetry.handle_error(exception: e)
108
+ end
128
109
 
129
- @init_time = ::Time.now
130
- end
110
+ def tracer
111
+ HTTPX::Instrumentation.instance.tracer
131
112
  end
132
113
  end
133
114
  end
@@ -16,7 +16,7 @@ module OpenTelemetry
16
16
  end
17
17
 
18
18
  compatible do
19
- Gem::Version.new(::HTTPX::VERSION) >= Gem::Version.new('0.24.7')
19
+ Gem::Version.new(::HTTPX::VERSION) >= Gem::Version.new('1.6.0')
20
20
  end
21
21
 
22
22
  present do
@@ -8,119 +8,100 @@ module OpenTelemetry
8
8
  module Instrumentation
9
9
  module HTTPX
10
10
  module Old
11
+ # Old Plugin
11
12
  module Plugin
12
- # Instruments around HTTPX's request/response lifecycle in order to generate
13
- # an OTEL trace.
14
- module RequestTracer
15
- module_function
13
+ def self.load_dependencies(klass)
14
+ require_relative '../plugin'
15
+ klass.plugin(HTTPX::Plugin)
16
16
 
17
- # initializes tracing on the +request+.
18
- def call(request)
19
- span = nil
20
-
21
- # request objects are reused, when already buffered requests get rerouted to a different
22
- # connection due to connection issues, or when they already got a response, but need to
23
- # be retried. In such situations, the original span needs to be extended for the former,
24
- # while a new is required for the latter.
25
- request.on(:idle) do
26
- span = nil
27
- end
28
- # the span is initialized when the request is buffered in the parser, which is the closest
29
- # one gets to actually sending the request.
30
- request.on(:headers) do
31
- next if span
32
-
33
- span = initialize_span(request)
34
- end
17
+ HTTPX::Plugin.const_set(:RequestTracer, RequestTracer)
18
+ end
19
+ end
35
20
 
36
- request.on(:response) do |response|
37
- unless span
38
- next unless response.is_a?(::HTTPX::ErrorResponse) && response.error.respond_to?(:connection)
21
+ # Instruments around HTTPX's request/response lifecycle in order to generate
22
+ # an OTEL trace.
23
+ module RequestTracer
24
+ extend self
39
25
 
40
- # handles the case when the +error+ happened during name resolution, which means
41
- # that the tracing start point hasn't been triggered yet; in such cases, the approximate
42
- # initial resolving time is collected from the connection, and used as span start time,
43
- # and the tracing object in inserted before the on response callback is called.
44
- span = initialize_span(request, response.error.connection.init_time)
26
+ # initializes tracing on the +request+.
27
+ def call(request)
28
+ span = nil
45
29
 
46
- end
30
+ # request objects are reused, when already buffered requests get rerouted to a different
31
+ # connection due to connection issues, or when they already got a response, but need to
32
+ # be retried. In such situations, the original span needs to be extended for the former,
33
+ # while a new is required for the latter.
34
+ request.on(:idle) do
35
+ span = nil
36
+ end
37
+ # the span is initialized when the request is buffered in the parser, which is the closest
38
+ # one gets to actually sending the request.
39
+ request.on(:headers) do
40
+ next if span
47
41
 
48
- finish(response, span)
49
- end
42
+ span = initialize_span(request)
50
43
  end
51
44
 
52
- def finish(response, span)
53
- if response.is_a?(::HTTPX::ErrorResponse)
54
- span.record_exception(response.error)
55
- span.status = Trace::Status.error(response.error.to_s)
56
- else
57
- span.set_attribute(OpenTelemetry::SemanticConventions::Trace::HTTP_STATUS_CODE, response.status)
58
-
59
- if response.status.between?(400, 599)
60
- err = ::HTTPX::HTTPError.new(response)
61
- span.record_exception(err)
62
- span.status = Trace::Status.error(err.to_s)
63
- end
64
- end
45
+ request.on(:response) do |response|
46
+ span = initialize_span(request, request.init_time) if !span && request.init_time
65
47
 
66
- span.finish
48
+ finish(response, span)
67
49
  end
50
+ end
68
51
 
69
- # return a span initialized with the +@request+ state.
70
- def initialize_span(request, start_time = ::Time.now)
71
- verb = request.verb
72
- uri = request.uri
52
+ private
73
53
 
74
- span_data = HttpHelper.span_attrs_for_old(verb)
54
+ def finish(response, span)
55
+ if response.is_a?(::HTTPX::ErrorResponse)
56
+ span.record_exception(response.error)
57
+ span.status = Trace::Status.error(response.error.to_s)
58
+ else
59
+ span.set_attribute(OpenTelemetry::SemanticConventions::Trace::HTTP_STATUS_CODE, response.status)
75
60
 
76
- config = HTTPX::Instrumentation.instance.config
61
+ if response.status.between?(400, 599)
62
+ err = ::HTTPX::HTTPError.new(response)
63
+ span.record_exception(err)
64
+ span.status = Trace::Status.error(err.to_s)
65
+ end
66
+ end
77
67
 
78
- attributes = {
79
- OpenTelemetry::SemanticConventions::Trace::HTTP_HOST => uri.host,
80
- OpenTelemetry::SemanticConventions::Trace::HTTP_SCHEME => uri.scheme,
81
- OpenTelemetry::SemanticConventions::Trace::HTTP_TARGET => uri.path,
82
- OpenTelemetry::SemanticConventions::Trace::HTTP_URL => "#{uri.scheme}://#{uri.host}",
83
- OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME => uri.host,
84
- OpenTelemetry::SemanticConventions::Trace::NET_PEER_PORT => uri.port
85
- }
68
+ span.finish
69
+ end
86
70
 
87
- attributes[OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = config[:peer_service] if config[:peer_service]
88
- attributes.merge!(span_data.attributes)
71
+ # return a span initialized with the +@request+ state.
72
+ def initialize_span(request, start_time = ::Time.now)
73
+ verb = request.verb
74
+ uri = request.uri
89
75
 
90
- span = tracer.start_span(span_data.span_name, attributes: attributes, kind: :client, start_timestamp: start_time)
76
+ span_data = HttpHelper.span_attrs_for_old(verb)
91
77
 
92
- OpenTelemetry::Trace.with_span(span) do
93
- OpenTelemetry.propagation.inject(request.headers)
94
- end
78
+ config = HTTPX::Instrumentation.instance.config
95
79
 
96
- span
97
- rescue StandardError => e
98
- OpenTelemetry.handle_error(exception: e)
99
- end
80
+ attributes = {
81
+ OpenTelemetry::SemanticConventions::Trace::HTTP_HOST => uri.host,
82
+ OpenTelemetry::SemanticConventions::Trace::HTTP_SCHEME => uri.scheme,
83
+ OpenTelemetry::SemanticConventions::Trace::HTTP_TARGET => uri.path,
84
+ OpenTelemetry::SemanticConventions::Trace::HTTP_URL => "#{uri.scheme}://#{uri.host}",
85
+ OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME => uri.host,
86
+ OpenTelemetry::SemanticConventions::Trace::NET_PEER_PORT => uri.port
87
+ }
100
88
 
101
- def tracer
102
- HTTPX::Instrumentation.instance.tracer
103
- end
104
- end
89
+ attributes[OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = config[:peer_service] if config[:peer_service]
90
+ attributes.merge!(span_data.attributes)
105
91
 
106
- # Request patch to initiate the trace on initialization.
107
- module RequestMethods
108
- def initialize(*)
109
- super
92
+ span = tracer.start_span(span_data.span_name, attributes: attributes, kind: :client, start_timestamp: start_time)
110
93
 
111
- RequestTracer.call(self)
94
+ OpenTelemetry::Trace.with_span(span) do
95
+ OpenTelemetry.propagation.inject(request.headers)
112
96
  end
113
- end
114
-
115
- # Connection patch to start monitoring on initialization.
116
- module ConnectionMethods
117
- attr_reader :init_time
118
97
 
119
- def initialize(*)
120
- super
98
+ span
99
+ rescue StandardError => e
100
+ OpenTelemetry.handle_error(exception: e)
101
+ end
121
102
 
122
- @init_time = ::Time.now
123
- end
103
+ def tracer
104
+ HTTPX::Instrumentation.instance.tracer
124
105
  end
125
106
  end
126
107
  end
@@ -0,0 +1,54 @@
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 HTTPX
10
+ # Base Plugin
11
+ module Plugin
12
+ # Request patch to initiate the trace on initialization.
13
+ module RequestMethods
14
+ attr_accessor :init_time
15
+
16
+ # intercepts request initialization to inject the tracing logic.
17
+ def initialize(*)
18
+ super
19
+
20
+ @init_time = nil
21
+
22
+ RequestTracer.call(self)
23
+ end
24
+
25
+ def response=(*)
26
+ # init_time should be set when it's send to a connection.
27
+ # However, there are situations where connection initialization fails.
28
+ # Example is the :ssrf_filter plugin, which raises an error on
29
+ # initialize if the host is an IP which matches against the known set.
30
+ # in such cases, we'll just set here right here.
31
+ @init_time ||= ::Time.now
32
+
33
+ super
34
+ end
35
+ end
36
+
37
+ # Connection mixin
38
+ module ConnectionMethods
39
+ def initialize(*)
40
+ super
41
+
42
+ @init_time = ::Time.now
43
+ end
44
+
45
+ def send(request)
46
+ request.init_time ||= @init_time
47
+
48
+ super
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -8,118 +8,99 @@ module OpenTelemetry
8
8
  module Instrumentation
9
9
  module HTTPX
10
10
  module Stable
11
+ # Stable Plugin
11
12
  module Plugin
12
- # Instruments around HTTPX's request/response lifecycle in order to generate
13
- # an OTEL trace.
14
- module RequestTracer
15
- module_function
13
+ def self.load_dependencies(klass)
14
+ require_relative '../plugin'
15
+ klass.plugin(HTTPX::Plugin)
16
16
 
17
- # initializes tracing on the +request+.
18
- def call(request)
19
- span = nil
20
-
21
- # request objects are reused, when already buffered requests get rerouted to a different
22
- # connection due to connection issues, or when they already got a response, but need to
23
- # be retried. In such situations, the original span needs to be extended for the former,
24
- # while a new is required for the latter.
25
- request.on(:idle) do
26
- span = nil
27
- end
28
- # the span is initialized when the request is buffered in the parser, which is the closest
29
- # one gets to actually sending the request.
30
- request.on(:headers) do
31
- next if span
32
-
33
- span = initialize_span(request)
34
- end
35
-
36
- request.on(:response) do |response|
37
- unless span
38
- next unless response.is_a?(::HTTPX::ErrorResponse) && response.error.respond_to?(:connection)
17
+ HTTPX::Plugin.const_set(:RequestTracer, RequestTracer)
18
+ end
19
+ end
39
20
 
40
- # handles the case when the +error+ happened during name resolution, which means
41
- # that the tracing start point hasn't been triggered yet; in such cases, the approximate
42
- # initial resolving time is collected from the connection, and used as span start time,
43
- # and the tracing object in inserted before the on response callback is called.
44
- span = initialize_span(request, response.error.connection.init_time)
21
+ # Instruments around HTTPX's request/response lifecycle in order to generate
22
+ # an OTEL trace.
23
+ module RequestTracer
24
+ extend self
45
25
 
46
- end
26
+ # initializes tracing on the +request+.
27
+ def call(request)
28
+ span = nil
47
29
 
48
- finish(response, span)
49
- end
30
+ # request objects are reused, when already buffered requests get rerouted to a different
31
+ # connection due to connection issues, or when they already got a response, but need to
32
+ # be retried. In such situations, the original span needs to be extended for the former,
33
+ # while a new is required for the latter.
34
+ request.on(:idle) do
35
+ span = nil
50
36
  end
37
+ # the span is initialized when the request is buffered in the parser, which is the closest
38
+ # one gets to actually sending the request.
39
+ request.on(:headers) do
40
+ next if span
51
41
 
52
- def finish(response, span)
53
- if response.is_a?(::HTTPX::ErrorResponse)
54
- span.record_exception(response.error)
55
- span.status = Trace::Status.error(response.error.to_s)
56
- else
57
- span.set_attribute('http.response.status_code', response.status)
58
-
59
- if response.status.between?(400, 599)
60
- err = ::HTTPX::HTTPError.new(response)
61
- span.record_exception(err)
62
- span.status = Trace::Status.error(err.to_s)
63
- end
64
- end
65
-
66
- span.finish
42
+ span = initialize_span(request)
67
43
  end
68
44
 
69
- # return a span initialized with the +@request+ state.
70
- def initialize_span(request, start_time = ::Time.now)
71
- verb = request.verb
72
- uri = request.uri
45
+ request.on(:response) do |response|
46
+ span = initialize_span(request, request.init_time) if !span && request.init_time
73
47
 
74
- span_data = HttpHelper.span_attrs_for_stable(verb)
75
-
76
- config = HTTPX::Instrumentation.instance.config
48
+ finish(response, span)
49
+ end
50
+ end
77
51
 
78
- attributes = {
79
- 'url.scheme' => uri.scheme,
80
- 'url.path' => uri.path,
81
- 'url.full' => "#{uri.scheme}://#{uri.host}",
82
- 'server.address' => uri.host,
83
- 'server.port' => uri.port
84
- }
85
- attributes['url.query'] = uri.query unless uri.query.nil?
86
- attributes[OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = config[:peer_service] if config[:peer_service]
87
- attributes.merge!(span_data.attributes)
52
+ private
88
53
 
89
- span = tracer.start_span(span_data.span_name, attributes: attributes, kind: :client, start_timestamp: start_time)
54
+ def finish(response, span)
55
+ if response.is_a?(::HTTPX::ErrorResponse)
56
+ span.record_exception(response.error)
57
+ span.status = Trace::Status.error(response.error.to_s)
58
+ else
59
+ span.set_attribute('http.response.status_code', response.status)
90
60
 
91
- OpenTelemetry::Trace.with_span(span) do
92
- OpenTelemetry.propagation.inject(request.headers)
61
+ if response.status.between?(400, 599)
62
+ err = ::HTTPX::HTTPError.new(response)
63
+ span.record_exception(err)
64
+ span.status = Trace::Status.error(err.to_s)
93
65
  end
94
-
95
- span
96
- rescue StandardError => e
97
- OpenTelemetry.handle_error(exception: e)
98
66
  end
99
67
 
100
- def tracer
101
- HTTPX::Instrumentation.instance.tracer
102
- end
68
+ span.finish
103
69
  end
104
70
 
105
- # Request patch to initiate the trace on initialization.
106
- module RequestMethods
107
- def initialize(*)
108
- super
71
+ # return a span initialized with the +@request+ state.
72
+ def initialize_span(request, start_time = ::Time.now)
73
+ verb = request.verb
74
+ uri = request.uri
109
75
 
110
- RequestTracer.call(self)
111
- end
112
- end
76
+ span_data = HttpHelper.span_attrs_for_stable(verb)
77
+
78
+ config = HTTPX::Instrumentation.instance.config
113
79
 
114
- # Connection patch to start monitoring on initialization.
115
- module ConnectionMethods
116
- attr_reader :init_time
80
+ attributes = {
81
+ 'url.scheme' => uri.scheme,
82
+ 'url.path' => uri.path,
83
+ 'url.full' => "#{uri.scheme}://#{uri.host}",
84
+ 'server.address' => uri.host,
85
+ 'server.port' => uri.port
86
+ }
87
+ attributes['url.query'] = uri.query unless uri.query.nil?
88
+ attributes[OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = config[:peer_service] if config[:peer_service]
89
+ attributes.merge!(span_data.attributes)
117
90
 
118
- def initialize(*)
119
- super
91
+ span = tracer.start_span(span_data.span_name, attributes: attributes, kind: :client, start_timestamp: start_time)
120
92
 
121
- @init_time = ::Time.now
93
+ OpenTelemetry::Trace.with_span(span) do
94
+ OpenTelemetry.propagation.inject(request.headers)
122
95
  end
96
+
97
+ span
98
+ rescue StandardError => e
99
+ OpenTelemetry.handle_error(exception: e)
100
+ end
101
+
102
+ def tracer
103
+ HTTPX::Instrumentation.instance.tracer
123
104
  end
124
105
  end
125
106
  end
@@ -7,7 +7,7 @@
7
7
  module OpenTelemetry
8
8
  module Instrumentation
9
9
  module HTTPX
10
- VERSION = '0.6.0'
10
+ VERSION = '0.6.1'
11
11
  end
12
12
  end
13
13
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opentelemetry-instrumentation-httpx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenTelemetry Authors
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2026-01-13 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: opentelemetry-instrumentation-base
@@ -42,17 +41,17 @@ files:
42
41
  - lib/opentelemetry/instrumentation/httpx/http_helper.rb
43
42
  - lib/opentelemetry/instrumentation/httpx/instrumentation.rb
44
43
  - lib/opentelemetry/instrumentation/httpx/old/plugin.rb
44
+ - lib/opentelemetry/instrumentation/httpx/plugin.rb
45
45
  - lib/opentelemetry/instrumentation/httpx/stable/plugin.rb
46
46
  - lib/opentelemetry/instrumentation/httpx/version.rb
47
47
  homepage: https://github.com/open-telemetry/opentelemetry-ruby-contrib
48
48
  licenses:
49
49
  - Apache-2.0
50
50
  metadata:
51
- changelog_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-httpx/0.6.0/file/CHANGELOG.md
51
+ changelog_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-httpx/0.6.1/file/CHANGELOG.md
52
52
  source_code_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/tree/main/instrumentation/http
53
53
  bug_tracker_uri: https://github.com/open-telemetry/opentelemetry-ruby-contrib/issues
54
- documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-httpx/0.6.0
55
- post_install_message:
54
+ documentation_uri: https://rubydoc.info/gems/opentelemetry-instrumentation-httpx/0.6.1
56
55
  rdoc_options: []
57
56
  require_paths:
58
57
  - lib
@@ -67,8 +66,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
67
66
  - !ruby/object:Gem::Version
68
67
  version: '0'
69
68
  requirements: []
70
- rubygems_version: 3.4.19
71
- signing_key:
69
+ rubygems_version: 4.0.3
72
70
  specification_version: 4
73
71
  summary: HTTPX instrumentation for the OpenTelemetry framework
74
72
  test_files: []