inari 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +20 -6
- data/lib/inari.rb +5 -2
- data/lib/inari/commands.rb +22 -23
- data/lib/inari/commands/http.rb +43 -27
- data/lib/inari/commands/smtp.rb +3 -3
- data/lib/inari/commands/tcp_simple.rb +3 -3
- data/lib/inari/commands/test.rb +2 -2
- data/lib/inari/misc.rb +6 -0
- data/lib/inari/version.rb +2 -2
- data/test/abstract_test.rb +4 -0
- data/test/commands/http_test.rb +22 -0
- data/test/commands/tcp_simple_test.rb +13 -0
- data/test/configuration_test.rb +0 -5
- metadata +20 -33
- data/InstalledFiles +0 -1
- data/lib/inari/response.rb +0 -9
data/Rakefile
CHANGED
@@ -4,10 +4,11 @@ require 'rake/testtask'
|
|
4
4
|
require 'rake/rdoctask'
|
5
5
|
require 'rake/gempackagetask'
|
6
6
|
require 'inari/version'
|
7
|
+
require 'rake/contrib/rubyforgepublisher'
|
7
8
|
|
8
9
|
desc 'Run the functional and unit tests.'
|
9
10
|
Rake::TestTask.new(:test) do |t|
|
10
|
-
t.test_files = FileList['test/*_test.rb']
|
11
|
+
t.test_files = FileList['test/*_test.rb'] + FileList['test/*/*_test.rb']
|
11
12
|
t.verbose = true
|
12
13
|
end
|
13
14
|
|
@@ -23,11 +24,11 @@ end
|
|
23
24
|
|
24
25
|
task :default => :test
|
25
26
|
|
26
|
-
|
27
|
+
spec = Gem::Specification.new do |s|
|
27
28
|
s.name = 'inari'
|
28
29
|
s.version = Inari::INARI_VERSION
|
29
30
|
s.date = Inari::INARI_RELEASE_DATE
|
30
|
-
s.summary = 'Inari is a
|
31
|
+
s.summary = 'Inari is a system monitoring program.'
|
31
32
|
s.email = 'alex@helicoid.net'
|
32
33
|
s.homepage = Inari::UPSTREAM_URL
|
33
34
|
s.rubyforge_project = 'inari'
|
@@ -38,7 +39,7 @@ Spec = Gem::Specification.new do |s|
|
|
38
39
|
s.files = FileList['lib/**/*.rb', 'bin/*', '[A-Z]*', 'test/**/*'].to_a
|
39
40
|
s.test_files = Dir['test/test_*.rb']
|
40
41
|
s.requirements = ['logger']
|
41
|
-
s.post_install_message = <<EOF
|
42
|
+
"""s.post_install_message = <<EOF
|
42
43
|
|
43
44
|
Welcome to Inari
|
44
45
|
================
|
@@ -51,12 +52,25 @@ Take a look at README for help on writing configuration files.
|
|
51
52
|
|
52
53
|
http://inari.rubyforge.org
|
53
54
|
|
54
|
-
EOF
|
55
|
+
EOF"""
|
55
56
|
|
56
57
|
end
|
57
58
|
|
58
59
|
task :gem => [:test]
|
59
|
-
Rake::GemPackageTask.new(
|
60
|
+
Rake::GemPackageTask.new(spec) do |p|
|
61
|
+
p.gem_spec = spec
|
60
62
|
p.need_tar = true
|
63
|
+
p.need_zip = true
|
61
64
|
end
|
62
65
|
|
66
|
+
desc 'Publish the release files to RubyForge.'
|
67
|
+
task :release => [:package] do
|
68
|
+
`rubyforge login`
|
69
|
+
|
70
|
+
for ext in %w(gem tgz zip)
|
71
|
+
pub = Rake::SshFilePublisher.new('alex_young@rubyforge.org',
|
72
|
+
'/var/www/gforge-projects/inari',
|
73
|
+
"pkg/inari-#{Inari::INARI_VERSION}.#{ext}")
|
74
|
+
pub.upload
|
75
|
+
end
|
76
|
+
end
|
data/lib/inari.rb
CHANGED
@@ -5,10 +5,13 @@ require 'socket'
|
|
5
5
|
require 'net/smtp'
|
6
6
|
require 'timeout'
|
7
7
|
require 'singleton'
|
8
|
-
require '
|
8
|
+
require 'digest'
|
9
|
+
require 'digest/md5'
|
9
10
|
require 'tmpdir'
|
11
|
+
require 'logger'
|
10
12
|
|
11
13
|
# Inari's classes and modules
|
14
|
+
require 'inari/misc'
|
12
15
|
require 'inari/daemon'
|
13
16
|
require 'inari/commands'
|
14
17
|
require 'inari/task_manager'
|
@@ -41,4 +44,4 @@ module Inari
|
|
41
44
|
logger.info '*** Inari stopped'
|
42
45
|
end
|
43
46
|
end
|
44
|
-
end
|
47
|
+
end
|
data/lib/inari/commands.rb
CHANGED
@@ -1,6 +1,3 @@
|
|
1
|
-
# The response object
|
2
|
-
require 'inari/response'
|
3
|
-
|
4
1
|
# The command drivers
|
5
2
|
require 'inari/commands/http'
|
6
3
|
require 'inari/commands/snmp'
|
@@ -10,6 +7,9 @@ require 'inari/commands/tcp_simple'
|
|
10
7
|
require 'inari/commands/defaults'
|
11
8
|
require 'inari/commands/test'
|
12
9
|
|
10
|
+
# Responses are recorded in this format
|
11
|
+
Response = Struct.new(:code, :body, :logged, :size)
|
12
|
+
|
13
13
|
module Inari
|
14
14
|
# This is the configuration API. These methods can be used from configuration files.
|
15
15
|
#
|
@@ -24,11 +24,11 @@ module Inari
|
|
24
24
|
#
|
25
25
|
class Commands
|
26
26
|
include Singleton
|
27
|
-
|
27
|
+
|
28
28
|
# The taskmanager created for this command instance.
|
29
29
|
attr_reader :last_response
|
30
30
|
attr_accessor :host, :port, :path, :sleep, :timeout
|
31
|
-
|
31
|
+
|
32
32
|
include HTTP
|
33
33
|
include SNMP
|
34
34
|
include SMTP
|
@@ -38,9 +38,9 @@ module Inari
|
|
38
38
|
include TestCommands
|
39
39
|
|
40
40
|
def initialize
|
41
|
-
@host = ''
|
42
41
|
@port = nil
|
43
42
|
@path = ''
|
43
|
+
@host = nil
|
44
44
|
|
45
45
|
@sleep = 60
|
46
46
|
@timeout = 5
|
@@ -49,7 +49,6 @@ module Inari
|
|
49
49
|
@downtimers = {}
|
50
50
|
@last_downtime = {}
|
51
51
|
@responses_limit = 10
|
52
|
-
@last_response = ''
|
53
52
|
|
54
53
|
@localhost = 'localhost'
|
55
54
|
end
|
@@ -62,8 +61,10 @@ module Inari
|
|
62
61
|
def current_host ; @host ; end
|
63
62
|
|
64
63
|
# The status of the last task against the service.
|
65
|
-
def status ;
|
66
|
-
|
64
|
+
def status ; last_response.code; end
|
65
|
+
|
66
|
+
def last_response ; @responses[current_host] and @responses[current_host].last ; end
|
67
|
+
|
67
68
|
# Set the port the service you're monitoring runs on.
|
68
69
|
def port(port) ; @port = port ; end
|
69
70
|
|
@@ -95,27 +96,27 @@ module Inari
|
|
95
96
|
|
96
97
|
# Get the downtime for this task.
|
97
98
|
def down_for
|
98
|
-
if @downtimers[
|
99
|
-
return @last_downtime[
|
99
|
+
if @downtimers[current_host].nil?
|
100
|
+
return @last_downtime[current_host] || 0
|
100
101
|
else
|
101
|
-
return time.to_i - @downtimers[
|
102
|
+
return time.to_i - @downtimers[current_host].to_i
|
102
103
|
end
|
103
104
|
end
|
104
105
|
|
105
106
|
# Called when a task has reported a service offline.
|
106
107
|
def down
|
107
|
-
if @downtimers[
|
108
|
-
@downtimers[
|
109
|
-
@last_downtime[
|
108
|
+
if @downtimers[current_host].nil?
|
109
|
+
@downtimers[current_host] = time
|
110
|
+
@last_downtime[current_host] = 0
|
110
111
|
@on_down.call(self) if @on_down
|
111
112
|
end
|
112
113
|
end
|
113
114
|
|
114
115
|
# Called when a task has seen the service come back.
|
115
116
|
def up
|
116
|
-
if @downtimers[
|
117
|
-
@last_downtime[
|
118
|
-
@downtimers[
|
117
|
+
if @downtimers[current_host]
|
118
|
+
@last_downtime[current_host] = time.to_i - @downtimers[current_host].to_i
|
119
|
+
@downtimers[current_host] = nil
|
119
120
|
@on_up.call(self) if @on_up
|
120
121
|
end
|
121
122
|
end
|
@@ -128,13 +129,11 @@ module Inari
|
|
128
129
|
|
129
130
|
# Store the remote responses in queue.
|
130
131
|
def add_response(name, response, down = false)
|
131
|
-
@last_response = response
|
132
|
-
|
133
132
|
down ? self.down : up
|
134
133
|
|
135
|
-
@responses[
|
136
|
-
@responses[
|
137
|
-
@responses[
|
134
|
+
@responses[current_host] ||= []
|
135
|
+
@responses[current_host].insert 0, {:name => name, :response => response, :time => time, :down => down }
|
136
|
+
@responses[current_host].pop if @responses[current_host].size > @responses_limit
|
138
137
|
end
|
139
138
|
|
140
139
|
def to_seconds(argument)
|
data/lib/inari/commands/http.rb
CHANGED
@@ -3,40 +3,56 @@ require 'net/http'
|
|
3
3
|
module HTTP
|
4
4
|
# HTTP commands
|
5
5
|
def page_size(response = nil)
|
6
|
-
response =
|
6
|
+
response = last_response if response.nil?
|
7
7
|
response.body.size rescue 0
|
8
8
|
end
|
9
9
|
|
10
|
-
def page_content
|
11
|
-
|
12
|
-
|
13
|
-
Timeout::timeout(@timeout) do
|
14
|
-
response = Net::HTTP.get_response(@host, page, @port || 80)
|
15
|
-
add_response(page, response)
|
16
|
-
|
17
|
-
# Return true when a 200 is returned, in case people use get_web_page as a condition
|
18
|
-
response.code == '200'
|
19
|
-
end
|
20
|
-
rescue
|
21
|
-
add_response(page, Response.new(:code => $!), true)
|
22
|
-
false
|
10
|
+
def page_content(response = nil)
|
11
|
+
response = last_response if response.nil?
|
12
|
+
response.body rescue nil
|
23
13
|
end
|
24
14
|
|
25
|
-
|
26
|
-
|
15
|
+
# Fetches a web page and notifies when a timeout occurs or the page
|
16
|
+
# returns an unexpected status.
|
17
|
+
#
|
18
|
+
# Supply a block to use something instead of Net::HTTP.get_response
|
19
|
+
def get_web_page(page, &block)
|
20
|
+
response, down = get_remote_response(page, &block)
|
21
|
+
|
22
|
+
add_response(page, response, down)
|
23
|
+
response.code == '200'
|
24
|
+
end
|
27
25
|
|
26
|
+
# Raises an alert when a page changes.
|
27
|
+
def watch_for_changes_on_page(page, &block)
|
28
28
|
# Fetch a fresh copy of the page and retain the last one
|
29
|
-
|
29
|
+
response, down = get_remote_response(page, &block)
|
30
|
+
|
31
|
+
returning (!set_first_response(response) and changed?(response)) do |state|
|
32
|
+
add_response(page, last_response, state)
|
33
|
+
end
|
30
34
|
end
|
31
35
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
36
|
+
def set_first_response(response)
|
37
|
+
@first_response ||= {}
|
38
|
+
returning @first_response[current_host].nil? do |added|
|
39
|
+
@first_response[current_host] = response unless !added
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def first_response ; @first_response[current_host] ; end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def changed?(response)
|
48
|
+
Digest::MD5::hexdigest(page_content(first_response).to_s) != Digest::MD5::hexdigest(page_content(response).to_s)
|
49
|
+
end
|
50
|
+
|
51
|
+
def get_remote_response(page, &block)
|
52
|
+
Timeout::timeout(@timeout) do
|
53
|
+
[block ? yield : Net::HTTP.get_response(@host, page, @port || 80), false]
|
54
|
+
end
|
55
|
+
rescue
|
56
|
+
[Response.new($!), true]
|
57
|
+
end
|
42
58
|
end
|
data/lib/inari/commands/smtp.rb
CHANGED
@@ -6,11 +6,11 @@ module SMTP
|
|
6
6
|
response = Response.new
|
7
7
|
begin
|
8
8
|
Net::SMTP.start(@host, port=@port, helo=@localhost, user=nil, secret=nil, authtype=nil)
|
9
|
-
add_response('helo', Response.new(
|
9
|
+
add_response('helo', Response.new('Connection accepted'))
|
10
10
|
true
|
11
11
|
rescue
|
12
|
-
add_response('helo', Response.new(
|
12
|
+
add_response('helo', Response.new($!), true)
|
13
13
|
false
|
14
14
|
end
|
15
15
|
end
|
16
|
-
end
|
16
|
+
end
|
@@ -8,11 +8,11 @@ module TCPSimple
|
|
8
8
|
Timeout::timeout(@timeout) do
|
9
9
|
t = TCPSocket.new(@host, @port)
|
10
10
|
state = true
|
11
|
-
add_response(name, Response.new(
|
11
|
+
add_response(name, Response.new('Up'))
|
12
12
|
end
|
13
13
|
rescue
|
14
14
|
Inari::logger.error "TCP error: #{$!} for host: #{@host}, port: #{@port}"
|
15
|
-
add_response(name, Response.new(
|
15
|
+
add_response(name, Response.new($!), true)
|
16
16
|
ensure
|
17
17
|
t.close if defined? t
|
18
18
|
end
|
@@ -21,4 +21,4 @@ module TCPSimple
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def down? ; !up? ; end
|
24
|
-
end
|
24
|
+
end
|
data/lib/inari/commands/test.rb
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
module TestCommands
|
2
2
|
def run_test(probability)
|
3
3
|
if rand(100) > probability
|
4
|
-
add_response('Test', Response.new(
|
4
|
+
add_response('Test', Response.new('200'))
|
5
5
|
else
|
6
|
-
add_response('Test', Response.new(
|
6
|
+
add_response('Test', Response.new('404'), true)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
end
|
data/lib/inari/misc.rb
ADDED
data/lib/inari/version.rb
CHANGED
data/test/abstract_test.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'test/abstract_test'
|
2
|
+
|
3
|
+
class CommandsTest::HTTP < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@commands = Inari::Commands.instance
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_get_web_page
|
9
|
+
@commands.host = InariTest::default_host
|
10
|
+
assert @commands.get_web_page('/')
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_watch_for_changes_on_page
|
14
|
+
@commands.host = 'test_watch_for_changes_on_page'
|
15
|
+
assert !@commands.watch_for_changes_on_page('/') { Response.new('200', 'Test') }
|
16
|
+
assert !@commands.watch_for_changes_on_page('/') { Response.new('200', 'Test') }
|
17
|
+
assert !@commands.watch_for_changes_on_page('/') { Response.new('200', 'Test') }
|
18
|
+
|
19
|
+
# This should be considered different
|
20
|
+
assert @commands.watch_for_changes_on_page('/') { Response.new('200', 'Page changed') }
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'test/abstract_test'
|
2
|
+
|
3
|
+
class CommandsTest::TCPSimple < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@commands = Inari::Commands.instance
|
6
|
+
end
|
7
|
+
|
8
|
+
def test_up_down
|
9
|
+
@commands.host = InariTest::default_host
|
10
|
+
@commands.port = 80
|
11
|
+
assert @commands.up?
|
12
|
+
end
|
13
|
+
end
|
data/test/configuration_test.rb
CHANGED
@@ -5,11 +5,6 @@ class ConfigurationTest < Test::Unit::TestCase
|
|
5
5
|
@configuration = Inari::Configuration.instance
|
6
6
|
end
|
7
7
|
|
8
|
-
# Check if any of the load paths make sense
|
9
|
-
def test_default_load_path_exists
|
10
|
-
assert File.directory?(@configuration.default_load_path)
|
11
|
-
end
|
12
|
-
|
13
8
|
def test_loads
|
14
9
|
@configuration.load_paths.push 'test/fixtures/'
|
15
10
|
assert_nil @configuration.load('test_config.rb')
|
metadata
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.
|
2
|
+
rubygems_version: 0.8.10
|
3
3
|
specification_version: 1
|
4
4
|
name: inari
|
5
5
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 0.1.
|
7
|
-
date: 2007-02-06
|
8
|
-
summary: Inari is a
|
6
|
+
version: 0.1.1
|
7
|
+
date: 2007-02-06
|
8
|
+
summary: Inari is a system monitoring program.
|
9
9
|
require_paths:
|
10
10
|
- lib
|
11
11
|
email: alex@helicoid.net
|
@@ -23,52 +23,39 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
|
|
23
23
|
version: 0.0.0
|
24
24
|
version:
|
25
25
|
platform: ruby
|
26
|
-
signing_key:
|
27
|
-
cert_chain:
|
28
|
-
post_install_message: |+
|
29
|
-
|
30
|
-
Welcome to Inari
|
31
|
-
================
|
32
|
-
|
33
|
-
Inari is a small and extenable system monitor, intended for us with
|
34
|
-
web applications. To start using it, tailor /usr/local/etc/inari.conf
|
35
|
-
to your requirements.
|
36
|
-
|
37
|
-
Take a look at README for help on writing configuration files.
|
38
|
-
|
39
|
-
http://inari.rubyforge.org
|
40
|
-
|
41
26
|
authors: []
|
42
27
|
|
43
28
|
files:
|
44
29
|
- lib/inari.rb
|
45
|
-
- lib/inari/
|
30
|
+
- lib/inari/task_process.rb
|
46
31
|
- lib/inari/configuration.rb
|
32
|
+
- lib/inari/commands.rb
|
47
33
|
- lib/inari/daemon.rb
|
48
|
-
- lib/inari/response.rb
|
49
|
-
- lib/inari/task_manager.rb
|
50
|
-
- lib/inari/task_process.rb
|
51
34
|
- lib/inari/version.rb
|
35
|
+
- lib/inari/task_manager.rb
|
36
|
+
- lib/inari/misc.rb
|
52
37
|
- lib/inari/commands/defaults.rb
|
53
|
-
- lib/inari/commands/http.rb
|
54
|
-
- lib/inari/commands/reporting.rb
|
55
|
-
- lib/inari/commands/smtp.rb
|
56
38
|
- lib/inari/commands/snmp.rb
|
57
|
-
- lib/inari/commands/
|
39
|
+
- lib/inari/commands/http.rb
|
58
40
|
- lib/inari/commands/test.rb
|
41
|
+
- lib/inari/commands/tcp_simple.rb
|
42
|
+
- lib/inari/commands/smtp.rb
|
43
|
+
- lib/inari/commands/reporting.rb
|
59
44
|
- bin/inari
|
60
|
-
- CHANGES
|
61
|
-
- InstalledFiles
|
62
45
|
- LICENSE
|
63
46
|
- Rakefile
|
64
|
-
-
|
47
|
+
- CHANGES
|
65
48
|
- THANKS
|
66
|
-
-
|
67
|
-
- test/commands_test.rb
|
68
|
-
- test/configuration_test.rb
|
49
|
+
- README
|
69
50
|
- test/fixtures
|
70
51
|
- test/task_manager_test.rb
|
52
|
+
- test/commands_test.rb
|
53
|
+
- test/abstract_test.rb
|
54
|
+
- test/commands
|
55
|
+
- test/configuration_test.rb
|
71
56
|
- test/fixtures/test_config.rb
|
57
|
+
- test/commands/http_test.rb
|
58
|
+
- test/commands/tcp_simple_test.rb
|
72
59
|
test_files: []
|
73
60
|
|
74
61
|
rdoc_options: []
|
data/InstalledFiles
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
/usr/local/lib/ruby/site_ruby/1.8/inari.rb
|