outpost 0.1.0 → 0.2.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.
- 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
|