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 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
- Spec = Gem::Specification.new do |s|
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 ruby system monitoring program.'
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(Spec) do |p|
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
@@ -5,10 +5,13 @@ require 'socket'
5
5
  require 'net/smtp'
6
6
  require 'timeout'
7
7
  require 'singleton'
8
- require 'logger'
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
@@ -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 ; @last_response.code; end
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[@host].nil?
99
- return @last_downtime[@host] || 0
99
+ if @downtimers[current_host].nil?
100
+ return @last_downtime[current_host] || 0
100
101
  else
101
- return time.to_i - @downtimers[@host].to_i
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[@host].nil?
108
- @downtimers[@host] = time
109
- @last_downtime[@host] = 0
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[@host]
117
- @last_downtime[@host] = time.to_i - @downtimers[@host].to_i
118
- @downtimers[@host] = nil
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[@host] ||= []
136
- @responses[@host].insert 0, {:name => name, :response => response, :time => time, :down => down }
137
- @responses[@host].pop if @responses[@host].size > @responses_limit
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)
@@ -3,40 +3,56 @@ require 'net/http'
3
3
  module HTTP
4
4
  # HTTP commands
5
5
  def page_size(response = nil)
6
- response = @last_response if response.nil?
6
+ response = last_response if response.nil?
7
7
  response.body.size rescue 0
8
8
  end
9
9
 
10
- def page_content; @last_response.body; end
11
-
12
- def get_web_page(page)
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
- def unexpected_page_change
26
- @first_response = @last_response if @first_response.nil? and @last_response
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
- page_size(@first_response) == page_size
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
- #def when_http_status_is(status, invert = false, &block)
33
- # response = Net::HTTP.get_response(@host, @path)
34
- # if status.to_i == response.code.to_i and not invert
35
- # instance_eval(&block) if block
36
- # end
37
- #end
38
- #
39
- #def when_http_status_is_not(status, &block)
40
- # when_http_status_is(status, true, &block)
41
- #end
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
@@ -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(:code => 'Connection accepted'))
9
+ add_response('helo', Response.new('Connection accepted'))
10
10
  true
11
11
  rescue
12
- add_response('helo', Response.new(:code => $!), true)
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(:code => 'Up'))
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(:code => $!), true)
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
@@ -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(:code => '200'))
4
+ add_response('Test', Response.new('200'))
5
5
  else
6
- add_response('Test', Response.new(:code => '404'), true)
6
+ add_response('Test', Response.new('404'), true)
7
7
  end
8
8
  end
9
9
  end
@@ -0,0 +1,6 @@
1
+ class Object
2
+ def returning(value)
3
+ yield(value)
4
+ value
5
+ end
6
+ end
@@ -2,8 +2,8 @@
2
2
  module Inari
3
3
  APP_NAME = 'Inari'
4
4
 
5
- INARI_VERSION = '0.1.0'
5
+ INARI_VERSION = '0.1.1'
6
6
  INARI_RELEASE_DATE = '2007/02/06'
7
7
 
8
8
  UPSTREAM_URL = 'http://inari.rubyforge.org'
9
- end
9
+ end
@@ -2,3 +2,7 @@
2
2
 
3
3
  require 'test/unit'
4
4
  require 'inari'
5
+
6
+ module InariTest
7
+ def self.default_host ; 'alexyoung.org' ; end
8
+ end
@@ -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
@@ -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.9.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.0
7
- date: 2007-02-06 00:00:00 +00:00
8
- summary: Inari is a ruby system monitoring program.
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/commands.rb
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/tcp_simple.rb
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
- - README
47
+ - CHANGES
65
48
  - THANKS
66
- - test/abstract_test.rb
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: []
@@ -1 +0,0 @@
1
- /usr/local/lib/ruby/site_ruby/1.8/inari.rb
@@ -1,9 +0,0 @@
1
- class Response
2
- attr_accessor :code
3
- attr_accessor :size
4
- attr_accessor :logged
5
-
6
- def initialize(*args)
7
- args.each { |field, value| self.send(field, value) } if args.is_a? Hash
8
- end
9
- end