bidu-house 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.
- 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
|
+
[](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
|