inari 0.1.0 → 0.1.1
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/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
|