Module: OneApm::Agent::Instrumentation::QueueTime

Defined in:
lib/one_apm/inst/support/queue_time.rb

Constant Summary collapse

OA_REQUEST_START_HEADER =
'HTTP_X_REQUEST_START'.freeze
OA_QUEUE_START_HEADER =
'HTTP_X_QUEUE_START'.freeze
OA_MIDDLEWARE_START_HEADER =
'HTTP_X_MIDDLEWARE_START'.freeze
OA_ALL_QUEUE_METRIC =
'WebFrontend/QueueTime'.freeze
OA_EARLIEST_ACCEPTABLE_TIME =

any timestamps before this are thrown out and the parser will try again with a larger unit (2000/1/1 UTC)

Time.at(946684800)
OA_CANDIDATE_HEADERS =
[
  OA_REQUEST_START_HEADER,
  OA_QUEUE_START_HEADER,
  OA_MIDDLEWARE_START_HEADER
].freeze
OA_DIVISORS =
[1_000_000, 1_000, 1]

Class Method Summary collapse

Class Method Details

.parse_frontend_timestamp(headers, now = Time.now) ⇒ Object



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/one_apm/inst/support/queue_time.rb', line 27

def parse_frontend_timestamp(headers, now=Time.now)
  earliest = nil

  OA_CANDIDATE_HEADERS.each do |header|
    if headers[header]
      parsed = parse_timestamp(timestamp_string_from_header_value(headers[header]))
      if parsed && (!earliest || parsed < earliest)
        earliest = parsed
      end
    end
  end

  if earliest && earliest > now
    OneApm::Manager.logger.debug("Negative queue time detected, treating as zero: start=#{earliest.to_f} > now=#{now.to_f}")
    earliest = now
  end

  earliest
end

.parse_timestamp(string) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/one_apm/inst/support/queue_time.rb', line 56

def parse_timestamp(string)
  OA_DIVISORS.each do |divisor|
    begin
      t = Time.at(string.to_f / divisor)
      return t if t > OA_EARLIEST_ACCEPTABLE_TIME
    rescue RangeError
      # On Ruby versions built with a 32-bit time_t, attempting to
      # instantiate a Time object in the far future raises a RangeError,
      # in which case we know we've chosen the wrong divisor.
    end
  end

  nil
end

.timestamp_string_from_header_value(value) ⇒ Object



47
48
49
50
51
52
53
54
# File 'lib/one_apm/inst/support/queue_time.rb', line 47

def timestamp_string_from_header_value(value)
  case value
  when /^\s*([\d+\.]+)\s*$/ then $1
  # following regexp intentionally unanchored to handle
  # (ie ignore) leading server names
  when /t=([\d+\.]+)/       then $1
  end
end