remnant 0.4.10 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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