check 0.2.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 +19 -0
- data/LICENSE +22 -0
- data/README.md +75 -0
- data/Rakefile +11 -0
- data/benchmarks/benchmark.rb +9 -0
- data/benchmarks/metric_check.rb +51 -0
- data/benchmarks/metric_crud.rb +43 -0
- data/check.gemspec +29 -0
- data/examples/config.ru +4 -0
- data/examples/example.rb +14 -0
- data/examples/metric_check.rb +36 -0
- data/examples/metric_crud.rb +21 -0
- data/examples/unicorn.conf.rb +41 -0
- data/lib/check.rb +17 -0
- data/lib/check/api.rb +50 -0
- data/lib/check/api/metrics.rb +64 -0
- data/lib/check/metric.rb +225 -0
- data/lib/check/notifications.rb +65 -0
- data/test/check/api/metrics_test.rb +109 -0
- data/test/check/metric_test.rb +255 -0
- data/test/check_test.rb +12 -0
- data/test/test_helper.rb +24 -0
- metadata +190 -0
@@ -0,0 +1,255 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
require 'check/metric'
|
4
|
+
|
5
|
+
module Check
|
6
|
+
describe Metric do
|
7
|
+
before do
|
8
|
+
Redis.current.flushdb
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "name" do
|
12
|
+
it "must be present" do
|
13
|
+
Metric.new.wont_be :valid_name?
|
14
|
+
Metric.new(name: "foo").must_be :valid_name?
|
15
|
+
end
|
16
|
+
|
17
|
+
it "cannot be empty string" do
|
18
|
+
Metric.new(name: " ").wont_be :valid_name?
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "accepts custom attributes" do
|
23
|
+
emails = %w[foo@bar.com foo2@bar.com]
|
24
|
+
metric = Metric.new(name: "foo", email: emails)
|
25
|
+
metric[:email].must_equal emails
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#save" do
|
29
|
+
it "doesn't create duplicates" do
|
30
|
+
Metric.new(name: "foo", lower: 1).save
|
31
|
+
2.times { Metric.new(name: "foo", lower: 1).save }
|
32
|
+
Redis.current.keys.size.must_equal 1
|
33
|
+
Metric.find(name: "foo").similar.size.must_equal 1
|
34
|
+
end
|
35
|
+
|
36
|
+
it "updating a metric saves it as a new one" do
|
37
|
+
metric = Metric.new(name: "foo").save
|
38
|
+
metric.similar.size.must_equal 1
|
39
|
+
metric.lower = 5
|
40
|
+
metric.save
|
41
|
+
metric.similar.size.must_equal 2
|
42
|
+
end
|
43
|
+
|
44
|
+
it "updating a metric name saves it as a new one" do
|
45
|
+
metric = Metric.new(name: "foo").save
|
46
|
+
metric.name = "bar"
|
47
|
+
metric.save
|
48
|
+
(%w[foo bar] - Redis.current.keys).must_equal []
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#similar" do
|
53
|
+
it "returns all metric checks with the same name" do
|
54
|
+
Metric.new(name: "foo", lower: 1).save
|
55
|
+
metric = Metric.new(name: "foo", lower: 10)
|
56
|
+
metric.similar.map(&:lower).must_equal [1]
|
57
|
+
metric.save
|
58
|
+
(metric.similar.map(&:lower) - [1, 10]).must_equal []
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "#notify?" do
|
63
|
+
it "disabled if REDIS_NOTIFICATIONS is an empty string" do
|
64
|
+
ENV['REDIS_NOTIFICATIONS'] = ""
|
65
|
+
load 'check.rb' # pardon the shouty CONSTANTS...
|
66
|
+
Metric.new(name: "foo").wont_be :notify?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe "#check" do
|
71
|
+
before do
|
72
|
+
@metric = Metric.new(
|
73
|
+
name: "foo",
|
74
|
+
lower: 5,
|
75
|
+
upper: 10,
|
76
|
+
matches_for_positive: 2,
|
77
|
+
over_seconds: 60,
|
78
|
+
suspend_after_positives: 1,
|
79
|
+
suspend_for_seconds: 2
|
80
|
+
).save
|
81
|
+
end
|
82
|
+
|
83
|
+
it "stores matches" do
|
84
|
+
@metric.matches.length.must_equal 0
|
85
|
+
@metric.check({name: "foo", value: 4})
|
86
|
+
@metric.matches.length.must_equal 1
|
87
|
+
end
|
88
|
+
|
89
|
+
it "matches don't grow past matches_for_positive" do
|
90
|
+
3.times { |value| @metric.check({name: "foo", value: value}) }
|
91
|
+
@metric.matches.length.must_be :<=, @metric[:matches_for_positive]
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "when values are between lower & upper bounds" do
|
95
|
+
it "no matches get recorded" do
|
96
|
+
(5..10).each { |value| @metric.check({name: "foo", value: value}) }
|
97
|
+
@metric.matches.length.must_equal 0
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "when values are outside lower & upper bounds" do
|
102
|
+
describe "when new matches are within over_seconds period" do
|
103
|
+
before do
|
104
|
+
#binding.pry
|
105
|
+
# $ redis-cli -s /tmp/redis-check-test.sock subscribe check_notifications
|
106
|
+
(10..13).each { |value| @metric.check({name: "foo", value: value}) }
|
107
|
+
end
|
108
|
+
|
109
|
+
it "a new positive gets created" do
|
110
|
+
@metric.positives.length.must_equal 1
|
111
|
+
end
|
112
|
+
|
113
|
+
it "and matching gets suspended for :suspend_for_seconds" do
|
114
|
+
@metric.must_be :suspended?
|
115
|
+
@metric.matches.length.must_equal 0
|
116
|
+
end
|
117
|
+
|
118
|
+
it "sends pub/sub notification" do
|
119
|
+
skip "Check the before for tips on a quick, manual test"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe "multiple metric checks" do
|
125
|
+
it "checks against all persisted checks" do
|
126
|
+
metric = Metric.new(
|
127
|
+
name: "foo",
|
128
|
+
lower: 1,
|
129
|
+
matches_for_positive: 1
|
130
|
+
).save
|
131
|
+
metric.check({name: "foo", value: 0})
|
132
|
+
metric.matches.length.must_equal 0
|
133
|
+
metric.positives.length.must_equal 1
|
134
|
+
@metric.matches.length.must_equal 1
|
135
|
+
@metric.positives.length.must_equal 0
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "disable/enable" do
|
141
|
+
before do
|
142
|
+
@metric = Metric.new(
|
143
|
+
name: "foo",
|
144
|
+
lower: 5
|
145
|
+
).save
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "by default" do
|
149
|
+
it "is not disabled" do
|
150
|
+
@metric.wont_be :disabled?
|
151
|
+
end
|
152
|
+
|
153
|
+
it "matches are not ignored" do
|
154
|
+
@metric.check({name: "foo", value: 1})
|
155
|
+
@metric.matches.length.must_equal 1
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "when it is disabled" do
|
160
|
+
it "new matches are ignored" do
|
161
|
+
@metric.disable!
|
162
|
+
@metric.must_be :disabled?
|
163
|
+
@metric.check({name: "foo", value: 1})
|
164
|
+
@metric.matches.length.must_equal 0
|
165
|
+
@metric.enable!
|
166
|
+
@metric.wont_be :disabled?
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
describe "#delete" do
|
172
|
+
before do
|
173
|
+
@metric = Metric.new(name: "foo", lower: 2).save
|
174
|
+
end
|
175
|
+
|
176
|
+
it "deletes itself from the metric checks with the same name" do
|
177
|
+
metric = Metric.new(name: "foo", lower: 1).save
|
178
|
+
metric.must_be :persisted?
|
179
|
+
metric.delete
|
180
|
+
metric.wont_be :persisted?
|
181
|
+
metric.similar.must_equal [@metric.to_hash]
|
182
|
+
end
|
183
|
+
|
184
|
+
it "deletes all matches" do
|
185
|
+
@metric.check({name: "foo", value: 1})
|
186
|
+
Redis.current.must_be :exists, @metric.matches_key
|
187
|
+
@metric.delete
|
188
|
+
Redis.current.wont_be :exists, @metric.matches_key
|
189
|
+
end
|
190
|
+
|
191
|
+
it "deletes all positives" do
|
192
|
+
2.times { |value| @metric.check({name: "foo", value: value}) }
|
193
|
+
Redis.current.must_be :exists, @metric.positives_key
|
194
|
+
@metric.delete
|
195
|
+
Redis.current.wont_be :exists, @metric.positives_key
|
196
|
+
end
|
197
|
+
|
198
|
+
it "deletes disable" do
|
199
|
+
@metric.disable!
|
200
|
+
@metric.delete
|
201
|
+
Redis.current.wont_be :exists, @metric.disable_key
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
describe "#delete_positives" do
|
206
|
+
before do
|
207
|
+
@metric = Metric.new(name: "foo", upper: 10).save
|
208
|
+
(10..13).each { |value| @metric.check({name: "foo", value: value}) }
|
209
|
+
@metric.positives.count.must_be :>, 0
|
210
|
+
@metric.must_be :suspended?
|
211
|
+
@metric.delete_positives
|
212
|
+
end
|
213
|
+
|
214
|
+
it "removes all positives" do
|
215
|
+
@metric.positives.count.must_equal 0
|
216
|
+
end
|
217
|
+
|
218
|
+
it "unsuspends metric checking" do
|
219
|
+
@metric.wont_be :suspended?
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
describe ".defaults" do
|
224
|
+
it "overwrite default values" do
|
225
|
+
Metric.new.must_equal Metric.defaults
|
226
|
+
Metric.defaults = { foo: "bar"}
|
227
|
+
metric = Metric.new
|
228
|
+
metric.fetch(:foo).must_equal "bar"
|
229
|
+
metric.first.must_equal Metric.defaults.first
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
describe ".find" do
|
234
|
+
it "behaves like new" do
|
235
|
+
Metric.find.must_equal Metric.new
|
236
|
+
end
|
237
|
+
|
238
|
+
it "doesn't create duplicates" do
|
239
|
+
Metric.new(name: "foo").save
|
240
|
+
metric = Metric.find(name: "foo")
|
241
|
+
metric.similar.size.must_equal 1
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
describe ".delete_all" do
|
246
|
+
it "deletes all metric checks" do
|
247
|
+
Metric.new(name: "foo", lower: 1).save
|
248
|
+
Metric.new(name: "foo", lower: 2).save
|
249
|
+
|
250
|
+
Metric.delete_all("foo")
|
251
|
+
Metric.new(name: "foo").similar.size.must_equal 0
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
data/test/check_test.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require_relative 'test_helper'
|
2
|
+
|
3
|
+
require 'check'
|
4
|
+
|
5
|
+
describe Check do
|
6
|
+
it "configures Redis connection" do
|
7
|
+
config_uri = URI(ENV['REDIS_URI'])
|
8
|
+
Redis.current.client.host.must_equal config_uri.host
|
9
|
+
Redis.current.client.port.must_equal config_uri.port
|
10
|
+
Redis.current.client.path.to_s.must_equal config_uri.path
|
11
|
+
end
|
12
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
|
3
|
+
require 'pry'
|
4
|
+
require 'ap'
|
5
|
+
require 'rack/test'
|
6
|
+
require 'turn/autorun'
|
7
|
+
|
8
|
+
APP_ROOT = File.expand_path('../../', __FILE__)
|
9
|
+
$:.push "#{APP_ROOT}/lib"
|
10
|
+
|
11
|
+
require 'redis_gun'
|
12
|
+
|
13
|
+
REDIS_SERVER ||= RedisGun::RedisServer.new
|
14
|
+
ENV['REDIS_URI'] = REDIS_SERVER.socket
|
15
|
+
def stop_redis_server
|
16
|
+
REDIS_SERVER.stop
|
17
|
+
end
|
18
|
+
Signal.trap("SIGTERM", stop_redis_server)
|
19
|
+
Signal.trap("SIGINT", stop_redis_server)
|
20
|
+
Signal.trap("SIGQUIT", stop_redis_server)
|
21
|
+
|
22
|
+
MiniTest::Unit.after_tests do
|
23
|
+
stop_redis_server
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,190 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: check
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Gerhard Lazu
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-11-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: hashr
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 0.0.21
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 0.0.21
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: hiredis
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ~>
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: 0.4.5
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: 0.4.5
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: msgpack
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 0.4.7
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ~>
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: 0.4.7
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: redis
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ~>
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 3.0.2
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ~>
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 3.0.2
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: redis-objects
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ~>
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 0.6.1
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: 0.6.1
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: grape
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 0.2.2
|
102
|
+
type: :runtime
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.2.2
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: grape-swagger
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ~>
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: 0.3.0
|
118
|
+
type: :runtime
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ~>
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 0.3.0
|
126
|
+
description: Redis backed service for monitoring metric data streams against pre-defined
|
127
|
+
thresholds
|
128
|
+
email:
|
129
|
+
- gerhard@lazu.co.uk
|
130
|
+
executables: []
|
131
|
+
extensions: []
|
132
|
+
extra_rdoc_files: []
|
133
|
+
files:
|
134
|
+
- lib/check/api/metrics.rb
|
135
|
+
- lib/check/api.rb
|
136
|
+
- lib/check/metric.rb
|
137
|
+
- lib/check/notifications.rb
|
138
|
+
- lib/check.rb
|
139
|
+
- examples/config.ru
|
140
|
+
- examples/example.rb
|
141
|
+
- examples/metric_check.rb
|
142
|
+
- examples/metric_crud.rb
|
143
|
+
- examples/unicorn.conf.rb
|
144
|
+
- benchmarks/benchmark.rb
|
145
|
+
- benchmarks/metric_check.rb
|
146
|
+
- benchmarks/metric_crud.rb
|
147
|
+
- Gemfile
|
148
|
+
- check.gemspec
|
149
|
+
- Rakefile
|
150
|
+
- README.md
|
151
|
+
- LICENSE
|
152
|
+
- test/check/api/metrics_test.rb
|
153
|
+
- test/check/metric_test.rb
|
154
|
+
- test/check_test.rb
|
155
|
+
- test/test_helper.rb
|
156
|
+
homepage: https://github.com/gosquared/osprey
|
157
|
+
licenses: []
|
158
|
+
post_install_message:
|
159
|
+
rdoc_options: []
|
160
|
+
require_paths:
|
161
|
+
- lib
|
162
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
163
|
+
none: false
|
164
|
+
requirements:
|
165
|
+
- - ! '>='
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
segments:
|
169
|
+
- 0
|
170
|
+
hash: -3975405867045093680
|
171
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
172
|
+
none: false
|
173
|
+
requirements:
|
174
|
+
- - ! '>='
|
175
|
+
- !ruby/object:Gem::Version
|
176
|
+
version: '0'
|
177
|
+
segments:
|
178
|
+
- 0
|
179
|
+
hash: -3975405867045093680
|
180
|
+
requirements: []
|
181
|
+
rubyforge_project:
|
182
|
+
rubygems_version: 1.8.23
|
183
|
+
signing_key:
|
184
|
+
specification_version: 3
|
185
|
+
summary: Data stream monitor
|
186
|
+
test_files:
|
187
|
+
- test/check/api/metrics_test.rb
|
188
|
+
- test/check/metric_test.rb
|
189
|
+
- test/check_test.rb
|
190
|
+
- test/test_helper.rb
|