bidu-house 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +4 -1
- data/README.md +20 -7
- data/house.gemspec +1 -0
- data/lib/bidu/house/report.rb +2 -1
- data/lib/bidu/house/report/error.rb +1 -1
- data/lib/bidu/house/report/range.rb +54 -0
- data/lib/bidu/house/version.rb +1 -1
- data/spec/lib/bidu/house/report/range_spec.rb +302 -0
- data/spec/spec_helper.rb +5 -0
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1bce0f17bbdd46d4d769e1b3a6d086abad2ba9b4
|
4
|
+
data.tar.gz: ab14a3c78154d146481f730c198face541890f24
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 173182741ddeb9f5ec7bcf41beb5e084777d8039cd6d13e3dee181c9b6bddab21ebe052248199c8bd8450ea79ce12523a00439140629a35337c374ca6ac7698b
|
7
|
+
data.tar.gz: 5d83943edac6382f139c0f7d61b35c32b1566cd355f28ccf5816c326f093a431b515d7edee0a81ab8fa0d4863f32d05fd96351ca62ac3801d6c0f1a5c129648d
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
bidu-house (1.
|
4
|
+
bidu-house (1.1.0)
|
5
5
|
activesupport
|
6
6
|
bidu-active_ext
|
7
7
|
concern_builder
|
@@ -30,6 +30,8 @@ GEM
|
|
30
30
|
bidu-core_ext (1.2.2)
|
31
31
|
activesupport
|
32
32
|
builder (3.2.2)
|
33
|
+
codeclimate-test-reporter (0.5.0)
|
34
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
33
35
|
coderay (1.1.0)
|
34
36
|
concern_builder (0.0.2)
|
35
37
|
activesupport
|
@@ -75,6 +77,7 @@ DEPENDENCIES
|
|
75
77
|
activerecord
|
76
78
|
bidu-house!
|
77
79
|
bundler (~> 1.6)
|
80
|
+
codeclimate-test-reporter
|
78
81
|
pry-nav
|
79
82
|
rake
|
80
83
|
rspec (~> 2.14)
|
data/README.md
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
Bidu House
|
2
2
|
==========
|
3
3
|
|
4
|
+
[![Code Climate](https://codeclimate.com/github/Bidu/house/badges/gpa.svg)](https://codeclimate.com/github/Bidu/house)
|
5
|
+
|
4
6
|
This gem tries to make server monitoring easier and more reliable by adding an easly configurable
|
5
7
|
report and making it avaliable in a controller
|
6
8
|
|
@@ -21,8 +23,10 @@ with error and render the report
|
|
21
23
|
include Bidu::House
|
22
24
|
|
23
25
|
status_report :failures, clazz: Document
|
24
|
-
status_report :failures, clazz: Schedules, on: :schedules
|
26
|
+
status_report :'failures.schedules', clazz: Schedules, on: :schedules
|
25
27
|
status_report :delays, clazz: Schedules, scope: :late, on: :schedules
|
28
|
+
status_report :'documents.count', clazz: Document, scope: :active, type: House::Range, minimum: 100
|
29
|
+
status_report :'documents.errors', clazz: Document, scope: :'active.with_error', type: :range, maximum: 1000
|
26
30
|
|
27
31
|
def status
|
28
32
|
render_status
|
@@ -45,14 +49,23 @@ with error and render the report
|
|
45
49
|
|
46
50
|
3. Set the correct options on your status report to achieve a perfect report
|
47
51
|
- clazz: Class of the object that might contain error
|
48
|
-
- scope: scope to be fetched when trying to find objects with error (default: :with_error)
|
49
|
-
- external_key: column to be exposed as id for the objects with error
|
50
|
-
- threshold: default report threshold (default: 0.02)
|
51
52
|
- period: default search period (default: 1 day)
|
52
53
|
- on: report bucket (default: :default)
|
53
|
-
-
|
54
|
-
|
55
|
-
|
54
|
+
- type: report type (error, range or other custom report)
|
55
|
+
|
56
|
+
Remembering that each report may have its onw parameters
|
57
|
+
|
58
|
+
- ```House::Error```
|
59
|
+
- scope: scope to be fetched when trying to find objects with error (default: :with_error)
|
60
|
+
- external_key: column to be exposed as id for the objects with error
|
61
|
+
- threshold: default report threshold (default: 0.02)
|
62
|
+
- base_scope: scope to be universal sample
|
63
|
+
- uniq: when the output ids should not be repeated
|
64
|
+
- limit: limit of ids to be outputed
|
65
|
+
- ```House::Range```
|
66
|
+
- scope: scope of the query to be counted
|
67
|
+
- maximum: max value accepted in the range
|
68
|
+
- minimum: minimum value accepted in the range
|
56
69
|
|
57
70
|
4. Run the server and hit the health-check routes
|
58
71
|
|
data/house.gemspec
CHANGED
data/lib/bidu/house/report.rb
CHANGED
@@ -3,13 +3,14 @@ module Bidu
|
|
3
3
|
class Report
|
4
4
|
include JsonParser
|
5
5
|
require 'bidu/house/report/error'
|
6
|
+
require 'bidu/house/report/range'
|
6
7
|
ALLOWED_PARAMETERS = []
|
7
8
|
DEFAULT_OPTION = {}
|
8
9
|
|
9
10
|
attr_reader :json
|
10
11
|
|
11
12
|
json_parse :period, type: :period
|
12
|
-
json_parse :clazz, :base_scope, case: :snake
|
13
|
+
json_parse :clazz, :base_scope, :id, case: :snake
|
13
14
|
|
14
15
|
def initialize(options)
|
15
16
|
@json = DEFAULT_OPTION.merge(options)
|
@@ -13,7 +13,7 @@ module Bidu
|
|
13
13
|
}
|
14
14
|
|
15
15
|
json_parse :threshold, type: :float
|
16
|
-
json_parse :scope, :
|
16
|
+
json_parse :scope, :external_key, :uniq, :limit, case: :snake
|
17
17
|
|
18
18
|
def initialize(options)
|
19
19
|
super(DEFAULT_OPTION.merge(options))
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Bidu
|
2
|
+
module House
|
3
|
+
class Report
|
4
|
+
class Range < Report
|
5
|
+
ALLOWED_PARAMETERS=[:period, :maximum, :minimum]
|
6
|
+
DEFAULT_OPTION = {
|
7
|
+
period: 1.day,
|
8
|
+
scope: :all,
|
9
|
+
minimum: nil,
|
10
|
+
maximum: nil
|
11
|
+
}
|
12
|
+
|
13
|
+
json_parse :scope
|
14
|
+
json_parse :minimum, :maximum, type: :integer
|
15
|
+
|
16
|
+
def initialize(options)
|
17
|
+
super(DEFAULT_OPTION.merge(options))
|
18
|
+
end
|
19
|
+
|
20
|
+
def scoped
|
21
|
+
@scoped ||= fetch_scoped(last_entries, scope)
|
22
|
+
end
|
23
|
+
|
24
|
+
def error?
|
25
|
+
@error ||= !count_in_range?
|
26
|
+
end
|
27
|
+
|
28
|
+
def as_json
|
29
|
+
{
|
30
|
+
status: status,
|
31
|
+
count: count
|
32
|
+
}
|
33
|
+
end
|
34
|
+
|
35
|
+
def count
|
36
|
+
scoped.count
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def range
|
42
|
+
(minimum..maximum)
|
43
|
+
end
|
44
|
+
|
45
|
+
def count_in_range?
|
46
|
+
return range.include?(count) unless (maximum.nil? || minimum.nil?)
|
47
|
+
return count >= minimum unless minimum.nil?
|
48
|
+
return count <= maximum unless maximum.nil?
|
49
|
+
true
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/bidu/house/version.rb
CHANGED
@@ -0,0 +1,302 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bidu::House::Report::Range do
|
4
|
+
let(:errors) { 1 }
|
5
|
+
let(:successes) { 1 }
|
6
|
+
let(:old_errors) { 2 }
|
7
|
+
let(:old_sucesses) { 2 }
|
8
|
+
let(:period) { 1.day }
|
9
|
+
let(:scope) { :with_error }
|
10
|
+
let(:maximum) { nil }
|
11
|
+
let(:minimum) { nil }
|
12
|
+
let(:options) do
|
13
|
+
{
|
14
|
+
period: period,
|
15
|
+
scope: scope,
|
16
|
+
clazz: Document,
|
17
|
+
minimum: minimum,
|
18
|
+
maximum: maximum
|
19
|
+
}
|
20
|
+
end
|
21
|
+
let(:subject) { described_class.new(options) }
|
22
|
+
let(:types) { [:a] }
|
23
|
+
before do
|
24
|
+
Document.all.each(&:destroy)
|
25
|
+
types.each do |type|
|
26
|
+
successes.times { Document.create status: :success, doc_type: type }
|
27
|
+
errors.times do |i|
|
28
|
+
Document.create status: :error, external_id: 10 * successes + i, outter_external_id: i, doc_type: type
|
29
|
+
end
|
30
|
+
old_errors.times do
|
31
|
+
Document.create status: :error, created_at: 2.days.ago, updated_at: 2.days.ago, doc_type: type
|
32
|
+
end
|
33
|
+
old_sucesses.times do
|
34
|
+
Document.create status: :success, created_at: 2.days.ago, updated_at: 2.days.ago, doc_type: type
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe '#status' do
|
40
|
+
context 'when looking for maximum counts' do
|
41
|
+
context 'when there are more errors than the allowed by the maximum' do
|
42
|
+
let(:errors) { 2 }
|
43
|
+
let(:maximum) { 1 }
|
44
|
+
it { expect(subject.status).to eq(:error) }
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'when the maximum is 0 and there are no errors' do
|
48
|
+
let(:errors) { 0 }
|
49
|
+
let(:maximum) { 0 }
|
50
|
+
it { expect(subject.status).to eq(:ok) }
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'when the maximum is nil and there are no errors' do
|
54
|
+
let(:errors) { 0 }
|
55
|
+
let(:maximum) { nil }
|
56
|
+
it { expect(subject.status).to eq(:ok) }
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'when the count is the same as the maximum' do
|
60
|
+
let(:errors) { 1 }
|
61
|
+
let(:maximum) { 1 }
|
62
|
+
it { expect(subject.status).to eq(:ok) }
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'when the count is less than the maximum' do
|
66
|
+
let(:errors) { 1 }
|
67
|
+
let(:maximum) { 2 }
|
68
|
+
it { expect(subject.status).to eq(:ok) }
|
69
|
+
end
|
70
|
+
|
71
|
+
context 'when there are older errors out of the period' do
|
72
|
+
let(:maximum) { 1 }
|
73
|
+
|
74
|
+
it 'ignores the older errros' do
|
75
|
+
expect(subject.status).to eq(:ok)
|
76
|
+
end
|
77
|
+
|
78
|
+
context 'when passing a bigger period' do
|
79
|
+
let(:period) { 3.days }
|
80
|
+
|
81
|
+
it 'consider the older errros' do
|
82
|
+
expect(subject.status).to eq(:error)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
context 'when looking for minimum' do
|
89
|
+
let(:scope) { :with_success }
|
90
|
+
context 'when there are less successes than the allowed by the minimum' do
|
91
|
+
let(:successes) { 1 }
|
92
|
+
let(:minimum) { 2 }
|
93
|
+
it { expect(subject.status).to eq(:error) }
|
94
|
+
end
|
95
|
+
|
96
|
+
context 'when the minimum is 0 and there are no sucesses' do
|
97
|
+
let(:successes) { 0 }
|
98
|
+
let(:minimum) { 0 }
|
99
|
+
it { expect(subject.status).to eq(:ok) }
|
100
|
+
end
|
101
|
+
|
102
|
+
context 'when the minimum is nil and there are no sucesses' do
|
103
|
+
let(:successes) { 0 }
|
104
|
+
let(:minimum) { nil }
|
105
|
+
it { expect(subject.status).to eq(:ok) }
|
106
|
+
end
|
107
|
+
|
108
|
+
context 'when the count is the same as the minimum' do
|
109
|
+
let(:successes) { 1 }
|
110
|
+
let(:minimum) { 1 }
|
111
|
+
it { expect(subject.status).to eq(:ok) }
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'when the count is greater than the minimum' do
|
115
|
+
let(:successes) { 2 }
|
116
|
+
let(:minimum) { 1 }
|
117
|
+
it { expect(subject.status).to eq(:ok) }
|
118
|
+
end
|
119
|
+
|
120
|
+
context 'when there are older sucesses out of the period' do
|
121
|
+
let(:successes) { 0 }
|
122
|
+
let(:minimum) { 1 }
|
123
|
+
|
124
|
+
it 'ignores the older sucesses' do
|
125
|
+
expect(subject.status).to eq(:error)
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'when passing a bigger period' do
|
129
|
+
let(:period) { 3.days }
|
130
|
+
|
131
|
+
it 'consider the older sucesses' do
|
132
|
+
expect(subject.status).to eq(:ok)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
context 'when looking for a range' do
|
139
|
+
let(:scope) { :all }
|
140
|
+
let(:minimum) { 2 }
|
141
|
+
let(:maximum) { 4 }
|
142
|
+
|
143
|
+
context 'when there are less documents than the allowed by the minimum' do
|
144
|
+
let(:successes) { 1 }
|
145
|
+
let(:errors) { 0 }
|
146
|
+
it { expect(subject.status).to eq(:error) }
|
147
|
+
end
|
148
|
+
|
149
|
+
context 'when the count is the same as the minimum' do
|
150
|
+
let(:successes) { 1 }
|
151
|
+
let(:errors) { 2 }
|
152
|
+
it { expect(subject.status).to eq(:ok) }
|
153
|
+
end
|
154
|
+
|
155
|
+
context 'when the count is inside the range' do
|
156
|
+
let(:successes) { 1 }
|
157
|
+
let(:errors) { 2 }
|
158
|
+
it { expect(subject.status).to eq(:ok) }
|
159
|
+
end
|
160
|
+
|
161
|
+
context 'when the count is the same as the maximum' do
|
162
|
+
let(:successes) { 2 }
|
163
|
+
let(:errors) { 2 }
|
164
|
+
it { expect(subject.status).to eq(:ok) }
|
165
|
+
end
|
166
|
+
|
167
|
+
context 'when the count is greater than the maximum' do
|
168
|
+
let(:successes) { 3 }
|
169
|
+
let(:errors) { 2 }
|
170
|
+
it { expect(subject.status).to eq(:error) }
|
171
|
+
end
|
172
|
+
|
173
|
+
context 'when the minimum is 0 and the count is 0' do
|
174
|
+
let(:successes) { 0 }
|
175
|
+
let(:errors) { 0 }
|
176
|
+
let(:minimum) { 0 }
|
177
|
+
it { expect(subject.status).to eq(:ok) }
|
178
|
+
end
|
179
|
+
|
180
|
+
context 'when there are older sucesses out of the period' do
|
181
|
+
let(:old_errors) { 1 }
|
182
|
+
let(:old_sucesses) { 2 }
|
183
|
+
|
184
|
+
context 'and the regular documents are not enough' do
|
185
|
+
let(:successes) { 1 }
|
186
|
+
let(:errors) { 0 }
|
187
|
+
|
188
|
+
it 'ignores the older sucesses' do
|
189
|
+
expect(subject.status).to eq(:error)
|
190
|
+
end
|
191
|
+
|
192
|
+
context 'when passing a bigger period' do
|
193
|
+
let(:period) { 3.days }
|
194
|
+
|
195
|
+
it 'consider the older sucesses' do
|
196
|
+
expect(subject.status).to eq(:ok)
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
|
201
|
+
context 'and the regular documents are almost in the limit' do
|
202
|
+
let(:successes) { 2 }
|
203
|
+
let(:errors) { 1 }
|
204
|
+
|
205
|
+
it 'ignores the older sucesses' do
|
206
|
+
expect(subject.status).to eq(:ok)
|
207
|
+
end
|
208
|
+
|
209
|
+
context 'when passing a bigger period' do
|
210
|
+
let(:period) { 3.days }
|
211
|
+
|
212
|
+
it 'consider the older documents' do
|
213
|
+
expect(subject.status).to eq(:error)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
describe '#count' do
|
222
|
+
let(:types) { [:a, :b] }
|
223
|
+
let(:errors) { 1 }
|
224
|
+
let(:scope) { :with_error }
|
225
|
+
|
226
|
+
it 'returns all the documents found' do
|
227
|
+
expect(subject.count).to eq(2)
|
228
|
+
end
|
229
|
+
|
230
|
+
context 'when configuring with a complex scope' do
|
231
|
+
let(:old_errors) { 0 }
|
232
|
+
let(:scope) { :'with_error.type_b' }
|
233
|
+
let(:errors) { 1 }
|
234
|
+
|
235
|
+
context 'as symbol' do
|
236
|
+
let(:scope) { :'with_error.type_b' }
|
237
|
+
|
238
|
+
it 'fetches from each scope in order' do
|
239
|
+
expect(subject.count).to eq(1)
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
context 'as string where scope' do
|
244
|
+
let(:scope) { "status = 'error' and doc_type = 'b'" }
|
245
|
+
|
246
|
+
it 'fetches from each scope in order' do
|
247
|
+
expect(subject.count).to eq(1)
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
context 'as hash where scope' do
|
252
|
+
let(:scope) { { status: :error, doc_type: :b } }
|
253
|
+
|
254
|
+
it 'fetches from each scope in order' do
|
255
|
+
expect(subject.count).to eq(1)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
describe '#error?' do
|
262
|
+
let(:errors) { 2 }
|
263
|
+
let(:maximum) { 1 }
|
264
|
+
|
265
|
+
context 'when errors count overcome maximum' do
|
266
|
+
it { expect(subject.error?).to be_truthy }
|
267
|
+
end
|
268
|
+
|
269
|
+
context 'when errors count do not overcome maximum' do
|
270
|
+
let(:errors) { 0 }
|
271
|
+
it { expect(subject.error?).to be_falsey }
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
describe '#as_json' do
|
276
|
+
let(:expected) do
|
277
|
+
{ count: count_expected, status: status_expected }
|
278
|
+
end
|
279
|
+
|
280
|
+
context 'when everything is ok' do
|
281
|
+
let(:errors) { 1 }
|
282
|
+
let(:status_expected) { :ok }
|
283
|
+
let(:count_expected) { errors }
|
284
|
+
let(:maximum) { 2 }
|
285
|
+
|
286
|
+
it 'returns the count and status' do
|
287
|
+
expect(subject.as_json).to eq(expected)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
context 'when there is an error' do
|
292
|
+
let(:errors) { 2 }
|
293
|
+
let(:status_expected) { :error }
|
294
|
+
let(:count_expected) { errors }
|
295
|
+
let(:maximum) { 1 }
|
296
|
+
|
297
|
+
it 'returns the count and status' do
|
298
|
+
expect(subject.as_json).to eq(expected)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
end
|
302
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bidu-house
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bidu Dev's Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-08-
|
11
|
+
date: 2016-08-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -164,6 +164,20 @@ dependencies:
|
|
164
164
|
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: codeclimate-test-reporter
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - ">="
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - ">="
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '0'
|
167
181
|
description: Gem for easy health check
|
168
182
|
email:
|
169
183
|
- dev@bidu.com.br
|
@@ -185,6 +199,7 @@ files:
|
|
185
199
|
- lib/bidu/house/concern.rb
|
186
200
|
- lib/bidu/house/report.rb
|
187
201
|
- lib/bidu/house/report/error.rb
|
202
|
+
- lib/bidu/house/report/range.rb
|
188
203
|
- lib/bidu/house/report_builder.rb
|
189
204
|
- lib/bidu/house/report_config.rb
|
190
205
|
- lib/bidu/house/status.rb
|
@@ -193,6 +208,7 @@ files:
|
|
193
208
|
- lib/bidu/period_parser.rb
|
194
209
|
- lib/json_parser/type_cast_ext.rb
|
195
210
|
- spec/lib/bidu/house/report/error_spec.rb
|
211
|
+
- spec/lib/bidu/house/report/range_spec.rb
|
196
212
|
- spec/lib/bidu/house/report/report_config_spec.rb
|
197
213
|
- spec/lib/bidu/house/report_builder_spec.rb
|
198
214
|
- spec/lib/bidu/house/status_builder_spec.rb
|