Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 62 lines (54 sloc) 2.253 kB
c7bf1c3 @jaggederest queue time, initial header work
jaggederest authored
1 module NewRelic
2 module Agent
3 module Instrumentation
1e068f4 @gnarg RUBY-1024 fixed and simplified WebFrontend/QueueTime metric recording
gnarg authored
4 # https://newrelic.com/docs/features/tracking-front-end-time
5 # Record queue time metrics based on any of three headers
6 # which can be set on the request.
c7bf1c3 @jaggederest queue time, initial header work
jaggederest authored
7 module QueueTime
f223dd4 @gnarg RUBY-1024 make sure not to define the queue time constants more than …
gnarg authored
8 unless defined?(REQUEST_START_HEADER)
9 REQUEST_START_HEADER = 'HTTP_X_REQUEST_START'
10 QUEUE_START_HEADER = 'HTTP_X_QUEUE_START'
11 QUEUE_DURATION_HEADER = 'HTTP_X_QUEUE_TIME'
12 MIDDLEWARE_START_HEADER = 'HTTP_X_MIDDLEWARE_START'
13 ALL_QUEUE_METRIC = 'WebFrontend/QueueTime'
59711d7 @gnarg RUBY-1024 make sure not to define the queue time constants more than …
gnarg authored
14 # any timestamps before this are thrown out and the parser
15 # will try again with a larger unit (2000/1/1 UTC)
16 EARLIEST_ACCEPTABLE_TIMESTAMP = 946684800
f223dd4 @gnarg RUBY-1024 make sure not to define the queue time constants more than …
gnarg authored
17 end
1e068f4 @gnarg RUBY-1024 fixed and simplified WebFrontend/QueueTime metric recording
gnarg authored
18
19 module_function
20
6cee6b5 @benweint RUBY-1024 Handle negative queue times caused by clock drift or miscon…
benweint authored
21 def parse_frontend_timestamp(headers, now=Time.now)
1e068f4 @gnarg RUBY-1024 fixed and simplified WebFrontend/QueueTime metric recording
gnarg authored
22 candidate_headers = [ REQUEST_START_HEADER, QUEUE_START_HEADER,
23 MIDDLEWARE_START_HEADER ]
6cee6b5 @benweint RUBY-1024 Handle negative queue times caused by clock drift or miscon…
benweint authored
24 earliest = candidate_headers.map do |header|
1e068f4 @gnarg RUBY-1024 fixed and simplified WebFrontend/QueueTime metric recording
gnarg authored
25 if headers[header]
26 parse_timestamp(timestamp_string_from_header_value(headers[header]))
27 end
28 end.compact.min
6cee6b5 @benweint RUBY-1024 Handle negative queue times caused by clock drift or miscon…
benweint authored
29
30 if earliest && earliest > now
31 NewRelic::Agent.logger.debug("Negative queue time detected, treating as zero: start=#{earliest.to_f} > now=#{now.to_f}")
32 earliest = now
33 end
34
35 earliest
1e068f4 @gnarg RUBY-1024 fixed and simplified WebFrontend/QueueTime metric recording
gnarg authored
36 end
37
38 def record_frontend_metrics(start_time, now=Time.now)
39 NewRelic::Agent.instance.stats_engine.get_stats(ALL_QUEUE_METRIC) \
40 .record_data_point((now - start_time).to_f)
41 end
42
43 def timestamp_string_from_header_value(value)
44 case value
45 when /^\s*([\d+\.]+)\s*$/ then $1
46 # following regexp intentionally unanchored to handle
47 # (ie ignore) leading server names
48 when /t=([\d+\.]+)/ then $1
aca6854 @jaggederest queue time finally actually measuring queue time, wip
jaggederest authored
49 end
c7bf1c3 @jaggederest queue time, initial header work
jaggederest authored
50 end
51
1e068f4 @gnarg RUBY-1024 fixed and simplified WebFrontend/QueueTime metric recording
gnarg authored
52 def parse_timestamp(string)
53 cut_off = Time.at(EARLIEST_ACCEPTABLE_TIMESTAMP)
54 [1_000_000, 1_000, 1].map do |divisor|
55 Time.at(string.to_f / divisor)
56 end.find {|candidate| candidate > cut_off }
c7bf1c3 @jaggederest queue time, initial header work
jaggederest authored
57 end
58 end
59 end
60 end
61 end
Something went wrong with that request. Please try again.