Module: LogBrew::HttpClientTracing

Defined in:
lib/logbrew/http_client_tracing.rb

Defined Under Namespace

Classes: FaradayHeaderSnapshot, NetHttpHeaderSnapshot

Class Method Summary collapse

Class Method Details

.active_operation?Boolean

Returns:

  • (Boolean)


233
234
235
# File 'lib/logbrew/http_client_tracing.rb', line 233

def active_operation?
  !Thread.current[ACTIVE_OPERATION_KEY].nil?
end

.capture_net_http(http, request, client:, on_capture_error: nil) ⇒ Object



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/logbrew/http_client_tracing.rb', line 168

def capture_net_http(http, request, client:, on_capture_error: nil)
  prepared = prepare(client: client, source: "net_http", on_capture_error: on_capture_error) do
    [request.method, http.address, NetHttpHeaderSnapshot.new(request)]
  end
  return yield unless prepared

  operation, header = prepared
  begin
    header.inject(operation.traceparent)
  rescue StandardError => error
    operation.capture_error(error)
    reset_header(header, operation)
    return yield
  end

  response = nil
  begin
    response = operation.around { yield }
  rescue StandardError => error
    operation.finish(error: error)
    raise
  ensure
    reset_header(header, operation)
  end
  operation.finish(status_code: read_status(response, :code, operation))
  response
end

.monotonic_timeObject



278
279
280
# File 'lib/logbrew/http_client_tracing.rb', line 278

def monotonic_time
  Process.clock_gettime(Process::CLOCK_MONOTONIC)
end

.normalize_host(host) ⇒ Object



246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/logbrew/http_client_tracing.rb', line 246

def normalize_host(host)
  value = host.to_s.strip.downcase.sub(/\.+\z/, "")
  return nil if value.empty? || value.bytesize > 253
  return nil if value.match?(/\A[0-9.]+\z/)
  return nil unless value.match?(/\A[a-z0-9](?:[a-z0-9.-]*[a-z0-9])?\z/)

  begin
    IPAddr.new(value)
    nil
  rescue IPAddr::InvalidAddressError
    value
  end
end

.normalize_method(method) ⇒ Object



241
242
243
244
# File 'lib/logbrew/http_client_tracing.rb', line 241

def normalize_method(method)
  value = method.to_s.strip.upcase
  value.empty? ? "HTTP" : value[0, 32]
end

.normalize_status_code(status_code) ⇒ Object



260
261
262
263
# File 'lib/logbrew/http_client_tracing.rb', line 260

def normalize_status_code(status_code)
  value = status_code.to_i
  value.positive? && value <= 999 ? value : nil
end

.prepare(client:, source:, on_capture_error: nil) ⇒ Object



196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# File 'lib/logbrew/http_client_tracing.rb', line 196

def prepare(client:, source:, on_capture_error: nil)
  parent = Trace.current
  return nil unless parent
  return nil if suppressed? || active_operation?
  return nil unless SOURCES.include?(source)

  method, host, header = yield
  operation = HttpClientTraceOperation.new(
    client: client,
    parent: parent,
    source: source,
    method: method,
    host: host,
    on_capture_error: on_capture_error
  )
  [operation, header]
rescue StandardError => error
  report_capture_error(on_capture_error, error)
  nil
end

.read_status(response, method, operation) ⇒ Object



265
266
267
268
269
270
# File 'lib/logbrew/http_client_tracing.rb', line 265

def read_status(response, method, operation)
  response.public_send(method)
rescue StandardError => error
  operation.capture_error(error)
  nil
end

.report_capture_error(callback, error) ⇒ Object



282
283
284
285
286
# File 'lib/logbrew/http_client_tracing.rb', line 282

def report_capture_error(callback, error)
  callback.call(error) if callback.respond_to?(:call)
rescue StandardError
  nil
end

.reset_header(header, operation) ⇒ Object



272
273
274
275
276
# File 'lib/logbrew/http_client_tracing.rb', line 272

def reset_header(header, operation)
  header.reset
rescue StandardError => error
  operation.capture_error(error)
end

.suppressObject



225
226
227
228
229
230
231
# File 'lib/logbrew/http_client_tracing.rb', line 225

def suppress
  previous = Thread.current[SUPPRESSION_KEY]
  Thread.current[SUPPRESSION_KEY] = true
  yield
ensure
  Thread.current[SUPPRESSION_KEY] = previous
end

.suppressed?Boolean

Returns:

  • (Boolean)


237
238
239
# File 'lib/logbrew/http_client_tracing.rb', line 237

def suppressed?
  Thread.current[SUPPRESSION_KEY] == true
end

.with_operation(operation) ⇒ Object



217
218
219
220
221
222
223
# File 'lib/logbrew/http_client_tracing.rb', line 217

def with_operation(operation)
  previous = Thread.current[ACTIVE_OPERATION_KEY]
  Thread.current[ACTIVE_OPERATION_KEY] = operation
  Trace.with_context(operation.context) { yield }
ensure
  Thread.current[ACTIVE_OPERATION_KEY] = previous
end

.wrap_net_http(http, client:, on_capture_error: nil) ⇒ Object



162
163
164
165
166
# File 'lib/logbrew/http_client_tracing.rb', line 162

def wrap_net_http(http, client:, on_capture_error: nil)
  return http if http.is_a?(NetHttpTracingClient)

  NetHttpTracingClient.new(http, client: client, on_capture_error: on_capture_error)
end