Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 79 lines (67 sloc) 2.625 kb
304fef1 @samg Add license header to source files
samg authored
1 # encoding: utf-8
2 # This file is distributed under New Relic's license terms.
3 # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
c7bf1c3 @jaggederest queue time, initial header work
jaggederest authored
5 module NewRelic
6 module Agent
7 module Instrumentation
1e068f4 @gnarg RUBY-1024 fixed and simplified WebFrontend/QueueTime metric recording
gnarg authored
8 # https://newrelic.com/docs/features/tracking-front-end-time
9 # Record queue time metrics based on any of three headers
10 # which can be set on the request.
c7bf1c3 @jaggederest queue time, initial header work
jaggederest authored
11 module QueueTime
f223dd4 @gnarg RUBY-1024 make sure not to define the queue time constants more than …
gnarg authored
12 unless defined?(REQUEST_START_HEADER)
c94e07e @benweint RUBY-1292 Reduce object allocations in QueueTime#parse_frontend_times…
benweint authored
13 REQUEST_START_HEADER = 'HTTP_X_REQUEST_START'.freeze
14 QUEUE_START_HEADER = 'HTTP_X_QUEUE_START'.freeze
15 MIDDLEWARE_START_HEADER = 'HTTP_X_MIDDLEWARE_START'.freeze
16 ALL_QUEUE_METRIC = 'WebFrontend/QueueTime'.freeze
59711d7 @gnarg RUBY-1024 make sure not to define the queue time constants more than …
gnarg authored
17 # any timestamps before this are thrown out and the parser
18 # will try again with a larger unit (2000/1/1 UTC)
6e0e275 @lexmag RUBY-1368 Reduce object allocations in `QueueTime` module
lexmag authored
19 EARLIEST_ACCEPTABLE_TIME = Time.at(946684800)
1e068f4 @gnarg RUBY-1024 fixed and simplified WebFrontend/QueueTime metric recording
gnarg authored
20
4ae02e7 @benweint RUBY-1292 Fix constant redefinition warnings on 1.8.x
benweint authored
21 CANDIDATE_HEADERS = [
22 REQUEST_START_HEADER,
23 QUEUE_START_HEADER,
24 MIDDLEWARE_START_HEADER
25 ].freeze
7e8b205 @benweint Avoid re-definition of DIVISORS constant on old Rubies
benweint authored
26
27 DIVISORS = [1_000_000, 1_000, 1]
4ae02e7 @benweint RUBY-1292 Fix constant redefinition warnings on 1.8.x
benweint authored
28 end
c94e07e @benweint RUBY-1292 Reduce object allocations in QueueTime#parse_frontend_times…
benweint authored
29
1e068f4 @gnarg RUBY-1024 fixed and simplified WebFrontend/QueueTime metric recording
gnarg authored
30 module_function
31
6cee6b5 @benweint RUBY-1024 Handle negative queue times caused by clock drift or miscon…
benweint authored
32 def parse_frontend_timestamp(headers, now=Time.now)
c94e07e @benweint RUBY-1292 Reduce object allocations in QueueTime#parse_frontend_times…
benweint authored
33 earliest = nil
34
35 CANDIDATE_HEADERS.each do |header|
1e068f4 @gnarg RUBY-1024 fixed and simplified WebFrontend/QueueTime metric recording
gnarg authored
36 if headers[header]
c94e07e @benweint RUBY-1292 Reduce object allocations in QueueTime#parse_frontend_times…
benweint authored
37 parsed = parse_timestamp(timestamp_string_from_header_value(headers[header]))
38 if parsed && (!earliest || parsed < earliest)
39 earliest = parsed
40 end
1e068f4 @gnarg RUBY-1024 fixed and simplified WebFrontend/QueueTime metric recording
gnarg authored
41 end
c94e07e @benweint RUBY-1292 Reduce object allocations in QueueTime#parse_frontend_times…
benweint authored
42 end
6cee6b5 @benweint RUBY-1024 Handle negative queue times caused by clock drift or miscon…
benweint authored
43
44 if earliest && earliest > now
45 NewRelic::Agent.logger.debug("Negative queue time detected, treating as zero: start=#{earliest.to_f} > now=#{now.to_f}")
46 earliest = now
47 end
48
49 earliest
1e068f4 @gnarg RUBY-1024 fixed and simplified WebFrontend/QueueTime metric recording
gnarg authored
50 end
51
52 def timestamp_string_from_header_value(value)
53 case value
54 when /^\s*([\d+\.]+)\s*$/ then $1
55 # following regexp intentionally unanchored to handle
56 # (ie ignore) leading server names
57 when /t=([\d+\.]+)/ then $1
aca6854 @jaggederest queue time finally actually measuring queue time, wip
jaggederest authored
58 end
c7bf1c3 @jaggederest queue time, initial header work
jaggederest authored
59 end
60
1e068f4 @gnarg RUBY-1024 fixed and simplified WebFrontend/QueueTime metric recording
gnarg authored
61 def parse_timestamp(string)
7afecac @benweint RUBY-1368 Further reduce object allocations in queue time parsing
benweint authored
62 DIVISORS.each do |divisor|
807a8bd @benweint RUBY-1024 Swallow RangeError when attempting to instantiate far-futur…
benweint authored
63 begin
7afecac @benweint RUBY-1368 Further reduce object allocations in queue time parsing
benweint authored
64 t = Time.at(string.to_f / divisor)
65 return t if t > EARLIEST_ACCEPTABLE_TIME
807a8bd @benweint RUBY-1024 Swallow RangeError when attempting to instantiate far-futur…
benweint authored
66 rescue RangeError
67 # On Ruby versions built with a 32-bit time_t, attempting to
68 # instantiate a Time object in the far future raises a RangeError,
69 # in which case we know we've chosen the wrong divisor.
70 end
7afecac @benweint RUBY-1368 Further reduce object allocations in queue time parsing
benweint authored
71 end
72
73 nil
c7bf1c3 @jaggederest queue time, initial header work
jaggederest authored
74 end
75 end
76 end
77 end
78 end
Something went wrong with that request. Please try again.