updawg 0.3.5
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/.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
|