updawg 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.gitignore +25 -0
- data/CHANGELOG +8 -0
- data/Gemfile +13 -0
- data/LICENSE +20 -0
- data/README.rdoc +99 -0
- data/Rakefile +45 -0
- data/VERSION +1 -0
- data/lib/updawg.rb +36 -0
- data/lib/updawg/checks.rb +3 -0
- data/lib/updawg/checks/check.rb +67 -0
- data/lib/updawg/checks/deviation_check.rb +64 -0
- data/lib/updawg/checks/threshold_check.rb +36 -0
- data/lib/updawg/monitor.rb +33 -0
- data/lib/updawg/results.rb +111 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/updawg/checks/check_spec.rb +112 -0
- data/spec/updawg/checks/deviation_check_spec.rb +125 -0
- data/spec/updawg/checks/threshold_check_spec.rb +43 -0
- data/spec/updawg/monitor_spec.rb +68 -0
- data/spec/updawg/results_spec.rb +118 -0
- data/spec/updawg_spec.rb +59 -0
- data/updawg.gemspec +81 -0
- metadata +156 -0
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'builder'
|
2
|
+
|
3
|
+
module Updawg
|
4
|
+
class ResultSet < Array
|
5
|
+
def success?
|
6
|
+
map { |result| result.success? }.all?
|
7
|
+
end
|
8
|
+
|
9
|
+
def warning?
|
10
|
+
map { |result| result.warning? }.any? && !error?
|
11
|
+
end
|
12
|
+
|
13
|
+
def error?
|
14
|
+
map { |result| result.error? }.any?
|
15
|
+
end
|
16
|
+
|
17
|
+
def errors
|
18
|
+
select { |result| result.error? }
|
19
|
+
end
|
20
|
+
|
21
|
+
def warnings
|
22
|
+
select { |result| result.warning? }
|
23
|
+
end
|
24
|
+
|
25
|
+
def status
|
26
|
+
return :error if error?
|
27
|
+
return :warning if warning?
|
28
|
+
:pass
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_html(builder = Builder::XmlMarkup.new)
|
32
|
+
builder.table('class' => status.to_s) do |b|
|
33
|
+
each do |result|
|
34
|
+
b.tr('class' => result.status.to_s) do |tr|
|
35
|
+
tr.td(result.name, 'class' => 'name')
|
36
|
+
tr.td(result.message, 'class' => 'message')
|
37
|
+
tr.td(result.status_text, 'class' => 'status')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_text
|
44
|
+
map do |r|
|
45
|
+
"#{r.status_text}\t#{r.name} - #{r.message}\n"
|
46
|
+
end.join
|
47
|
+
end
|
48
|
+
|
49
|
+
def nagios_report!(stream = STDOUT)
|
50
|
+
if error?
|
51
|
+
status = "CRITICAL"
|
52
|
+
service = errors.first
|
53
|
+
message = " #{service.name} #{service.message}"
|
54
|
+
elsif warning?
|
55
|
+
status ||= "WARNING"
|
56
|
+
service = warnings.first
|
57
|
+
message = " #{service.name} #{service.message}"
|
58
|
+
else
|
59
|
+
status ||= "OK"
|
60
|
+
message = ""
|
61
|
+
end
|
62
|
+
|
63
|
+
warning_count = warnings.size
|
64
|
+
error_count = errors.size
|
65
|
+
passed_count = size - error_count - warning_count
|
66
|
+
|
67
|
+
service_output = ["#{status}#{message}", "OK:#{passed_count} WRN:#{warning_count} CRT:#{error_count}"]
|
68
|
+
stream.write "#{service_output.join("; ")}\n"
|
69
|
+
stream.write to_text
|
70
|
+
return exit(2) if error?
|
71
|
+
return exit(1) if warning?
|
72
|
+
exit(0)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
class Result
|
77
|
+
attr_reader :name, :status, :message
|
78
|
+
|
79
|
+
def initialize(name, status = :pass, message = nil)
|
80
|
+
@name = name
|
81
|
+
@status = status
|
82
|
+
@message = message
|
83
|
+
end
|
84
|
+
|
85
|
+
def success?
|
86
|
+
:pass == @status
|
87
|
+
end
|
88
|
+
|
89
|
+
def warning?
|
90
|
+
:warning == @status
|
91
|
+
end
|
92
|
+
|
93
|
+
def error?
|
94
|
+
:error == @status
|
95
|
+
end
|
96
|
+
|
97
|
+
def status_text
|
98
|
+
return Updawg.configuration.error_text if error?
|
99
|
+
return Updawg.configuration.warning_text if warning?
|
100
|
+
Updawg.configuration.success_text
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
class ResultException < Exception
|
105
|
+
attr_reader :result
|
106
|
+
|
107
|
+
def initialize(result)
|
108
|
+
@result = result
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'bundler'
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
|
8
|
+
require 'updawg'
|
9
|
+
require 'spec'
|
10
|
+
require 'spec/autorun'
|
11
|
+
|
12
|
+
|
13
|
+
Spec::Runner.configure do |config|
|
14
|
+
|
15
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Updawg::Check do
|
4
|
+
describe 'initialize' do
|
5
|
+
it 'should save the block' do
|
6
|
+
block = lambda { 'eep' }
|
7
|
+
check = Updawg::Check.new('test', &block)
|
8
|
+
check.instance_eval { @block }.should == block
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
describe 'perform' do
|
13
|
+
describe 'with a successful block' do
|
14
|
+
before(:each) do
|
15
|
+
@check = Updawg::Check.new('test'){}
|
16
|
+
@result = @check.perform
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should return a result' do
|
20
|
+
@result.should be_instance_of(Updawg::Result)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should be successful' do
|
24
|
+
@result.should be_success
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should not have a message' do
|
28
|
+
@result.message.should == nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should be a warning when the block returns warning' do
|
33
|
+
Updawg::Check.new('test') { warning('eep') }.perform.should be_warning
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should be an error when the block returns error' do
|
37
|
+
Updawg::Check.new('test') { error('eep') }.perform.should be_error
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should not eat low-level errors' do
|
41
|
+
expect { Updawg::Check.new('test') { xyz }.perform }.to raise_error(NameError)
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'with xxx! results' do
|
45
|
+
it 'should not raise an exception' do
|
46
|
+
lambda { Updawg::Check.new('test') { pass!('everything is ok!') } }.should_not raise_error
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should stop execution and be a warning after warning!' do
|
50
|
+
something = mock('value')
|
51
|
+
something.should_receive(:go).exactly(0).times
|
52
|
+
|
53
|
+
Updawg::Check.new('test') { warning!('this executes first'); something.go() }.perform.should be_warning
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'should stop execution and be an error after error!' do
|
57
|
+
something = mock('value')
|
58
|
+
something.should_receive(:go).exactly(0).times
|
59
|
+
|
60
|
+
Updawg::Check.new('test') { error!('this executes first'); something.go() }.perform.should be_error
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'when the block raises an error' do
|
65
|
+
before(:each) do
|
66
|
+
@check = Updawg::Check.new('test'){ raise 'error: frog' }
|
67
|
+
lambda { @result = @check.perform }.should_not raise_error
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'should be an error' do
|
71
|
+
@result.should be_error
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should have an error message' do
|
75
|
+
@result.message.should == 'error: frog'
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe 'when the block execution exceeds the timeout' do
|
80
|
+
before(:each) do
|
81
|
+
@check = Updawg::Check.new('test', :timeout => 0.1){ sleep 1 }
|
82
|
+
@result = @check.perform
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should be an error' do
|
86
|
+
@result.should be_error
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should have a timeout message' do
|
90
|
+
@result.message.should match(/timeout/)
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe 'with timeout value' do
|
95
|
+
before(:each) do
|
96
|
+
Updawg.configuration.timeout = 99
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should use the default if none is set' do
|
100
|
+
check = Updawg::Check.new('test') {}
|
101
|
+
Updawg::Timeout.should_receive(:timeout).with(99)
|
102
|
+
check.perform
|
103
|
+
end
|
104
|
+
|
105
|
+
it 'should use the check timeout if provided' do
|
106
|
+
check = Updawg::Check.new('test', :timeout => 5) {}
|
107
|
+
Updawg::Timeout.should_receive(:timeout).with(5)
|
108
|
+
check.perform
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,125 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Updawg::DeviationCheck do
|
4
|
+
it 'should raise ArgumentError if an invalid option is provided' do
|
5
|
+
lambda {
|
6
|
+
subject.new('test', :im_a_little_teapot => 1){}
|
7
|
+
}.should raise_error(ArgumentError)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should pass with an empty value list' do
|
11
|
+
check = Updawg::DeviationCheck.new('test'){ [] }
|
12
|
+
check.perform.should be_success
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'should pass with a value list containing one item' do
|
16
|
+
check = Updawg::DeviationCheck.new('test'){ [1] }
|
17
|
+
check.perform.should be_success
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should pass with a value list containing two items' do
|
21
|
+
check = Updawg::DeviationCheck.new('test'){ [0.25, 0.25] }
|
22
|
+
check.perform.should be_success
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should pass with a value list of all 0s' do
|
26
|
+
check = Updawg::DeviationCheck.new('test'){ [0, 0.0, 0, 0.0] }
|
27
|
+
check.perform.should be_success
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'by default' do
|
31
|
+
before(:each) do
|
32
|
+
@check = Updawg::DeviationCheck.new('test'){ }
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should have smoothing on' do
|
36
|
+
@check.smoothing.should be_true
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should have a scale factor of 2' do
|
40
|
+
@check.scale_factor.should == 2
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe 'with a value set' do
|
45
|
+
before(:each) do
|
46
|
+
@values = [19, 18, 16, 11, 18, 10, 16, 13, 11, 14]
|
47
|
+
@avg = 14.6
|
48
|
+
@std_dev = 3.27278338896896
|
49
|
+
@options = {:scale_factor => 2}
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'with smoothing enabled' do
|
53
|
+
before(:each) do
|
54
|
+
@options = {:smoothing => true}
|
55
|
+
@smooth_values = [16, 16, 13, 14]
|
56
|
+
@avg = 14.75
|
57
|
+
@std_dev = 1.5
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'should error with a value above the range' do
|
61
|
+
check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg + 2 * @std_dev + 0.01] }
|
62
|
+
result = check.perform
|
63
|
+
result.message.should match(/above expected maximum/)
|
64
|
+
result.should be_error
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should error with a value below the range' do
|
68
|
+
check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg - 2 * @std_dev - 0.01] }
|
69
|
+
result = check.perform
|
70
|
+
result.message.should match(/below expected minimum/)
|
71
|
+
result.should be_error
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should pass with value in the range' do
|
75
|
+
check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg] }
|
76
|
+
check.perform.should be_success
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should pass with high edge value in the range' do
|
80
|
+
check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg + 2 * @std_dev] }
|
81
|
+
check.perform.should be_success
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'should pass with low edge value in the range' do
|
85
|
+
check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg - 2 * @std_dev] }
|
86
|
+
check.perform.should be_success
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe 'with smoothing disabled' do
|
91
|
+
before(:each) do
|
92
|
+
@options[:smoothing] = false
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'should error with a value above the range' do
|
96
|
+
check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg + 2 * @std_dev] }
|
97
|
+
result = check.perform
|
98
|
+
result.message.should match(/above expected maximum/)
|
99
|
+
result.should be_error
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'should error with a value below the range' do
|
103
|
+
check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg - 2 * @std_dev] }
|
104
|
+
result = check.perform
|
105
|
+
result.message.should match(/below expected minimum/)
|
106
|
+
result.should be_error
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'should pass with value in the range' do
|
110
|
+
check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg] }
|
111
|
+
check.perform.should be_success
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'should pass with high edge value in the range' do
|
115
|
+
check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg + 2 * @std_dev - 0.01] }
|
116
|
+
check.perform.should be_success
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should pass with low edge value in the range' do
|
120
|
+
check = Updawg::DeviationCheck.new('test', @options){ @values + [@avg - 2 * @std_dev + 0.01] }
|
121
|
+
check.perform.should be_success
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Updawg::ThresholdCheck do
|
4
|
+
it 'should raise ArgumentError if an invalid option is provided' do
|
5
|
+
lambda {
|
6
|
+
Updawg::ThresholdCheck.new('test', :im_a_little_teapot => 1){}
|
7
|
+
}.should raise_error(ArgumentError)
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'should accept a block for the check value' do
|
11
|
+
generator = mock('value')
|
12
|
+
generator.should_receive(:value).and_return(1)
|
13
|
+
|
14
|
+
Updawg::ThresholdCheck.new('test') do
|
15
|
+
generator.value
|
16
|
+
end.perform
|
17
|
+
end
|
18
|
+
|
19
|
+
|
20
|
+
it 'should be a warning if the value is under warning threshold' do
|
21
|
+
Updawg::ThresholdCheck.new('test', :warning_under => 10) { 9 }.perform.should be_warning
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should be a warning if the value is over warning threshold' do
|
25
|
+
Updawg::ThresholdCheck.new('test', :warning_over => 10) { 11 }.perform.should be_warning
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'should be an error if the value is over the error threshold' do
|
29
|
+
Updawg::ThresholdCheck.new('test', :error_over => 10) { 11 }.perform.should be_error
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should be an error if the value is under the error threshold' do
|
33
|
+
Updawg::ThresholdCheck.new('test', :error_under => 10) { 9 }.perform.should be_error
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'should be successful if the value is in the sweet spot' do
|
37
|
+
Updawg::ThresholdCheck.new('test',
|
38
|
+
:warning_under => 9, :warning_over => 11,
|
39
|
+
:error_under => 8, :error_over => 12) do
|
40
|
+
10
|
41
|
+
end.perform.should be_success
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Updawg::Monitor do
|
4
|
+
before(:each) do
|
5
|
+
@monitor = Updawg::Monitor.new
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'by default' do
|
9
|
+
it 'should have an empty list of checks' do
|
10
|
+
@monitor.checks.should == []
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe '#check' do
|
15
|
+
it 'should create a new check' do
|
16
|
+
@monitor.check('test'){ 'eep'}.should be_instance_of(Updawg::Check)
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'should set the name of the check' do
|
20
|
+
@monitor.check('test'){ 'eep'}.name.should == 'test'
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should create a new check each call' do
|
24
|
+
@monitor.check('test'){}.should_not === @monitor.check('ok'){}
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should add the check to the list' do
|
28
|
+
check = @monitor.check('test'){}
|
29
|
+
@monitor.checks.should include(check)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#threshold' do
|
34
|
+
it 'should create a threshold check' do
|
35
|
+
args = ['test', {}]
|
36
|
+
block = Proc.new{1}
|
37
|
+
Updawg::ThresholdCheck.should_receive(:new).with(*args, &block).and_return(check = mock('threshold'))
|
38
|
+
@monitor.threshold(*args, &block).should == check
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should add the check to the list' do
|
42
|
+
check = @monitor.threshold('test')
|
43
|
+
@monitor.checks.should include(check)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#deviation' do
|
48
|
+
it 'should create a deviation check' do
|
49
|
+
args = ['test', {}]
|
50
|
+
block = Proc.new{1}
|
51
|
+
Updawg::DeviationCheck.should_receive(:new).with(*args, &block).and_return(check = mock('deviation'))
|
52
|
+
@monitor.deviation(*args, &block).should == check
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
describe '#perform' do
|
57
|
+
before(:each) do
|
58
|
+
@monitor.check 'One'
|
59
|
+
@monitor.check 'Two'
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should return result set with a result for each check' do
|
63
|
+
results = @monitor.perform
|
64
|
+
results.should be_instance_of(Updawg::ResultSet)
|
65
|
+
results.map { |result| result.name }.should == %w(One Two)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|