metriks-middleware 1.3.0 → 2.0.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 CHANGED
@@ -1,3 +1,3 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
@@ -2,7 +2,17 @@ require 'metriks'
2
2
 
3
3
  module Metriks
4
4
  class Middleware
5
- VERSION = '1.3.0'
5
+ VERSION = '2.0.0'
6
+
7
+ REQUEST_DELAY = 'request_delay'
8
+ HEROKU_DYNOS_IN_USE = 'heroku.dynos_in_use'
9
+ ERROR_RESPONSE = 'responses.error'
10
+ NOT_FOUND_RESPONSE = 'responses.not_found'
11
+ NOT_MODIFIED_RESPONSE = 'responses.not_modified'
12
+ CONTENT_LENGTH = 'responses.content_length'
13
+
14
+ REQUEST_START_HEADER = 'HTTP_X_REQUEST_START'
15
+ HEROKU_DYNOS_IN_USE_HEADER = 'HTTP_X_HEROKU_DYNOS_IN_USE'
6
16
 
7
17
  def initialize(app)
8
18
  @app = app
@@ -10,8 +20,9 @@ module Metriks
10
20
 
11
21
  def call(env)
12
22
  time_response(env) do
13
- record_heroku_status env
14
- record_error_rate env
23
+ record_request_delay env
24
+ record_heroku_dynos_in_use env
25
+ record_response env
15
26
  call_downstream env
16
27
  end
17
28
  end
@@ -28,20 +39,21 @@ module Metriks
28
39
  end
29
40
  end
30
41
 
31
- def record_heroku_status(env)
32
- queue_wait = env['HTTP_X_HEROKU_QUEUE_WAIT_TIME']
33
- queue_depth = env['HTTP_X_HEROKU_QUEUE_DEPTH']
34
- dynos_in_use = env['HTTP_X_HEROKU_DYNOS_IN_USE']
42
+ def record_request_delay(env)
43
+ delay = duration_since_request_start(env)
44
+ Metriks.histogram(REQUEST_DELAY).update(delay)
45
+ end
35
46
 
36
- Metriks.histogram("queue.wait") .update(queue_wait.to_i) if queue_wait
37
- Metriks.histogram("queue.depth") .update(queue_depth.to_i) if queue_depth
38
- Metriks.histogram("dynos.in_use").update(dynos_in_use.to_i) if dynos_in_use
47
+ def record_heroku_dynos_in_use(env)
48
+ dynos = env[HEROKU_DYNOS_IN_USE_HEADER]
49
+ return unless dynos
50
+ Metriks.histogram(HEROKU_DYNOS_IN_USE).update(dynos.to_i)
39
51
  end
40
52
 
41
- def record_error_rate(env)
53
+ def record_response(env)
42
54
  original_callback = env['async.callback']
43
55
  env['async.callback'] = lambda do |(status, headers, body)|
44
- record_error status
56
+ record_staus_code status
45
57
  record_content_length headers
46
58
  original_callback.call [status, headers, body]
47
59
  end
@@ -49,30 +61,37 @@ module Metriks
49
61
 
50
62
  def call_downstream(env)
51
63
  status, headers, body = @app.call env
52
- record_error status
64
+ record_staus_code status
53
65
  record_content_length headers
54
66
 
55
67
  [status, headers, body]
56
68
  end
57
69
 
58
- def record_error(status)
70
+ def record_staus_code(status)
59
71
  if status >= 500
60
- Metriks.meter("responses.error").mark
72
+ Metriks.meter(ERROR_RESPONSE).mark
61
73
  elsif status == 404
62
- Metriks.meter("responses.not_found").mark
74
+ Metriks.meter(NOT_FOUND_RESPONSE).mark
63
75
  elsif status == 304
64
- Metriks.meter("responses.not_modified").mark
76
+ Metriks.meter(NOT_MODIFIED_RESPONSE).mark
65
77
  end
66
78
  end
67
79
 
68
80
  def record_content_length(headers)
69
81
  content_length = headers.fetch('Content-Length', 0).to_i
70
82
  return unless content_length > 0
71
- Metriks.histogram('responses.content_length').update(content_length)
83
+ Metriks.histogram(CONTENT_LENGTH).update(content_length)
72
84
  end
73
85
 
74
86
  def response_timer
75
87
  Metriks.timer('app')
76
88
  end
89
+
90
+ def duration_since_request_start(env)
91
+ request_start = env[REQUEST_START_HEADER]
92
+ return 0 unless request_start
93
+ duration = ((Time.now.to_f * 1_000) - request_start.to_f).round
94
+ duration > 0 ? duration : 0
95
+ end
77
96
  end
78
97
  end
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
13
13
  ## If your rubyforge_project name is different, then edit it and comment out
14
14
  ## the sub! line in the Rakefile
15
15
  s.name = 'metriks-middleware'
16
- s.version = '1.3.0'
17
- s.date = '2012-12-11'
16
+ s.version = '2.0.0'
17
+ s.date = '2013-02-22'
18
18
 
19
19
  ## Make sure your summary is short. The description may be as long
20
20
  ## as you like.
@@ -28,7 +28,6 @@ class AsyncAppTest < Test::Unit::TestCase
28
28
  downstream.expects(:call).with(@env).returns(response)
29
29
 
30
30
  actual_response = Metriks::Middleware.new(downstream).call(@env)
31
-
32
31
  assert_equal response, actual_response
33
32
  end
34
33
 
@@ -43,7 +42,6 @@ class AsyncAppTest < Test::Unit::TestCase
43
42
  @async_close.call
44
43
 
45
44
  count = Metriks.timer('app').count
46
-
47
45
  assert_equal 1, count
48
46
  end
49
47
 
@@ -57,7 +55,6 @@ class AsyncAppTest < Test::Unit::TestCase
57
55
  @async_close.call
58
56
 
59
57
  time = Metriks.timer('app').mean
60
-
61
58
  assert_in_delta 0.1, time, 0.01
62
59
  end
63
60
 
@@ -97,7 +94,6 @@ class AsyncAppTest < Test::Unit::TestCase
97
94
  Metriks::Middleware.new(success_async_app).call(@env.dup)
98
95
 
99
96
  errors = Metriks.meter('responses.error').count
100
-
101
97
  assert_equal 2, errors
102
98
  end
103
99
 
@@ -120,7 +116,6 @@ class AsyncAppTest < Test::Unit::TestCase
120
116
  Metriks::Middleware.new(success_async_app).call(@env.dup)
121
117
 
122
118
  not_founds = Metriks.meter('responses.not_found').count
123
-
124
119
  assert_equal 2, not_founds
125
120
  end
126
121
 
@@ -143,36 +138,48 @@ class AsyncAppTest < Test::Unit::TestCase
143
138
  Metriks::Middleware.new(success_async_app).call(@env.dup)
144
139
 
145
140
  not_modifieds = Metriks.meter('responses.not_modified').count
146
-
147
141
  assert_equal 2, not_modifieds
148
142
  end
149
143
 
150
- def test_omits_queue_metrics
144
+ def test_omits_request_delay
151
145
  Metriks::Middleware.new(@downstream).call(@env)
152
- @async_close.call
153
-
154
- wait = Metriks.histogram('queue.wait').mean
155
- depth = Metriks.histogram('queue.depth').mean
156
- used = Metriks.histogram('dynos.in_use').mean
157
146
 
158
- assert_equal 0, wait
159
- assert_equal 0, depth
147
+ used = Metriks.histogram('request_delay').mean
160
148
  assert_equal 0, used
161
149
  end
162
150
 
163
- def test_records_heroku_queue_metrics
164
- @env.merge! 'HTTP_X_HEROKU_QUEUE_WAIT_TIME' => '42',
165
- 'HTTP_X_HEROKU_QUEUE_DEPTH' => '24',
166
- 'HTTP_X_HEROKU_DYNOS_IN_USE' => '3'
151
+ def test_records_request_delay
152
+ now = Time.now.to_f * 1000
153
+ start = now - 42
154
+ @env.merge! 'HTTP_X_REQUEST_START' => start.to_s
167
155
  Metriks::Middleware.new(@downstream).call(@env)
168
- @async_close.call
169
156
 
170
- wait = Metriks.histogram('queue.wait').mean
171
- depth = Metriks.histogram('queue.depth').mean
172
- used = Metriks.histogram('dynos.in_use').mean
157
+ delay = Metriks.histogram('request_delay').mean
158
+ assert_in_delta 42, delay, 1
159
+ end
160
+
161
+ def test_ignores_future_request_start_time
162
+ now = Time.now.to_f * 1000
163
+ start = now + 42
164
+ @env.merge! 'HTTP_X_REQUEST_START' => start.to_s
165
+ Metriks::Middleware.new(@downstream).call(@env)
166
+
167
+ delay = Metriks.histogram('request_delay').mean
168
+ assert_equal 0, delay
169
+ end
170
+
171
+ def test_omits_heroku_dynos_in_use
172
+ Metriks::Middleware.new(@downstream).call(@env)
173
+
174
+ used = Metriks.histogram('heroku.dynos_in_use').mean
175
+ assert_equal 0, used
176
+ end
177
+
178
+ def test_records_heroku_dynos_in_use
179
+ @env.merge! 'HTTP_X_HEROKU_DYNOS_IN_USE' => '42'
180
+ Metriks::Middleware.new(@downstream).call(@env)
173
181
 
174
- assert_equal 42, wait
175
- assert_equal 24, depth
176
- assert_equal 3, used
182
+ dynos = Metriks.histogram('heroku.dynos_in_use').mean
183
+ assert_equal 42, dynos
177
184
  end
178
185
  end
@@ -25,7 +25,6 @@ class SyncAppTest < Test::Unit::TestCase
25
25
  downstream.expects(:call).with(@env).returns(response)
26
26
 
27
27
  actual_response = Metriks::Middleware.new(downstream).call(@env)
28
-
29
28
  assert_equal response, actual_response
30
29
  end
31
30
 
@@ -33,7 +32,6 @@ class SyncAppTest < Test::Unit::TestCase
33
32
  Metriks::Middleware.new(@downstream).call(@env)
34
33
 
35
34
  count = Metriks.timer('app').count
36
-
37
35
  assert_equal 1, count
38
36
  end
39
37
 
@@ -41,7 +39,6 @@ class SyncAppTest < Test::Unit::TestCase
41
39
  Metriks::Middleware.new(sleepy_app).call(@env)
42
40
 
43
41
  time = Metriks.timer('app').mean
44
-
45
42
  assert_in_delta 0.1, time, 0.01
46
43
  end
47
44
 
@@ -62,7 +59,6 @@ class SyncAppTest < Test::Unit::TestCase
62
59
  Metriks::Middleware.new(@downstream).call(@env)
63
60
 
64
61
  errors = Metriks.meter('responses.error').count
65
-
66
62
  assert_equal 2, errors
67
63
  end
68
64
 
@@ -72,7 +68,6 @@ class SyncAppTest < Test::Unit::TestCase
72
68
  Metriks::Middleware.new(@downstream).call(@env)
73
69
 
74
70
  not_founds = Metriks.meter('responses.not_found').count
75
-
76
71
  assert_equal 2, not_founds
77
72
  end
78
73
 
@@ -82,34 +77,48 @@ class SyncAppTest < Test::Unit::TestCase
82
77
  Metriks::Middleware.new(@downstream).call(@env)
83
78
 
84
79
  not_modifieds = Metriks.meter('responses.not_modified').count
85
-
86
80
  assert_equal 2, not_modifieds
87
81
  end
88
82
 
89
- def test_omits_queue_metrics
83
+ def test_omits_request_delay
90
84
  Metriks::Middleware.new(@downstream).call(@env)
91
85
 
92
- wait = Metriks.histogram('queue.wait').mean
93
- depth = Metriks.histogram('queue.depth').mean
94
- used = Metriks.histogram('dynos.in_use').mean
95
-
96
- assert_equal 0, wait
97
- assert_equal 0, depth
86
+ used = Metriks.histogram('request_delay').mean
98
87
  assert_equal 0, used
99
88
  end
100
89
 
101
- def test_records_heroku_queue_metrics
102
- @env.merge! 'HTTP_X_HEROKU_QUEUE_WAIT_TIME' => '42',
103
- 'HTTP_X_HEROKU_QUEUE_DEPTH' => '24',
104
- 'HTTP_X_HEROKU_DYNOS_IN_USE' => '3'
90
+ def test_records_request_delay
91
+ now = Time.now.to_f * 1000
92
+ start = now - 42
93
+ @env.merge! 'HTTP_X_REQUEST_START' => start.to_s
105
94
  Metriks::Middleware.new(@downstream).call(@env)
106
95
 
107
- wait = Metriks.histogram('queue.wait').mean
108
- depth = Metriks.histogram('queue.depth').mean
109
- used = Metriks.histogram('dynos.in_use').mean
96
+ delay = Metriks.histogram('request_delay').mean
97
+ assert_in_delta 42, delay, 1
98
+ end
99
+
100
+ def test_ignores_future_request_start_time
101
+ now = Time.now.to_f * 1000
102
+ start = now + 42
103
+ @env.merge! 'HTTP_X_REQUEST_START' => start.to_s
104
+ Metriks::Middleware.new(@downstream).call(@env)
105
+
106
+ delay = Metriks.histogram('request_delay').mean
107
+ assert_equal 0, delay
108
+ end
109
+
110
+ def test_omits_heroku_dynos_in_use
111
+ Metriks::Middleware.new(@downstream).call(@env)
112
+
113
+ used = Metriks.histogram('heroku.dynos_in_use').mean
114
+ assert_equal 0, used
115
+ end
116
+
117
+ def test_records_heroku_dynos_in_use
118
+ @env.merge! 'HTTP_X_HEROKU_DYNOS_IN_USE' => '42'
119
+ Metriks::Middleware.new(@downstream).call(@env)
110
120
 
111
- assert_equal 42, wait
112
- assert_equal 24, depth
113
- assert_equal 3, used
121
+ dynos = Metriks.histogram('heroku.dynos_in_use').mean
122
+ assert_equal 42, dynos
114
123
  end
115
124
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: metriks-middleware
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.0
4
+ version: 2.0.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-11 00:00:00.000000000 Z
12
+ date: 2013-02-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: metriks
@@ -93,6 +93,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
93
93
  - - ! '>='
94
94
  - !ruby/object:Gem::Version
95
95
  version: '0'
96
+ segments:
97
+ - 0
98
+ hash: -1952576612337173392
96
99
  required_rubygems_version: !ruby/object:Gem::Requirement
97
100
  none: false
98
101
  requirements: