remnant 0.4.10 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- remnant (0.4.5)
4
+ remnant (0.3.2)
5
5
  statsd-ruby (= 1.0.0)
6
6
 
7
7
  GEM
data/lib/remnant/base.rb CHANGED
@@ -1,5 +1,17 @@
1
1
  class Remnant
2
2
  module ClassMethods
3
+ def disable!
4
+ @enabled = false
5
+ end
6
+
7
+ def enable!
8
+ @enabled = true
9
+ end
10
+
11
+ def enabled?
12
+ @enabled
13
+ end
14
+
3
15
  def color(default = false, heading = false)
4
16
  return "\033[0m" if default
5
17
  return "\033[0;01;33m" if heading
@@ -28,10 +40,28 @@ class Remnant
28
40
 
29
41
  extra_remnant_key = Remnant::Discover.results.delete(:extra_remnant_key)
30
42
 
31
- # process special queue times
32
- ::Remnant::Queue.process!
43
+ if ::Rails.env.production? || ::Rails.env.staging? || ::Rails.env.demo?
44
+ # only log if above sample rate
45
+ if @sample_counter > configuration.sample_rate
46
+ key_prefix = [
47
+ Remnant.configuration.tag,
48
+ Remnant.configuration.env,
49
+ extra_remnant_key
50
+ ].compact.join('.')
51
+
52
+ Remnant::Discover.results.map do |remnant_key, ms|
53
+ Remnant.handler.timing("#{key_prefix}.#{remnant_key}", ms.to_i)
54
+ end
55
+
56
+ Remnant.handler.timing("#{key_prefix}.gc", Remnant::GC.time.to_i)
57
+ Remnant.handler.timing("#{key_prefix}.db", Remnant::Database.total_time.to_i)
58
+ Remnant.handler.timing("#{key_prefix}.filters", Remnant::Filters.total_time.to_i)
33
59
 
34
- if ::Rails.env.development? || ::Rails.env.test?
60
+ @sample_counter = 0
61
+ else
62
+ @sample_counter += 1
63
+ end
64
+ else
35
65
  # always log in development mode
36
66
  Rails.logger.info "#{color(false, true)}--------------Remnants Discovered--------------#{color(true)}"
37
67
 
@@ -73,27 +103,6 @@ class Remnant
73
103
  end
74
104
 
75
105
  Rails.logger.info "#{color(false, true)}-----------------------------------------------#{color(true)}"
76
- else
77
- # only log if above sample rate
78
- if @sample_counter > configuration.sample_rate
79
- key_prefix = [
80
- Remnant.configuration.tag,
81
- Remnant.configuration.env,
82
- extra_remnant_key
83
- ].compact.join('.')
84
-
85
- Remnant::Discover.results.map do |remnant_key, ms|
86
- Remnant.handler.timing("#{key_prefix}.#{remnant_key}", ms.to_i)
87
- end
88
-
89
- Remnant.handler.timing("#{key_prefix}.gc", Remnant::GC.time.to_i)
90
- Remnant.handler.timing("#{key_prefix}.db", Remnant::Database.total_time.to_i)
91
- Remnant.handler.timing("#{key_prefix}.filters", Remnant::Filters.total_time.to_i)
92
-
93
- @sample_counter = 0
94
- else
95
- @sample_counter += 1
96
- end
97
106
  end
98
107
 
99
108
  # run hook if given
@@ -2,17 +2,12 @@ class Remnant
2
2
  class Filters
3
3
  module ClassMethods
4
4
  def record(filter_type, filter_name, &block)
5
- # ignore AroundFilters
6
- if filter_type.to_s == 'ActionController::Filters::AroundFilter'
7
- return block.call
8
- else
9
- start_time = Time.now
10
- result = block.call
11
- time = Time.now - start_time
12
- filters << {:type => filter_type, :name => filter_name, :time => time, :ms => time * 1000}
5
+ start_time = Time.now
6
+ result = block.call
7
+ time = Time.now - start_time
8
+ filters << {:type => filter_type, :name => filter_name, :time => time, :ms => time * 1000}
13
9
 
14
- return result
15
- end
10
+ return result
16
11
  end
17
12
 
18
13
  def reset
@@ -1,18 +1,22 @@
1
1
  class Remnant
2
2
  class GC
3
- class Mri
3
+ class Profiler
4
4
  module ClassMethods
5
5
  def enabled?
6
- true
6
+ ::GC::Profiler.enabled?
7
7
  end
8
8
 
9
9
  def time
10
- # returns time in seconds, so convert to ms
11
- ::GC::Profiler.total_time * 1000
10
+ # returns time in seconds so convert to ms
11
+ @time ||= raw_data.map {|data| data[:GC_TIME]}.sum * 1000
12
+ end
13
+
14
+ def raw_data
15
+ @raw_data ||= ::GC::Profiler.raw_data || []
12
16
  end
13
17
 
14
18
  def collections
15
- ::GC::Profiler.raw_data.try(:size) || 0
19
+ raw_data.size
16
20
  end
17
21
 
18
22
  def enable_stats
@@ -24,6 +28,7 @@ class Remnant
24
28
  end
25
29
 
26
30
  def clear_stats
31
+ @raw_data = nil
27
32
  ::GC::Profiler.clear
28
33
  end
29
34
  end
data/lib/remnant/gc.rb CHANGED
@@ -30,14 +30,12 @@ class Remnant
30
30
  end
31
31
 
32
32
  def _gc_implementation
33
- if RUBY_VERSION >= '2.1.0'
34
- Remnant::GC::Mri
33
+ if ::GC.respond_to?(:time) && ::GC.respond_to?(:collections)
34
+ Remnant::GC::Ree
35
+ elsif defined?(::GC::Profiler)
36
+ Remnant::GC::Profiler
35
37
  else
36
- if ::GC.respond_to?(:time) && ::GC.respond_to?(:collections)
37
- Remnant::GC::Ree
38
- else
39
- Remnant::GC::Base
40
- end
38
+ Remnant::GC::Base
41
39
  end
42
40
  end
43
41
  end
@@ -0,0 +1,46 @@
1
+ class Remnant
2
+ class Rack
3
+ def initialize(app)
4
+ @app = app
5
+ end
6
+
7
+ def call(env)
8
+ @response = [500, '', '']
9
+
10
+ if env['REQUEST_PATH'].include?('/asset')
11
+ @response = @app.call(env)
12
+ else
13
+
14
+ begin
15
+ # only gc capture as dev
16
+ if env['rack.request.cookie_hash']['developer']
17
+ ::Remnant::GC.enable_stats
18
+ end
19
+
20
+ # record request time
21
+ ::Remnant::Discover.measure('request') do
22
+ @response = @app.call(env)
23
+ end
24
+
25
+ # collect & clear stats for next request
26
+ ::Remnant.collect
27
+
28
+ # only gc capture as dev
29
+ if env['rack.request.cookie_hash']['developer']
30
+ ::Remnant::GC.clear_stats
31
+ end
32
+
33
+ ::Rails.logger.flush if ::Rails.logger.respond_to?(:flush)
34
+ rescue ::Exception => exception
35
+ if defined?(Flail)
36
+ Flail::Exception.new(env, exception).handle!
37
+ end
38
+
39
+ raise
40
+ end
41
+ end
42
+
43
+ @response
44
+ end
45
+ end
46
+ end
data/lib/remnant/rails.rb CHANGED
@@ -32,30 +32,13 @@ class Remnant
32
32
  #
33
33
 
34
34
  # hook remnants
35
- Remnant::Discover.find('request', ActionController::Dispatcher, :call)
36
- Remnant::Discover.find('action', ActionController::Base, :perform_action)
35
+ Remnant::Discover.find('action', ActionController::Base, :process_action)
37
36
  Remnant::Discover.find('view', ActionController::Base, :render)
38
37
 
39
38
  #
40
39
  # Filter capturing
41
40
  #
42
- [
43
- ActionController::Filters::BeforeFilter,
44
- ActionController::Filters::AfterFilter,
45
- ActionController::Filters::AroundFilter
46
- ].map do |remnant_constant|
47
- Remnant::Discover.find_with(remnant_constant) do
48
- remnant_constant.class_eval do
49
- def call_with_remnant(*args, &block)
50
- ::Remnant::Filters.record(self.class.to_s, method.to_s) do
51
- call_without_remnant(*args, &block)
52
- end
53
- end
54
-
55
- alias_method_chain :call, :remnant
56
- end
57
- end
58
- end
41
+ # TODO
59
42
 
60
43
  #
61
44
  # Template rendering
@@ -63,13 +46,13 @@ class Remnant
63
46
  if defined?(ActionView) && defined?(ActionView::Template)
64
47
  Remnant::Discover.find_with(ActionView::Template) do
65
48
  ActionView::Template.class_eval do
66
- def render_template_with_remnant(*args, &block)
67
- ::Remnant::Template.record(path_without_format_and_extension) do
68
- render_template_without_remnant(*args, &block)
49
+ def render_with_remnant(*args, &block)
50
+ ::Remnant::Template.record(@virtual_path) do
51
+ render_without_remnant(*args, &block)
69
52
  end
70
53
  end
71
54
 
72
- alias_method_chain :render_template, :remnant
55
+ alias_method_chain :render, :remnant
73
56
  end
74
57
  end
75
58
  end
@@ -77,52 +60,11 @@ class Remnant
77
60
  #
78
61
  # database query time
79
62
  #
80
- if ::Rails::VERSION::MAJOR == 2
81
- Remnant::Discover.find_with(ActiveRecord::ConnectionAdapters::AbstractAdapter) do
82
- ActiveRecord::ConnectionAdapters::AbstractAdapter.class_eval do
83
- def log_with_remnant(sql, name, &block)
84
- ::Remnant::Database.record(sql, Kernel.caller) do
85
- log_without_remnant(sql, name, &block)
86
- end
87
- end
88
-
89
- alias_method_chain :log, :remnant
90
- end
91
- end
92
- end
93
-
94
- # last hook into request cycle for sending results
95
- ::ActionController::Dispatcher.class_eval do
96
- def call_with_remnant_discovery(*args, &block) #:nodoc:
97
- ::Remnant::GC.enable_stats
98
- call_without_remnant_discovery(*args, &block).tap do |status, headers, response|
99
- ::Remnant::GC.disable_stats
100
- begin
101
- ::Remnant.collect
102
- ::Remnant::GC.clear_stats
103
- ::Rails.logger.flush if ::Rails.logger.respond_to? :flush
104
- rescue Exception => e
105
- if defined?(::Flail)
106
- Flail::Exception.notify(e)
107
- else
108
- Rails.logger.error e.inspect
109
- end
110
- end
111
- end
112
- end
113
- alias_method_chain :call, :remnant_discovery
114
- end
63
+ ActiveSupport::Notifications.subscribe("sql.active_record") do |name, started, ended, id, payload|
64
+ duration = ended - started
65
+ trace = ::Rails.backtrace_cleaner.clean(Kernel.caller[1..-1])
115
66
 
116
- # hook into perform_action for the extra remnant key
117
- ::ActionController::Base.class_eval do
118
- def perform_action_with_remnant_key(*args, &block) #:nodoc:
119
- ::Remnant::Discover.results['lb_queue_start'] = ::Remnant::Queue.parse_frontend_timestamp(request.headers, 'lb')
120
- ::Remnant::Discover.results['fe_queue_start'] = ::Remnant::Queue.parse_frontend_timestamp(request.headers, 'fe')
121
- ::Remnant::Discover.results['app_queue_start'] = request.env['process.request_start'] || Time.now.to_f
122
-
123
- perform_action_without_remnant_key(*args, &block)
124
- end
125
- alias_method_chain :perform_action, :remnant_key
67
+ ::Remnant::Database.queries << ::Remnant::Database::Query.new(payload[:sql], duration, trace)
126
68
  end
127
69
  end # setup!
128
70
  end
@@ -1,7 +1,11 @@
1
1
  class Remnant
2
2
  class Railtie < ::Rails::Railtie
3
+ initializer "remnant.use_rack_middleware" do |app|
4
+ app.config.middleware.use ::Remnant::Rack
5
+ end
6
+
3
7
  config.after_initialize do
4
- Remnant::Rails.setup!
8
+ ::Remnant::Rails.setup!
5
9
  end
6
10
  end
7
11
  end
@@ -1,3 +1,3 @@
1
1
  class Remnant
2
- VERSION = "0.4.10"
2
+ VERSION = "0.9.0"
3
3
  end
data/lib/remnant.rb CHANGED
@@ -7,7 +7,7 @@ require 'remnant/discover'
7
7
  require 'remnant/gc'
8
8
  require 'remnant/gc/base'
9
9
  require 'remnant/gc/ree'
10
- require 'remnant/gc/mri'
10
+ require 'remnant/gc/profiler'
11
11
 
12
12
  require 'remnant/filters'
13
13
 
@@ -18,9 +18,9 @@ require 'remnant/template/rendering'
18
18
  require 'remnant/database'
19
19
  require 'remnant/database/query'
20
20
 
21
- require 'remnant/queue'
22
-
21
+ require 'remnant/rack'
23
22
  require 'remnant/rails'
23
+
24
24
  require 'remnant/version'
25
25
 
26
26
  require 'remnant/railtie' if defined?(::Rails::Railtie)
data/spec/spec_helper.rb CHANGED
@@ -9,8 +9,8 @@ RSpec.configure do |config|
9
9
  config.mock_with :rr
10
10
  end
11
11
 
12
- require 'active_support'
13
12
  require 'action_controller'
13
+ require 'active_support'
14
14
 
15
15
  require 'remnant'
16
16
 
metadata CHANGED
@@ -1,141 +1,136 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: remnant
3
- version: !ruby/object:Gem::Version
4
- hash: 27
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 4
9
- - 10
10
- version: 0.4.10
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - John 'asceth' Long
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2015-03-23 00:00:00 -04:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2013-07-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: statsd-ruby
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
27
- - - "="
28
- - !ruby/object:Gem::Version
29
- hash: 23
30
- segments:
31
- - 1
32
- - 0
33
- - 0
18
+ requirements:
19
+ - - '='
20
+ - !ruby/object:Gem::Version
34
21
  version: 1.0.0
35
22
  type: :runtime
36
- version_requirements: *id001
37
- - !ruby/object:Gem::Dependency
38
- name: actionpack
39
23
  prerelease: false
40
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: !ruby/object:Gem::Requirement
41
25
  none: false
42
- requirements:
26
+ requirements:
27
+ - - '='
28
+ - !ruby/object:Gem::Version
29
+ version: 1.0.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: actionpack
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
43
35
  - - ~>
44
- - !ruby/object:Gem::Version
45
- hash: 19
46
- segments:
47
- - 2
48
- - 3
49
- - 8
36
+ - !ruby/object:Gem::Version
50
37
  version: 2.3.8
51
38
  type: :development
52
- version_requirements: *id002
53
- - !ruby/object:Gem::Dependency
54
- name: activerecord
55
39
  prerelease: false
56
- requirement: &id003 !ruby/object:Gem::Requirement
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.3.8
46
+ - !ruby/object:Gem::Dependency
47
+ name: activerecord
48
+ requirement: !ruby/object:Gem::Requirement
57
49
  none: false
58
- requirements:
50
+ requirements:
59
51
  - - ~>
60
- - !ruby/object:Gem::Version
61
- hash: 19
62
- segments:
63
- - 2
64
- - 3
65
- - 8
52
+ - !ruby/object:Gem::Version
66
53
  version: 2.3.8
67
54
  type: :development
68
- version_requirements: *id003
69
- - !ruby/object:Gem::Dependency
70
- name: activesupport
71
55
  prerelease: false
72
- requirement: &id004 !ruby/object:Gem::Requirement
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 2.3.8
62
+ - !ruby/object:Gem::Dependency
63
+ name: activesupport
64
+ requirement: !ruby/object:Gem::Requirement
73
65
  none: false
74
- requirements:
66
+ requirements:
75
67
  - - ~>
76
- - !ruby/object:Gem::Version
77
- hash: 19
78
- segments:
79
- - 2
80
- - 3
81
- - 8
68
+ - !ruby/object:Gem::Version
82
69
  version: 2.3.8
83
70
  type: :development
84
- version_requirements: *id004
85
- - !ruby/object:Gem::Dependency
86
- name: rake
87
71
  prerelease: false
88
- requirement: &id005 !ruby/object:Gem::Requirement
72
+ version_requirements: !ruby/object:Gem::Requirement
89
73
  none: false
90
- requirements:
91
- - - ">="
92
- - !ruby/object:Gem::Version
93
- hash: 3
94
- segments:
95
- - 0
96
- version: "0"
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 2.3.8
78
+ - !ruby/object:Gem::Dependency
79
+ name: rake
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
97
86
  type: :development
98
- version_requirements: *id005
99
- - !ruby/object:Gem::Dependency
100
- name: rspec
101
87
  prerelease: false
102
- requirement: &id006 !ruby/object:Gem::Requirement
88
+ version_requirements: !ruby/object:Gem::Requirement
103
89
  none: false
104
- requirements:
105
- - - ">="
106
- - !ruby/object:Gem::Version
107
- hash: 3
108
- segments:
109
- - 0
110
- version: "0"
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rspec
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
111
102
  type: :development
112
- version_requirements: *id006
113
- - !ruby/object:Gem::Dependency
114
- name: rr
115
103
  prerelease: false
116
- requirement: &id007 !ruby/object:Gem::Requirement
104
+ version_requirements: !ruby/object:Gem::Requirement
117
105
  none: false
118
- requirements:
119
- - - ">="
120
- - !ruby/object:Gem::Version
121
- hash: 3
122
- segments:
123
- - 0
124
- version: "0"
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rr
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
125
118
  type: :development
126
- version_requirements: *id007
127
- description: Remnant - peering into your ruby apps and discovering statistics you never knew could be so awful...
128
- email:
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ description: Remnant - peering into your ruby apps and discovering statistics you
127
+ never knew could be so awful...
128
+ email:
129
129
  - machinist@asceth.com
130
130
  executables: []
131
-
132
131
  extensions: []
133
-
134
132
  extra_rdoc_files: []
135
-
136
- files:
137
- - .gitignore
138
- - .ruby-version
133
+ files:
139
134
  - .rvmrc
140
135
  - Gemfile
141
136
  - Gemfile.lock
@@ -151,9 +146,9 @@ files:
151
146
  - lib/remnant/filters.rb
152
147
  - lib/remnant/gc.rb
153
148
  - lib/remnant/gc/base.rb
154
- - lib/remnant/gc/mri.rb
149
+ - lib/remnant/gc/profiler.rb
155
150
  - lib/remnant/gc/ree.rb
156
- - lib/remnant/queue.rb
151
+ - lib/remnant/rack.rb
157
152
  - lib/remnant/rails.rb
158
153
  - lib/remnant/railtie.rb
159
154
  - lib/remnant/template.rb
@@ -167,41 +162,31 @@ files:
167
162
  - spec/discover_spec.rb
168
163
  - spec/spec_helper.rb
169
164
  - spec/support/rr.rb
170
- has_rdoc: true
171
165
  homepage: https://github.com/asceth/remnant
172
166
  licenses: []
173
-
174
167
  post_install_message:
175
168
  rdoc_options: []
176
-
177
- require_paths:
169
+ require_paths:
178
170
  - lib
179
- required_ruby_version: !ruby/object:Gem::Requirement
171
+ required_ruby_version: !ruby/object:Gem::Requirement
180
172
  none: false
181
- requirements:
182
- - - ">="
183
- - !ruby/object:Gem::Version
184
- hash: 3
185
- segments:
186
- - 0
187
- version: "0"
188
- required_rubygems_version: !ruby/object:Gem::Requirement
173
+ requirements:
174
+ - - ! '>='
175
+ - !ruby/object:Gem::Version
176
+ version: '0'
177
+ required_rubygems_version: !ruby/object:Gem::Requirement
189
178
  none: false
190
- requirements:
191
- - - ">="
192
- - !ruby/object:Gem::Version
193
- hash: 3
194
- segments:
195
- - 0
196
- version: "0"
179
+ requirements:
180
+ - - ! '>='
181
+ - !ruby/object:Gem::Version
182
+ version: '0'
197
183
  requirements: []
198
-
199
184
  rubyforge_project: remnant
200
- rubygems_version: 1.6.2
185
+ rubygems_version: 1.8.23
201
186
  signing_key:
202
187
  specification_version: 3
203
188
  summary: Rails statistical discoverer
204
- test_files:
189
+ test_files:
205
190
  - spec/app/some/klass.rb
206
191
  - spec/app/some/module.rb
207
192
  - spec/base_spec.rb
data/.gitignore DELETED
@@ -1,2 +0,0 @@
1
- vendor/
2
- .bundle/
data/.ruby-version DELETED
@@ -1 +0,0 @@
1
- 1.8.7-p375
data/lib/remnant/queue.rb DELETED
@@ -1,95 +0,0 @@
1
- #
2
- # majority of this code comes from NewRelic RPM
3
- #
4
- class Remnant
5
- class Queue
6
- FRONTEND_START_HEADER = 'HTTP_X_FRONTEND_START'.freeze
7
- LOAD_BALANCED_START_HEADER = 'HTTP_X_LOAD_BALANCER_START'.freeze
8
-
9
- START_HEADERS = {
10
- 'lb' => [
11
- LOAD_BALANCED_START_HEADER
12
- ],
13
- 'fe' => [
14
- FRONTEND_START_HEADER
15
- ]
16
- }.freeze
17
-
18
- # any timestamps before this are thrown out and the parser
19
- # will try again with a larger unit (2000/1/1 UTC)
20
- EARLIEST_ACCEPTABLE_TIME = 946684800
21
-
22
-
23
- class << self
24
- def process!
25
- lb_queue_start = ::Remnant::Discover.results.delete('lb_queue_start')
26
- fe_queue_start = ::Remnant::Discover.results.delete('fe_queue_start')
27
- app_queue_start = ::Remnant::Discover.results.delete('app_queue_start')
28
-
29
- if lb_queue_start && fe_queue_start
30
- secs = fe_queue_start - lb_queue_start
31
-
32
- # if negative, clamp to 0
33
- if secs < 0.0
34
- secs = 0
35
- end
36
-
37
- ::Remnant::Discover.results['queue_lb'] = (secs * 1_000.0).round(2) # ms
38
- end
39
-
40
- if fe_queue_start && app_queue_start
41
- secs = app_queue_start - fe_queue_start
42
-
43
- # if negative, clamp to 0
44
- if secs < 0.0
45
- secs = 0
46
- end
47
-
48
- ::Remnant::Discover.results['queue_fe'] = (secs * 1_000.0).round(2) # ms
49
- end
50
- end
51
-
52
- def parse_frontend_timestamp(headers, role, unit = :second, now = Time.now.to_f)
53
- now = now.to_f if now.is_a?(Time)
54
- earliest = nil
55
-
56
- (START_HEADERS[role] || []).map do |header|
57
- if headers[header]
58
- parsed = parse_timestamp(timestamp_string_from_header_value(headers[header]), unit)
59
-
60
- if parsed && (!earliest || parsed < earliest)
61
- earliest = parsed
62
- end
63
- end
64
- end
65
-
66
- if earliest && earliest > now
67
- earliest = now
68
- end
69
-
70
- earliest
71
- end
72
-
73
- def timestamp_string_from_header_value(value)
74
- case value
75
- when /^\s*([\d+\.]+)\s*$/ then $1
76
- # following regexp intentionally unanchored to handle
77
- # (ie ignore) leading server names
78
- when /t=([\d+\.]+)/ then $1
79
- end
80
- end
81
-
82
- # bring everything into a seconds with millisecond precision
83
- def parse_timestamp(string, unit = :second)
84
- case unit
85
- when :second
86
- string.to_f
87
- when :millisecond
88
- string.to_f / 1_000
89
- when :microsecond
90
- string.to_f / 1_000_000
91
- end
92
- end
93
- end
94
- end
95
- end