Module: OpenTelemetry::Instrumentation::HTTPX::Stable::Plugin::RequestTracer
- Defined in:
- lib/opentelemetry/instrumentation/httpx/stable/plugin.rb
Overview
Instruments around HTTPX's request/response lifecycle in order to generate an OTEL trace.
Class Method Summary collapse
-
.call(request) ⇒ Object
initializes tracing on the +request+.
- .finish(response, span) ⇒ Object
-
.initialize_span(request, start_time = ::Time.now) ⇒ Object
return a span initialized with the +@request+ state.
- .tracer ⇒ Object
Class Method Details
.call(request) ⇒ Object
initializes tracing on the +request+.
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/opentelemetry/instrumentation/httpx/stable/plugin.rb', line 18 def call(request) span = nil # request objects are reused, when already buffered requests get rerouted to a different # connection due to connection issues, or when they already got a response, but need to # be retried. In such situations, the original span needs to be extended for the former, # while a new is required for the latter. request.on(:idle) do span = nil end # the span is initialized when the request is buffered in the parser, which is the closest # one gets to actually sending the request. request.on(:headers) do next if span span = initialize_span(request) end request.on(:response) do |response| unless span next unless response.is_a?(::HTTPX::ErrorResponse) && response.error.respond_to?(:connection) # handles the case when the +error+ happened during name resolution, which means # that the tracing start point hasn't been triggered yet; in such cases, the approximate # initial resolving time is collected from the connection, and used as span start time, # and the tracing object in inserted before the on response callback is called. span = initialize_span(request, response.error.connection.init_time) end finish(response, span) end end |
.finish(response, span) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/opentelemetry/instrumentation/httpx/stable/plugin.rb', line 52 def finish(response, span) if response.is_a?(::HTTPX::ErrorResponse) span.record_exception(response.error) span.status = Trace::Status.error(response.error.to_s) else span.set_attribute('http.response.status_code', response.status) if response.status.between?(400, 599) err = ::HTTPX::HTTPError.new(response) span.record_exception(err) span.status = Trace::Status.error(err.to_s) end end span.finish end |
.initialize_span(request, start_time = ::Time.now) ⇒ Object
return a span initialized with the +@request+ state.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/opentelemetry/instrumentation/httpx/stable/plugin.rb', line 70 def initialize_span(request, start_time = ::Time.now) verb = request.verb uri = request.uri span_data = HttpHelper.span_attrs_for(verb) config = HTTPX::Instrumentation.instance.config attributes = { 'http.request.method' => span_data.normalized_method, 'url.scheme' => uri.scheme, 'url.path' => uri.path, 'url.full' => "#{uri.scheme}://#{uri.host}", 'server.address' => uri.host, 'server.port' => uri.port } attributes['http.request.method_original'] = span_data.original_method if span_data.original_method attributes['url.query'] = uri.query unless uri.query.nil? attributes[OpenTelemetry::SemanticConventions::Trace::PEER_SERVICE] = config[:peer_service] if config[:peer_service] attributes.merge!(OpenTelemetry::Common::HTTP::ClientContext.attributes) span = tracer.start_span(span_data.span_name, attributes: attributes, kind: :client, start_timestamp: start_time) OpenTelemetry::Trace.with_span(span) do OpenTelemetry.propagation.inject(request.headers) end span rescue StandardError => e OpenTelemetry.handle_error(exception: e) end |
.tracer ⇒ Object
102 103 104 |
# File 'lib/opentelemetry/instrumentation/httpx/stable/plugin.rb', line 102 def tracer HTTPX::Instrumentation.instance.tracer end |