Module: OpenTelemetry::Instrumentation::HTTPX::Old::Plugin::RequestTracer

Defined in:
lib/opentelemetry/instrumentation/httpx/old/plugin.rb

Overview

Instruments around HTTPX's request/response lifecycle in order to generate an OTEL trace.

Class Method Summary collapse

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/old/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/old/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(OpenTelemetry::SemanticConventions::Trace::HTTP_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/old/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, semconv: :old)

  config = HTTPX::Instrumentation.instance.config

  attributes = {
    OpenTelemetry::SemanticConventions::Trace::HTTP_HOST => uri.host,
    OpenTelemetry::SemanticConventions::Trace::HTTP_METHOD => span_data.normalized_method,
    OpenTelemetry::SemanticConventions::Trace::HTTP_SCHEME => uri.scheme,
    OpenTelemetry::SemanticConventions::Trace::HTTP_TARGET => uri.path,
    OpenTelemetry::SemanticConventions::Trace::HTTP_URL => "#{uri.scheme}://#{uri.host}",
    OpenTelemetry::SemanticConventions::Trace::NET_PEER_NAME => uri.host,
    OpenTelemetry::SemanticConventions::Trace::NET_PEER_PORT => uri.port
  }

  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

.tracerObject



102
103
104
# File 'lib/opentelemetry/instrumentation/httpx/old/plugin.rb', line 102

def tracer
  HTTPX::Instrumentation.instance.tracer
end