Class: RequestQueueTime::Middleware::Metrics

Inherits:
Object
  • Object
show all
Defined in:
lib/request_queue_time/middleware.rb

Constant Summary collapse

MILLISECONDS_CUTOFF =
Time.new(2000, 1, 1).to_i * 1000
MICROSECONDS_CUTOFF =
MILLISECONDS_CUTOFF * 1000
NANOSECONDS_CUTOFF =
MICROSECONDS_CUTOFF * 1000
REQUEST_SIZE_LIMIT_BYTES =
100_000

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(env) ⇒ Metrics

Returns a new instance of Metrics.



43
44
45
46
47
48
# File 'lib/request_queue_time/middleware.rb', line 43

def initialize(env)
  @network_time = env["puma.request_body_wait"].to_i
  @request_start = env["HTTP_X_REQUEST_START"]
  @now = Time.now
  @request_size = env["rack.input"].respond_to?(:size) ? env["rack.input"].size : 0
end

Instance Attribute Details

#network_timeObject (readonly)

Returns the value of attribute network_time.



41
42
43
# File 'lib/request_queue_time/middleware.rb', line 41

def network_time
  @network_time
end

#nowObject (readonly)

Returns the value of attribute now.



41
42
43
# File 'lib/request_queue_time/middleware.rb', line 41

def now
  @now
end

#request_sizeObject (readonly)

Returns the value of attribute request_size.



41
42
43
# File 'lib/request_queue_time/middleware.rb', line 41

def request_size
  @request_size
end

#request_startObject (readonly)

Returns the value of attribute request_start.



41
42
43
# File 'lib/request_queue_time/middleware.rb', line 41

def request_start
  @request_start
end

Instance Method Details

#ignore?Boolean

Returns:

  • (Boolean)


50
51
52
# File 'lib/request_queue_time/middleware.rb', line 50

def ignore?
  queue_time.nil? || request_size > REQUEST_SIZE_LIMIT_BYTES
end

#queue_timeObject



54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/request_queue_time/middleware.rb', line 54

def queue_time
  return @queue_time if defined?(@queue_time)

  start = started_at
  return if start.nil?

  queue_time = ((now - start) * 1000).to_i

  # Remove the time Puma was waiting for the request body.
  queue_time -= network_time

  @queue_time = (queue_time > 0) ? queue_time : 0
end

#started_atObject



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/request_queue_time/middleware.rb', line 68

def started_at
  if request_start
    # There are several variants of this header. We handle these:
    #   - whole milliseconds (Heroku)
    #   - whole microseconds (???)
    #   - whole nanoseconds (Render)
    #   - fractional seconds (NGINX)
    #   - preceeding "t=" (NGINX)
    value = request_start.gsub(/[^0-9.]/, "").to_f

    # `value` could be seconds, milliseconds, microseconds or nanoseconds.
    # We use some arbitrary cutoffs to determine which one it is.

    if value > NANOSECONDS_CUTOFF
      Time.at(value / 1_000_000_000.0)
    elsif value > MICROSECONDS_CUTOFF
      Time.at(value / 1_000_000.0)
    elsif value > MILLISECONDS_CUTOFF
      Time.at(value / 1000.0)
    else
      Time.at(value)
    end
  end
end