outpost 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/CHANGELOG.rdoc +16 -0
- data/Gemfile +9 -3
- data/Gemfile.lock +39 -0
- data/MIT-LICENSE +20 -0
- data/README.markdown +40 -8
- data/Rakefile +14 -0
- data/TODO.md +7 -0
- data/lib/outpost.rb +1 -1
- data/lib/outpost/application.rb +143 -0
- data/lib/outpost/expectations/response_body.rb +23 -9
- data/lib/outpost/expectations/response_code.rb +5 -0
- data/lib/outpost/expectations/response_time.rb +10 -1
- data/lib/outpost/notifiers.rb +2 -0
- data/lib/outpost/notifiers/campfire.rb +50 -0
- data/lib/outpost/notifiers/email.rb +59 -0
- data/lib/outpost/report.rb +7 -1
- data/lib/outpost/scout.rb +82 -0
- data/lib/outpost/scout_config.rb +10 -4
- data/lib/outpost/scouts/http.rb +28 -7
- data/lib/outpost/scouts/ping.rb +26 -6
- data/lib/outpost/version.rb +4 -1
- data/outpost.gemspec +0 -2
- data/test/integration/{basic_dsl_test.rb → basic_application_test.rb} +5 -5
- data/test/integration/more_complex_test.rb +20 -8
- data/test/integration/notifiers_test.rb +51 -0
- data/test/outpost/dsl_test.rb +74 -3
- data/test/outpost/expectations/response_body_test.rb +13 -15
- data/test/outpost/expectations/response_code_test.rb +5 -7
- data/test/outpost/expectations/response_time_test.rb +9 -11
- data/test/outpost/notifiers/campfire_test.rb +72 -0
- data/test/outpost/notifiers/email_test.rb +90 -0
- data/test/outpost/scout_test.rb +5 -6
- data/test/outpost/scouts/http_test.rb +51 -0
- data/test/outpost/scouts/ping_test.rb +41 -0
- data/test/support/nothing_raised.rb +10 -0
- data/test/support/server.rb +0 -1
- data/test/support/stubs.rb +11 -0
- data/test/test_helper.rb +8 -6
- metadata +32 -22
- data/lib/outpost/dsl.rb +0 -54
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
.yardoc
|
data/CHANGELOG.rdoc
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
|
2
|
+
== 0.2
|
3
|
+
* Features
|
4
|
+
* Adding support for Notifications (Email and Campfire)
|
5
|
+
* RDoc documentation
|
6
|
+
* Refactoring, tests and cleanups
|
7
|
+
|
8
|
+
* Deprecations
|
9
|
+
* Renaming Outpost::DSL to Outpost::Application
|
10
|
+
|
11
|
+
* Bug Fixes
|
12
|
+
* Fixing Rake task to publish the gem (by github.com/ManuelKiessling)
|
13
|
+
* HTTP Scout now fails when it is not able to connect to the server
|
14
|
+
|
15
|
+
== 0.1
|
16
|
+
* Initial release
|
data/Gemfile
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
source :rubygems
|
2
2
|
|
3
|
-
gem 'net-ping', :require => false
|
4
|
-
|
5
3
|
group :test do
|
4
|
+
gem 'mail', :require => false
|
5
|
+
gem 'net-ping', :require => false
|
6
|
+
gem 'tinder', :require => false
|
7
|
+
|
6
8
|
gem 'thin'
|
7
9
|
gem 'rack'
|
8
10
|
gem 'sinatra'
|
9
|
-
|
11
|
+
|
12
|
+
gem 'minitest', '~> 2.0.2', :platforms => :ruby_18
|
13
|
+
gem 'ruby-debug', :platforms => :ruby_18
|
14
|
+
|
15
|
+
gem 'ruby-debug19', :platforms => :ruby_19
|
10
16
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,14 +1,37 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
+
activesupport (3.0.3)
|
5
|
+
addressable (2.2.2)
|
4
6
|
archive-tar-minitar (0.5.2)
|
5
7
|
columnize (0.3.2)
|
6
8
|
daemons (1.1.0)
|
7
9
|
eventmachine (0.12.10)
|
10
|
+
faraday (0.5.4)
|
11
|
+
addressable (~> 2.2.2)
|
12
|
+
multipart-post (~> 1.1.0)
|
13
|
+
rack (>= 1.1.0, < 2)
|
14
|
+
i18n (0.5.0)
|
15
|
+
linecache (0.43)
|
8
16
|
linecache19 (0.5.11)
|
9
17
|
ruby_core_source (>= 0.1.4)
|
18
|
+
mail (2.2.15)
|
19
|
+
activesupport (>= 2.3.6)
|
20
|
+
i18n (>= 0.4.0)
|
21
|
+
mime-types (~> 1.16)
|
22
|
+
treetop (~> 1.4.8)
|
23
|
+
mime-types (1.16)
|
24
|
+
minitest (2.0.2)
|
25
|
+
multipart-post (1.1.0)
|
10
26
|
net-ping (1.3.7)
|
27
|
+
polyglot (0.3.1)
|
11
28
|
rack (1.2.1)
|
29
|
+
roauth (0.0.3)
|
30
|
+
ruby-debug (0.10.4)
|
31
|
+
columnize (>= 0.1)
|
32
|
+
ruby-debug-base (~> 0.10.4.0)
|
33
|
+
ruby-debug-base (0.10.4)
|
34
|
+
linecache (>= 0.3)
|
12
35
|
ruby-debug-base19 (0.11.24)
|
13
36
|
columnize (>= 0.3.1)
|
14
37
|
linecache19 (>= 0.5.11)
|
@@ -27,13 +50,29 @@ GEM
|
|
27
50
|
eventmachine (>= 0.12.6)
|
28
51
|
rack (>= 1.0.0)
|
29
52
|
tilt (1.2.2)
|
53
|
+
tinder (1.4.3)
|
54
|
+
activesupport
|
55
|
+
eventmachine
|
56
|
+
faraday (~> 0.5.1)
|
57
|
+
mime-types
|
58
|
+
multipart-post
|
59
|
+
twitter-stream
|
60
|
+
treetop (1.4.9)
|
61
|
+
polyglot (>= 0.3.1)
|
62
|
+
twitter-stream (0.1.10)
|
63
|
+
eventmachine (>= 0.12.8)
|
64
|
+
roauth (>= 0.0.2)
|
30
65
|
|
31
66
|
PLATFORMS
|
32
67
|
ruby
|
33
68
|
|
34
69
|
DEPENDENCIES
|
70
|
+
mail
|
71
|
+
minitest (~> 2.0.2)
|
35
72
|
net-ping
|
36
73
|
rack
|
74
|
+
ruby-debug
|
37
75
|
ruby-debug19
|
38
76
|
sinatra
|
39
77
|
thin
|
78
|
+
tinder
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Vinicius Baggio Fuentes http://www.vinibaggio.net
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
CHANGED
@@ -1,8 +1,5 @@
|
|
1
1
|
# Outpost
|
2
2
|
|
3
|
-
Outpost is under development and is a project for the RMU: Ruby Mendicant
|
4
|
-
University.
|
5
|
-
|
6
3
|
## Features
|
7
4
|
|
8
5
|
Outpost is a tool to monitor the state of your service (not server). What does it mean?
|
@@ -21,8 +18,14 @@ It should report a status per declared system.
|
|
21
18
|
The idea is to make a reliable framework for the Ruby developer to create his own monitoring rules.
|
22
19
|
So, summing it all up, Nagios in Ruby, much cooler!
|
23
20
|
|
21
|
+
## Information
|
22
|
+
|
23
|
+
* [Rdoc](http://rdoc.info/github/vinibaggio/outpost/master/frames)
|
24
|
+
|
24
25
|
## Installing
|
25
26
|
|
27
|
+
Outpost is tested with Ruby 1.8.7 and Ruby 1.9.2.
|
28
|
+
|
26
29
|
gem install outpost
|
27
30
|
|
28
31
|
## Starting
|
@@ -33,7 +36,7 @@ To create your Outposts, you must require 'outpost'. You also need to include
|
|
33
36
|
require 'outpost'
|
34
37
|
require 'outpost/scouts'
|
35
38
|
|
36
|
-
class Bla < Outpost::
|
39
|
+
class Bla < Outpost::Application
|
37
40
|
using Outpost::Scouts::Http => "web page" do
|
38
41
|
options :host => 'localhost', :port => 3000
|
39
42
|
report :up, :response_code => 200
|
@@ -52,7 +55,7 @@ Consider the following example:
|
|
52
55
|
require 'outpost'
|
53
56
|
require 'outpost/scouts'
|
54
57
|
|
55
|
-
class HttpOutpostExample < Outpost::
|
58
|
+
class HttpOutpostExample < Outpost::Application
|
56
59
|
using Outpost::Scouts::Http => "web page" do
|
57
60
|
options :host => 'localhost', :port => 3000
|
58
61
|
report :up, :response_code => 200
|
@@ -71,7 +74,7 @@ reporting "down" in that case).
|
|
71
74
|
## Outpost
|
72
75
|
|
73
76
|
Outpost is the description of the system and provides a DSL to do it.
|
74
|
-
Check "How it works" section for an example, or check the [integration tests](https://github.com/vinibaggio/outpost/blob/master/test/integration/
|
77
|
+
Check "How it works" section for an example, or check the [integration tests](https://github.com/vinibaggio/outpost/blob/master/test/integration/basic_application_test.rb)
|
75
78
|
for more.
|
76
79
|
|
77
80
|
## Scout
|
@@ -150,10 +153,39 @@ So you can easily create your own expectation. Let's recreate the :response\_cod
|
|
150
153
|
You can also check the supplied expectations in the source of the project to have
|
151
154
|
an idea on how to implement more complex rules.
|
152
155
|
|
156
|
+
## Notifiers
|
157
|
+
|
158
|
+
Notifiers query Outposts and act upon its status and reports. In the example
|
159
|
+
below, an Email notifier is being used to report failures in the system to the
|
160
|
+
system administrator:
|
161
|
+
|
162
|
+
require 'outpost'
|
163
|
+
require 'outpost/scouts'
|
164
|
+
require 'outpost/notifiers'
|
165
|
+
|
166
|
+
class HttpOutpostExample < Outpost::Application
|
167
|
+
notify Outpost::Notifiers::Email, {
|
168
|
+
:from => 'outpost@example.com',
|
169
|
+
:to => 'sleep_deprived_admin@example.com'
|
170
|
+
}
|
171
|
+
|
172
|
+
using Outpost::Scouts::Http => "web page" do
|
173
|
+
options :host => 'localhost', :port => 3000
|
174
|
+
report :up, :response_code => 200
|
175
|
+
report :down, :response_body => {:match => /Ops/}
|
176
|
+
end
|
177
|
+
end
|
178
|
+
outpost = HttpOutpostExample.new
|
179
|
+
outpost.run # => :down
|
180
|
+
|
181
|
+
# Will send an email to the poor sleep-deprived Sys Admin if the system is
|
182
|
+
# down.
|
183
|
+
outpost.notify if outpost.down?
|
184
|
+
|
153
185
|
## TODO
|
154
186
|
|
155
|
-
|
187
|
+
See [TODO](https://github.com/vinibaggio/outpost/blob/master/TODO.md).
|
156
188
|
|
157
189
|
## License
|
158
190
|
|
159
|
-
MIT.
|
191
|
+
MIT License.
|
data/Rakefile
CHANGED
@@ -1,5 +1,9 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __FILE__)
|
2
|
+
|
1
3
|
require 'rake/testtask'
|
2
4
|
|
5
|
+
require "outpost/version"
|
6
|
+
|
3
7
|
desc 'Default: run tests'
|
4
8
|
task :default => :test
|
5
9
|
|
@@ -10,3 +14,13 @@ Rake::TestTask.new(:test) do |t|
|
|
10
14
|
t.pattern = 'test/**/*_test.rb'
|
11
15
|
t.verbose = true
|
12
16
|
end
|
17
|
+
|
18
|
+
desc 'Build a gem from gemspec'
|
19
|
+
task :build do
|
20
|
+
system "gem build outpost.gemspec"
|
21
|
+
end
|
22
|
+
|
23
|
+
desc 'Release new gem version'
|
24
|
+
task :release => :build do
|
25
|
+
system "gem push outpost-#{Outpost::VERSION}.gem"
|
26
|
+
end
|
data/TODO.md
ADDED
data/lib/outpost.rb
CHANGED
@@ -0,0 +1,143 @@
|
|
1
|
+
module Outpost
|
2
|
+
# This class is the basic structure of an Outpost application. It provides
|
3
|
+
# the basic DSL for you to configure the monitoring of your services.
|
4
|
+
# Example:
|
5
|
+
#
|
6
|
+
# class ExampleSuccess < Outpost::Application
|
7
|
+
# name "Example"
|
8
|
+
# using Outpost::Scouts::Http => 'master http server' do
|
9
|
+
# options :host => 'localhost', :port => 9595
|
10
|
+
# report :up, :response_code => 200
|
11
|
+
# end
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# @abstract
|
15
|
+
class Application
|
16
|
+
class << self
|
17
|
+
# Returns all the registered scouts.
|
18
|
+
attr_reader :scouts
|
19
|
+
|
20
|
+
# Returns all the registered notifiers.
|
21
|
+
attr_reader :notifiers
|
22
|
+
|
23
|
+
# Register a scout in the list of scouts.
|
24
|
+
#
|
25
|
+
# @param [Hash{Scout => String}, #read] scout_description A hash
|
26
|
+
# containing Scout class as key and its description as a value.
|
27
|
+
#
|
28
|
+
# @yield Block to be evaluated to configure the current {Scout}.
|
29
|
+
def using(scout_description, &block)
|
30
|
+
@scouts ||= Hash.new { |h, k| h[k] = {} }
|
31
|
+
|
32
|
+
config = ScoutConfig.new
|
33
|
+
config.instance_eval(&block)
|
34
|
+
|
35
|
+
scout_description.each do |scout, description|
|
36
|
+
@scouts[scout][:description] = description
|
37
|
+
@scouts[scout][:config] = config
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# Register a notifier class in the list of notifications.
|
42
|
+
#
|
43
|
+
# @param [Class, #read] class A class that will be used to issue
|
44
|
+
# a notification. The class must accept a configuration hash in the
|
45
|
+
# constructor and also implement a #notify method that will receive an
|
46
|
+
# outpost instance. See {Outpost::Notifiers::Email} for an example.
|
47
|
+
#
|
48
|
+
# @param [Hash, #read] options Options that will be used to configure the
|
49
|
+
# notification class.
|
50
|
+
def notify(notifier, options={})
|
51
|
+
@notifiers ||= {}
|
52
|
+
@notifiers[notifier] = options
|
53
|
+
end
|
54
|
+
|
55
|
+
# Set the name of the scout. Can be used by notifiers in order to have
|
56
|
+
# a better description of the service in question.
|
57
|
+
#
|
58
|
+
# @param [String, #read] name The name to be given to a Outpost-based
|
59
|
+
# class.
|
60
|
+
def name(val=nil)
|
61
|
+
if val
|
62
|
+
@name = val
|
63
|
+
else
|
64
|
+
@name
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns the status of the last service check or nil if it didn't happen.
|
70
|
+
attr_reader :last_status
|
71
|
+
|
72
|
+
# Returns a list of {Report} containing the last results of the last check.
|
73
|
+
attr_reader :reports
|
74
|
+
|
75
|
+
# New instance of a Outpost-based class.
|
76
|
+
def initialize
|
77
|
+
@reports = []
|
78
|
+
@last_status = nil
|
79
|
+
end
|
80
|
+
|
81
|
+
# Execute all the scouts associated with an Outpost-based class and returns
|
82
|
+
# either :up or :down, depending on the results.
|
83
|
+
def run
|
84
|
+
@reports = self.class.scouts.map do |scout, options|
|
85
|
+
run_scout(scout, options)
|
86
|
+
end
|
87
|
+
|
88
|
+
statuses = @reports.map { |r| r.status }
|
89
|
+
|
90
|
+
@last_status = Report.summarize(statuses)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Runs all notifications associated with an Outpost-based class.
|
94
|
+
def notify
|
95
|
+
if reports.any?
|
96
|
+
self.class.notifiers.each do |notifier, options|
|
97
|
+
# .dup is NOT reliable
|
98
|
+
options_copy = Marshal.load(Marshal.dump(options))
|
99
|
+
notifier.new(options_copy).notify(self)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns true if the last status is :up
|
105
|
+
def up?
|
106
|
+
@last_status == :up
|
107
|
+
end
|
108
|
+
|
109
|
+
# Returns true if the last status is :down
|
110
|
+
def down?
|
111
|
+
@last_status == :down
|
112
|
+
end
|
113
|
+
|
114
|
+
# Returns the name of an Outpost-based class or the class name itself if
|
115
|
+
# not set.
|
116
|
+
#
|
117
|
+
# @return [String] The name of the Outpost
|
118
|
+
def name
|
119
|
+
self.class.name || self.class.to_s
|
120
|
+
end
|
121
|
+
|
122
|
+
# Returns the messages of the latest service check.
|
123
|
+
#
|
124
|
+
# @return [Array<String>] An array containing all report messages.
|
125
|
+
def messages
|
126
|
+
reports.map { |r| r.to_s }
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
# :nodoc:
|
132
|
+
def run_scout(scout, options)
|
133
|
+
scout_instance = scout.new(options[:description], options[:config])
|
134
|
+
|
135
|
+
params = {
|
136
|
+
:name => scout.name,
|
137
|
+
:description => options[:description],
|
138
|
+
:status => scout_instance.run
|
139
|
+
}
|
140
|
+
Report.new(params)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
@@ -1,20 +1,34 @@
|
|
1
1
|
module Outpost
|
2
2
|
module Expectations
|
3
|
+
# Module containing response_body matching expectations. Extend your Scout
|
4
|
+
# with ResponseBody and it will gain response_body evaluation powers!
|
5
|
+
#
|
6
|
+
# It respond to the following rules:
|
7
|
+
# * match => If the response body matches the associated regular expression
|
8
|
+
# * not_match => If the response body does not match the associated regular
|
9
|
+
# expression
|
10
|
+
# * equals => If the response body matches exactly the associated string
|
11
|
+
# * differs => If the response body differs in any way the associated
|
12
|
+
# string.
|
3
13
|
module ResponseBody
|
4
|
-
|
5
|
-
:match => "=~",
|
6
|
-
:not_match => "!~",
|
7
|
-
:equals => "==",
|
8
|
-
:differs => "!="
|
9
|
-
}.freeze
|
10
|
-
|
14
|
+
# Installs the response body expectation
|
11
15
|
def self.extended(base)
|
12
16
|
base.expect :response_body, base.method(:evaluate_response_body)
|
13
17
|
end
|
14
18
|
|
19
|
+
# Method that will be used as an expectation to evaluate response body
|
15
20
|
def evaluate_response_body(scout, rules)
|
16
|
-
rules.all? do |rule,comparison|
|
17
|
-
|
21
|
+
rules.all? do |rule, comparison|
|
22
|
+
case rule
|
23
|
+
when :match
|
24
|
+
scout.response_body =~ comparison
|
25
|
+
when :not_match
|
26
|
+
scout.response_body !~ comparison
|
27
|
+
when :equals
|
28
|
+
scout.response_body == comparison
|
29
|
+
when :differs
|
30
|
+
scout.response_body != comparison
|
31
|
+
end
|
18
32
|
end
|
19
33
|
end
|
20
34
|
end
|