Module: Datadog::Tracing::Contrib::HTTPX::Plugin::RequestTracer

Extended by:
Contrib::HttpAnnotationHelper
Defined in:
lib/httpx/adapters/datadog.rb

Constant Summary collapse

SPAN_REQUEST =
"httpx.request"

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.call(request) ⇒ Object

initializes tracing on the request.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/httpx/adapters/datadog.rb', line 50

def call(request)
  return unless configuration(request).enabled

  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, now)
  end

  request.on(:response) do |response|
    span = initialize_span(request, request.init_time) if !span && request.init_time

    finish(response, span)
  end
end

.configuration(request) ⇒ Object



149
150
151
# File 'lib/httpx/adapters/datadog.rb', line 149

def configuration(request)
  Datadog.configuration.tracing[:httpx, request.uri.host]
end

.finish(response, span) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/httpx/adapters/datadog.rb', line 77

def finish(response, span)
  if response.is_a?(::HTTPX::ErrorResponse)
    span.set_error(response.error)
  else
    span.set_tag(TAG_STATUS_CODE, response.status.to_s)

    span.set_error(::HTTPX::HTTPError.new(response)) if response.status >= 400 && response.status <= 599

    span.set_tags(
      Datadog.configuration.tracing.header_tags.response_tags(response.headers.to_h)
    ) if Datadog.configuration.tracing.respond_to?(:header_tags)
  end

  span.finish
end

.initialize_span(request, start_time) ⇒ Object

return a span initialized with the @request state.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/httpx/adapters/datadog.rb', line 94

def initialize_span(request, start_time)
  verb = request.verb
  uri = request.uri

  config = configuration(request)

  span = create_span(request, config, start_time)

  span.resource = verb

  # Tag original global service name if not used
  span.set_tag(TAG_BASE_SERVICE, Datadog.configuration.service) if span.service != Datadog.configuration.service

  span.set_tag(TAG_KIND, TAG_CLIENT)

  span.set_tag(TAG_COMPONENT, "httpx")
  span.set_tag(TAG_OPERATION, "request")

  span.set_tag(TAG_URL, request.path)
  span.set_tag(TAG_METHOD, verb)

  span.set_tag(TAG_TARGET_HOST, uri.host)
  span.set_tag(TAG_TARGET_PORT, uri.port)

  span.set_tag(TAG_PEER_HOSTNAME, uri.host)

  # Tag as an external peer service
  # span.set_tag(TAG_PEER_SERVICE, span.service)

  if config[:distributed_tracing]
    propagate_trace_http(
      Datadog::Tracing.active_trace,
      request.headers
    )
  end

  # Set analytics sample rate
  if Contrib::Analytics.enabled?(config[:analytics_enabled])
    Contrib::Analytics.set_sample_rate(span, config[:analytics_sample_rate])
  end

  span.set_tags(
    Datadog.configuration.tracing.header_tags.request_tags(request.headers.to_h)
  ) if Datadog.configuration.tracing.respond_to?(:header_tags)

  span
rescue StandardError => e
  Datadog.logger.error("error preparing span for http request: #{e}")
  Datadog.logger.error(e.backtrace)
end

.nowObject



145
146
147
# File 'lib/httpx/adapters/datadog.rb', line 145

def now
  ::Datadog::Core::Utils::Time.now.utc
end

Instance Method Details

#create_span(request, configuration, start_time) ⇒ Object



158
159
160
161
162
163
164
165
# File 'lib/httpx/adapters/datadog.rb', line 158

def create_span(request, configuration, start_time)
  Datadog::Tracing.trace(
    SPAN_REQUEST,
    service: service_name(request.uri.host, configuration),
    type: TYPE_OUTBOUND,
    start_time: start_time
  )
end

#propagate_trace_http(trace, headers) ⇒ Object



154
155
156
# File 'lib/httpx/adapters/datadog.rb', line 154

def propagate_trace_http(trace, headers)
  Datadog::Tracing::Contrib::HTTP.inject(trace, headers)
end