metriks-middleware 1.0.0 → 1.1.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 +2 -2
- data/lib/metriks/middleware.rb +17 -2
- data/metriks-middleware.gemspec +4 -3
- data/test/async_app_test.rb +125 -0
- data/test/sync_app_test.rb +96 -0
- metadata +6 -4
- data/test/metriks-middleware_test.rb +0 -123
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
metriks-middleware (1.
|
4
|
+
metriks-middleware (1.1.0)
|
5
5
|
metriks (~> 0.9.9)
|
6
6
|
|
7
7
|
GEM
|
@@ -11,7 +11,7 @@ GEM
|
|
11
11
|
avl_tree (1.1.3)
|
12
12
|
hitimes (1.1.1)
|
13
13
|
metaclass (0.0.1)
|
14
|
-
metriks (0.9.9)
|
14
|
+
metriks (0.9.9.1)
|
15
15
|
atomic (~> 1.0)
|
16
16
|
avl_tree (~> 1.1.2)
|
17
17
|
hitimes (~> 1.1)
|
data/lib/metriks/middleware.rb
CHANGED
@@ -2,7 +2,7 @@ require 'metriks'
|
|
2
2
|
|
3
3
|
module Metriks
|
4
4
|
class Middleware
|
5
|
-
VERSION = '1.
|
5
|
+
VERSION = '1.1.0'
|
6
6
|
|
7
7
|
def initialize(app, options = {})
|
8
8
|
@app = app
|
@@ -12,6 +12,7 @@ module Metriks
|
|
12
12
|
def call(env)
|
13
13
|
time_response(env) do
|
14
14
|
record_heroku_queue_status env
|
15
|
+
record_error_rate env
|
15
16
|
call_downstream env
|
16
17
|
end
|
17
18
|
end
|
@@ -36,8 +37,22 @@ module Metriks
|
|
36
37
|
Metriks.histogram("#{ @name }.queue.depth").update(queue_depth.to_i) if queue_depth
|
37
38
|
end
|
38
39
|
|
40
|
+
def record_error_rate(env)
|
41
|
+
original_callback = env['async.callback']
|
42
|
+
env['async.callback'] = lambda do |env|
|
43
|
+
record_error env.first
|
44
|
+
original_callback.call env
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
39
48
|
def call_downstream(env)
|
40
|
-
@app.call env
|
49
|
+
response = @app.call env
|
50
|
+
record_error response.first
|
51
|
+
response
|
52
|
+
end
|
53
|
+
|
54
|
+
def record_error(status)
|
55
|
+
Metriks.meter("#{ @name }.errors").mark if status >= 500
|
41
56
|
end
|
42
57
|
|
43
58
|
def response_timer
|
data/metriks-middleware.gemspec
CHANGED
@@ -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.
|
17
|
-
s.date = '2012-07-
|
16
|
+
s.version = '1.1.0'
|
17
|
+
s.date = '2012-07-11'
|
18
18
|
|
19
19
|
## Make sure your summary is short. The description may be as long
|
20
20
|
## as you like.
|
@@ -57,7 +57,8 @@ Gem::Specification.new do |s|
|
|
57
57
|
Rakefile
|
58
58
|
lib/metriks/middleware.rb
|
59
59
|
metriks-middleware.gemspec
|
60
|
-
test/
|
60
|
+
test/async_app_test.rb
|
61
|
+
test/sync_app_test.rb
|
61
62
|
test/test_helper.rb
|
62
63
|
]
|
63
64
|
# = MANIFEST =
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'metriks/middleware'
|
4
|
+
|
5
|
+
class AsyncAppTest < Test::Unit::TestCase
|
6
|
+
class AsyncClose
|
7
|
+
def callback(&block) @callback = block end
|
8
|
+
def call(*args) @callback.call(*args) end
|
9
|
+
end
|
10
|
+
|
11
|
+
def setup
|
12
|
+
@async_close = AsyncClose.new
|
13
|
+
@async_callback = ->(env) do @response = env end
|
14
|
+
@env = { 'async.close' => @async_close, 'async.callback' => @async_callback }
|
15
|
+
@downstream = lambda do |env|
|
16
|
+
env['async.callback'].call [200, {}, ['']]
|
17
|
+
[-1, {}, ['']]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def teardown
|
22
|
+
Metriks::Registry.default.each do |_, metric| metric.clear end
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_calls_downstream
|
26
|
+
downstream = mock
|
27
|
+
response = stub first: 42
|
28
|
+
downstream.expects(:call).with(@env).returns(response)
|
29
|
+
|
30
|
+
actual_response = Metriks::Middleware.new(downstream).call(@env)
|
31
|
+
|
32
|
+
assert_equal response, actual_response
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_calls_original_callback
|
36
|
+
Metriks::Middleware.new(@downstream).call(@env)
|
37
|
+
|
38
|
+
assert_equal [200, {}, ['']], @response
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_counts_throughput
|
42
|
+
Metriks::Middleware.new(@downstream).call(@env)
|
43
|
+
@async_close.call
|
44
|
+
|
45
|
+
count = Metriks.timer('app').count
|
46
|
+
|
47
|
+
assert_equal 1, count
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_times_downstream_response
|
51
|
+
sleepy_app = ->(env) do
|
52
|
+
sleep 0.1
|
53
|
+
@downstream.call env
|
54
|
+
end
|
55
|
+
|
56
|
+
Metriks::Middleware.new(sleepy_app).call(@env)
|
57
|
+
@async_close.call
|
58
|
+
|
59
|
+
time = Metriks.timer('app').mean
|
60
|
+
|
61
|
+
assert_in_delta 0.1, time, 0.01
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_records_errors
|
65
|
+
error_sync_app = lambda do |env| [500, {}, ['']] end
|
66
|
+
error_async_app = lambda do |env|
|
67
|
+
env['async.callback'].call [500, {}, ['']]
|
68
|
+
[-1, {}, ['']]
|
69
|
+
end
|
70
|
+
|
71
|
+
success_sync_app = lambda do |env| [200, {}, ['']] end
|
72
|
+
success_async_app = lambda do |env|
|
73
|
+
env['async.callback'].call [200, {}, ['']]
|
74
|
+
[-1, {}, ['']]
|
75
|
+
end
|
76
|
+
|
77
|
+
Metriks::Middleware.new(error_sync_app).call(@env.dup)
|
78
|
+
Metriks::Middleware.new(error_async_app).call(@env.dup)
|
79
|
+
Metriks::Middleware.new(success_sync_app).call(@env.dup)
|
80
|
+
Metriks::Middleware.new(success_async_app).call(@env.dup)
|
81
|
+
|
82
|
+
errors = Metriks.meter('app.errors').count
|
83
|
+
|
84
|
+
assert_equal 2, errors
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_omits_queue_metrics
|
88
|
+
Metriks::Middleware.new(@downstream).call(@env)
|
89
|
+
@async_close.call
|
90
|
+
|
91
|
+
wait = Metriks.histogram('app.queue.wait').mean
|
92
|
+
depth = Metriks.histogram('app.queue.depth').mean
|
93
|
+
|
94
|
+
assert_equal 0, wait
|
95
|
+
assert_equal 0, depth
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_records_heroku_queue_metrics
|
99
|
+
@env.merge! 'HTTP_X_HEROKU_QUEUE_WAIT_TIME' => '42',
|
100
|
+
'HTTP_X_HEROKU_QUEUE_DEPTH' => '24'
|
101
|
+
Metriks::Middleware.new(@downstream).call(@env)
|
102
|
+
@async_close.call
|
103
|
+
|
104
|
+
wait = Metriks.histogram('app.queue.wait').mean
|
105
|
+
depth = Metriks.histogram('app.queue.depth').mean
|
106
|
+
|
107
|
+
assert_equal 42, wait
|
108
|
+
assert_equal 24, depth
|
109
|
+
end
|
110
|
+
|
111
|
+
def test_name_merics
|
112
|
+
@env.merge! 'HTTP_X_HEROKU_QUEUE_WAIT_TIME' => '42',
|
113
|
+
'HTTP_X_HEROKU_QUEUE_DEPTH' => '24'
|
114
|
+
Metriks::Middleware.new(@downstream, name: 'metric-name').call(@env)
|
115
|
+
@async_close.call
|
116
|
+
|
117
|
+
count = Metriks.timer('metric-name').count
|
118
|
+
wait = Metriks.histogram('metric-name.queue.wait').mean
|
119
|
+
depth = Metriks.histogram('metric-name.queue.depth').mean
|
120
|
+
|
121
|
+
assert_operator count, :>, 0
|
122
|
+
assert_operator wait, :>, 0
|
123
|
+
assert_operator depth, :>, 0
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
require 'metriks/middleware'
|
4
|
+
|
5
|
+
class SyncAppTest < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@env = {}
|
8
|
+
@downstream = lambda do |env| [200, {}, ['']] end
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown
|
12
|
+
Metriks::Registry.default.each do |_, metric| metric.clear end
|
13
|
+
end
|
14
|
+
|
15
|
+
def sleepy_app
|
16
|
+
lambda do |env|
|
17
|
+
sleep 0.1
|
18
|
+
@downstream.call env
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def test_calls_downstream
|
23
|
+
downstream = mock
|
24
|
+
response = stub first: 200
|
25
|
+
downstream.expects(:call).with(@env).returns(response)
|
26
|
+
|
27
|
+
actual_response = Metriks::Middleware.new(downstream).call(@env)
|
28
|
+
|
29
|
+
assert_equal response, actual_response
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_counts_throughput
|
33
|
+
Metriks::Middleware.new(@downstream).call(@env)
|
34
|
+
|
35
|
+
count = Metriks.timer('app').count
|
36
|
+
|
37
|
+
assert_equal 1, count
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_times_downstream_response
|
41
|
+
Metriks::Middleware.new(sleepy_app).call(@env)
|
42
|
+
|
43
|
+
time = Metriks.timer('app').mean
|
44
|
+
|
45
|
+
assert_in_delta 0.1, time, 0.01
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_records_errors
|
49
|
+
error_app = lambda do |env| [500, {}, ['']] end
|
50
|
+
2.times { Metriks::Middleware.new(error_app).call(@env) }
|
51
|
+
Metriks::Middleware.new(@downstream).call(@env)
|
52
|
+
|
53
|
+
errors = Metriks.meter('app.errors').count
|
54
|
+
|
55
|
+
assert_equal 2, errors
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_omits_queue_metrics
|
59
|
+
Metriks::Middleware.new(@downstream).call(@env)
|
60
|
+
|
61
|
+
wait = Metriks.histogram('app.queue.wait').mean
|
62
|
+
depth = Metriks.histogram('app.queue.depth').mean
|
63
|
+
|
64
|
+
assert_equal 0, wait
|
65
|
+
assert_equal 0, depth
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_records_heroku_queue_metrics
|
69
|
+
@env.merge! 'HTTP_X_HEROKU_QUEUE_WAIT_TIME' => '42',
|
70
|
+
'HTTP_X_HEROKU_QUEUE_DEPTH' => '24'
|
71
|
+
Metriks::Middleware.new(@downstream).call(@env)
|
72
|
+
|
73
|
+
wait = Metriks.histogram('app.queue.wait').mean
|
74
|
+
depth = Metriks.histogram('app.queue.depth').mean
|
75
|
+
|
76
|
+
assert_equal 42, wait
|
77
|
+
assert_equal 24, depth
|
78
|
+
end
|
79
|
+
|
80
|
+
def test_name_merics
|
81
|
+
error_app = lambda do |env| [500, {}, ['']] end
|
82
|
+
@env.merge! 'HTTP_X_HEROKU_QUEUE_WAIT_TIME' => '42',
|
83
|
+
'HTTP_X_HEROKU_QUEUE_DEPTH' => '24'
|
84
|
+
Metriks::Middleware.new(error_app, name: 'metric-name').call(@env)
|
85
|
+
|
86
|
+
count = Metriks.timer('metric-name').count
|
87
|
+
errors = Metriks.meter('metric-name.errors').count
|
88
|
+
wait = Metriks.histogram('metric-name.queue.wait').mean
|
89
|
+
depth = Metriks.histogram('metric-name.queue.depth').mean
|
90
|
+
|
91
|
+
assert_operator count, :>, 0
|
92
|
+
assert_operator errors, :>, 0
|
93
|
+
assert_operator wait, :>, 0
|
94
|
+
assert_operator depth, :>, 0
|
95
|
+
end
|
96
|
+
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.
|
4
|
+
version: 1.1.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-07-
|
12
|
+
date: 2012-07-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: metriks
|
@@ -58,7 +58,8 @@ files:
|
|
58
58
|
- Rakefile
|
59
59
|
- lib/metriks/middleware.rb
|
60
60
|
- metriks-middleware.gemspec
|
61
|
-
- test/
|
61
|
+
- test/async_app_test.rb
|
62
|
+
- test/sync_app_test.rb
|
62
63
|
- test/test_helper.rb
|
63
64
|
homepage: https://github.com/lmarburger/metriks-middleware
|
64
65
|
licenses: []
|
@@ -86,4 +87,5 @@ signing_key:
|
|
86
87
|
specification_version: 2
|
87
88
|
summary: Rack middleware for metriks
|
88
89
|
test_files:
|
89
|
-
- test/
|
90
|
+
- test/async_app_test.rb
|
91
|
+
- test/sync_app_test.rb
|
@@ -1,123 +0,0 @@
|
|
1
|
-
require 'test_helper'
|
2
|
-
|
3
|
-
require 'metriks/middleware'
|
4
|
-
|
5
|
-
class MeterTest < Test::Unit::TestCase
|
6
|
-
def setup
|
7
|
-
@downstream = lambda do |env| end
|
8
|
-
@env = {}
|
9
|
-
end
|
10
|
-
|
11
|
-
def teardown
|
12
|
-
Metriks::Registry.default.each do |_, metric| metric.clear end
|
13
|
-
end
|
14
|
-
|
15
|
-
def sleepy_app
|
16
|
-
lambda do |env| sleep(0.1) end
|
17
|
-
end
|
18
|
-
|
19
|
-
def async_env(deferrable)
|
20
|
-
{ 'async.close' => deferrable }
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_calls_downstream
|
24
|
-
downstream = mock
|
25
|
-
response = stub
|
26
|
-
downstream.expects(:call).with(@env).returns(response)
|
27
|
-
actual_response = Metriks::Middleware.new(downstream).call(@env)
|
28
|
-
|
29
|
-
assert_equal response, actual_response
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_async_app_calls_downstream
|
33
|
-
downstream = mock
|
34
|
-
response = stub
|
35
|
-
|
36
|
-
deferrable = Object.new
|
37
|
-
def deferrable.callback() yield end
|
38
|
-
env = { 'async.close' => deferrable }
|
39
|
-
|
40
|
-
downstream.expects(:call).with(env).returns(response)
|
41
|
-
actual_response = Metriks::Middleware.new(downstream).call(env)
|
42
|
-
|
43
|
-
assert_equal response, actual_response
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_counts_throughput
|
47
|
-
Metriks::Middleware.new(@downstream).call(@env)
|
48
|
-
count = Metriks.timer('app').count
|
49
|
-
|
50
|
-
assert_equal 1, count
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_times_downstream_response
|
54
|
-
Metriks::Middleware.new(sleepy_app).call(@env)
|
55
|
-
time = Metriks.timer('app').mean
|
56
|
-
|
57
|
-
assert_in_delta 0.1, time, 0.01
|
58
|
-
end
|
59
|
-
|
60
|
-
def test_async_app_stops_timer_on_close
|
61
|
-
deferrable = Object.new
|
62
|
-
def deferrable.callback(&block) @callback = block end
|
63
|
-
def deferrable.call_callback() @callback.call end
|
64
|
-
env = { 'async.close' => deferrable }
|
65
|
-
|
66
|
-
Metriks::Middleware.new(sleepy_app).call(env)
|
67
|
-
deferrable.call_callback
|
68
|
-
count = Metriks.timer('app').count
|
69
|
-
time = Metriks.timer('app').mean
|
70
|
-
|
71
|
-
assert_equal 1, count
|
72
|
-
assert_in_delta 0.1, time, 0.01
|
73
|
-
end
|
74
|
-
|
75
|
-
def test_omits_queue_metrics
|
76
|
-
Metriks::Middleware.new(@downstream).call(@env)
|
77
|
-
wait = Metriks.histogram('app.queue.wait').mean
|
78
|
-
depth = Metriks.histogram('app.queue.depth').mean
|
79
|
-
|
80
|
-
assert_equal 0, wait
|
81
|
-
assert_equal 0, depth
|
82
|
-
end
|
83
|
-
|
84
|
-
def test_records_heroku_queue
|
85
|
-
env = { 'HTTP_X_HEROKU_QUEUE_WAIT_TIME' => '42',
|
86
|
-
'HTTP_X_HEROKU_QUEUE_DEPTH' => '24' }
|
87
|
-
|
88
|
-
Metriks::Middleware.new(@downstream).call(env)
|
89
|
-
wait = Metriks.histogram('app.queue.wait').mean
|
90
|
-
depth = Metriks.histogram('app.queue.depth').mean
|
91
|
-
|
92
|
-
assert_equal 42, wait
|
93
|
-
assert_equal 24, depth
|
94
|
-
end
|
95
|
-
|
96
|
-
def test_async_records_heroku_queue
|
97
|
-
deferrable = Object.new
|
98
|
-
def deferrable.callback() yield end
|
99
|
-
env = { 'async.close' => deferrable,
|
100
|
-
'HTTP_X_HEROKU_QUEUE_WAIT_TIME' => '42',
|
101
|
-
'HTTP_X_HEROKU_QUEUE_DEPTH' => '24' }
|
102
|
-
|
103
|
-
Metriks::Middleware.new(@downstream).call(env)
|
104
|
-
wait = Metriks.histogram('app.queue.wait').mean
|
105
|
-
depth = Metriks.histogram('app.queue.depth').mean
|
106
|
-
|
107
|
-
assert_equal 42, wait
|
108
|
-
assert_equal 24, depth
|
109
|
-
end
|
110
|
-
|
111
|
-
def test_name_merics
|
112
|
-
env = { 'HTTP_X_HEROKU_QUEUE_WAIT_TIME' => '42',
|
113
|
-
'HTTP_X_HEROKU_QUEUE_DEPTH' => '24' }
|
114
|
-
Metriks::Middleware.new(@downstream, name: 'metric-name').call(env)
|
115
|
-
count = Metriks.timer('metric-name').count
|
116
|
-
wait = Metriks.histogram('metric-name.queue.wait').mean
|
117
|
-
depth = Metriks.histogram('metric-name.queue.depth').mean
|
118
|
-
|
119
|
-
assert_not_nil count
|
120
|
-
assert_not_nil wait
|
121
|
-
assert_not_nil depth
|
122
|
-
end
|
123
|
-
end
|