RSS
 

[DEPRECATED]Ragios: Ruby based System and Network Monitoring Tool

31 Aug

This post has been deprecated. See the new version of Ragios here: http://github.com/obi-a/Ragios

While reading the book “Nagios: system and Network Monitoring” by Wolfgang Barth, I thought it will be a good idea to write a Ruby based Object Oriented System and Network Monitoring tool similar to Nagios.

So I started writing such a tool. Since it was inspired by Nagios, I will call it Ragios (Ruby Agios) aka Saint Ruby (St. Ruby) since Agios is Saint in Greek.

This is all just for fun and educational purposes.

Ragios could be used to monitor any type of system including servers, workstations, switches, routers, system services and applications, locally or over a network. The system admin can define the tests he wants to run on the system or re-use tests written by other developers. The tests run periodically on the system. When a test fails the admin receives an email or SMS alert from Ragios. Everything is written in ruby, the configuration settings are all in ruby syntax and Ragios itself is a ruby script.

Ragios is Object Oriented so everything is an object. The Base object is the System_monitor defined by the System_monitor class. This class defines the behavior of all system monitors.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class System_monitor
#base class that defines the behavior of all system monitors
 
   attr_reader :test_description   # a short description of the test performed by this system monitor
   attr_reader :hostname #hostname of the system being monitored
   attr_reader :address   #ip address of the system being monitored
   attr_reader :contact    #email address of admin to contact when a test fails
   attr_reader :test_result #results of a test
 
   def initialize
   end
 
   def test_command
   #defines the tests to run on a system
   end
 
   def failed
   #defines the action to take when a test fails
   #- May send email or SMS to the admin under contact
   #- May also take action to fix the issue like restart a process/service
   end
end

The method test_command defines the test that will be performed on the system periodically by the system monitor. If the test is successful test_command will return TRUE, if it fails the method will return FALSE. The test_command method can run any type of test, it just needs to return values TRUE for a PASSED test and FALSE for a FAILED test.

The failed method defines the actions to be performed when a test fails. These actions may include sending email or SMS to alert the system admin about a problem. It may also include actions to fix the problem.

After every test any results from the test like an error message for a failed test is saved in the test_result variable. This should be implemented in the test_command method.

Ragios monitors 2 types of systems, Hosts and Services. Hosts are devices that run on a network like computers, routers, switches and servers. Services are applications and processes like a web server, database, web apps, and system processes.

Hosts and Services both extend the System_monitor class. They both inherit all the characteristics of a System_monitor.

The Host class

1
2
3
4
5
6
7
class Host < System_monitor
#defines how computers,servers,network devices will be monitored
 
    def initialize
     super
    end
end

The Service class

1
2
3
4
5
6
class Service < System_monitor
#defines how services, processes and applications will be monitored
    def initialize
     super
    end
end

Now we have the basic framework in place. With Ragios the system admin implements his own system monitors or reuses system monitors already implemented by other developers.

Lets implement a simple system monitor that monitors a webpage and alerts the owner when the site is down. This is simply done by sending http requests to the site’s home page and alerting the site owner if it fails to get a HTTP 200 OK status response from the server.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Test_webpage_for_http_200 < Service
#monitors a webpage to check if the site is loading
#PASSED if it gets a HTTP 200 Response status code from the website
 
   attr_reader :test_url
 
   def initialize
        super
   end
 
   def test_command
     #returns true when http request to test_url returns a 200 OK Response
       response = Net::HTTP.get_response(URI.parse(test_url))
        @test_result = response.code
       if response.code != "200"
            return FALSE
       else
	    return TRUE
       end
   end
 
   def failed
         #send email notification to site owner
         #not yet implemented
   end
end

Test_webpage_for_http_200 extends the Service class because it is testing http which is a service. it also has all the characteristics of the base class System_monitor. We just needed to override the test_command method to implement our specific test.

def test_command
     #returns true when http request to test_url returns a 200 OK Response
       response = Net::HTTP.get_response(URI.parse(test_url))
        @test_result = response.code
       if response.code != "200"
            return FALSE
       else
	    return TRUE
       end
   end

test_command sends http requests to the test_url and returns TRUE when it gets a 200 OK Response, returns FALSE when it gets a different response code. The response code is saved in @test_result as the result of this test. This value gives a system admin insight on what has gone wrong.

The failed method should define the actions to take when a test fails. In this case it sends an email to notify the site owner. The email feature is not yet implemented.

Test_webpage_for_http_200 is a generic system monitor, it doesn’t test any particular site, we still need to write system monitors that test specific sites for us. These monitors will be subclasses of Test_webpage_for_http_200. Lets write some now

1
2
3
4
5
6
7
8
class Test_my_blog < Test_webpage_for_http_200
#monitors my blog, to check if the blog's home page is loading
   def initialize
      @test_description  = "Testing My Blog"
      @test_url = "http://obi-akubue.homeunix.org/"
      super
   end
end

Running

Test_my_blog.new.test_command

will send a http request to my blog’s home page http://obi-akubue.homeunix.org/ and return TRUE if it gets a 200 Ok Response and FALSE if it gets anything else.

Lets write another test, this one monitors my website http://whisperservers.com/blog.

1
2
3
4
5
6
7
class Test_my_site < Test_webpage_for_http_200
   def initialize
      @test_description  = "Testing my website site"
      @test_url = "http://www.whisperservers.com/blog/"
      super
   end
end

Running

Test_my_site.new.test_command

will send a http request to my site’s home page http://www.whisperservers.com/blog/ and return TRUE if it gets a 200 Ok Response and FALSE if it gets anything else.

Ragios will run all our tests and alert us when a test fails.

1
2
3
4
5
6
7
8
9
10
11
jobs = [Test_my_blog.new, Test_my_site.new]
 
jobs.each do |job|
 puts job.test_description
 if job.test_command
        puts "   [PASSED]"
     else
         puts "   [FAILED]"
         job.failed
     end
end

We just need to add our tests to the jobs Array.

jobs = [Test_my_blog.new, Test_my_site.new]

Ragios will alert us when a test fails by calling the failed method.

Complete source code for Ragios

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#!/usr/bin/ruby
#:Title   :Ragios (aka St. Ruby)
#:Date    :8/26/2010
#:Author  :Obi Akubue
#:Version :0.1
#description: This is the framework for a Ruby Based System and Network Monitoring Tool
 
 
require 'net/http'
 
class System_monitor
#base class that defines the behavior of all system monitors
 
   attr_reader :test_description   # a short description of the test performed by this system monitor
   attr_reader :hostname #hostname of the system being monitored
   attr_reader :address   #ip address of the system being monitored
   attr_reader :contact    #email address of admin to contact when a test fails
   attr_reader :test_result #results of a test
 
   def initialize
   end
 
   def test_command
   #defines the tests to run on a system
   end
 
   def failed
   #defines the action to take when a test fails
   #- May send email or SMS to the admin under contact
   #- May also take action to fix the issue like restart a process/service
   end
end
 
 
class Host < System_monitor
#defines how computers,servers,network devices will be monitored
 
    def initialize
     super
    end
 
end
 
class Service < System_monitor
#defines how services will be monitored
 
    def initialize
     super
    end
end
 
class Test_webpage_for_http_200 < Service
#monitors a webpage to check if the site is loading
#PASSED if it gets a HTTP 200 Response status code from the website
 
   attr_reader :test_url
 
   def initialize
        @contact = "Obi@whisperservers.com"
        super
   end
 
   def test_command
     #returns true when http request to test_url returns a 200 OK Response
       response = Net::HTTP.get_response(URI.parse(test_url))
        @test_result = response.code
       if response.code != "200"
            return FALSE
       else
	    return TRUE
       end
   end
 
   def failed
         #send email notification to site owner @contact
         #not yet implemented
   end
end
 
class Test_my_site < Test_webpage_for_http_200
   def initialize
      @test_description  = "Testing my website site"
      @test_url = "http://www.whisperservers.com/blog/"
      super
   end
end
 
class Test_my_blog < Test_webpage_for_http_200
#tests my blog, to check if the blog is loading
 
   def initialize
      @test_description  = "Testing My Blog"
      @test_url = "http://obi-akubue.homeunix.org/"
      super
   end
end
 
 
jobs = [ Test_my_site.new, Test_my_blog.new]
 
jobs.each do |job|
 puts job.test_description
 if job.test_command
        puts "   [PASSED]"
     else
        puts "   [FAILED]"
        job.failed
     end
end

In its current form Ragios is just a simple ruby script, the system admin has to edit this script to add tests and configuration settings, or reuse tests already available.

Any setting that applies to more than one test should be added to the initialize method of the super class of those tests. In the example above we added

@contact = "Obi@whisperservers.com"

to the initialize method of Test_webpage_for_http_200. This allows our tests (Test_my_blog and Test_my_site) to use the same contact = "obi@whisperservers.com" by simply calling the super method in their constructor.

Ragios is still incomplete, for now we may set it to run hourly as a cron job or in the future we may make it into a daemon. This is just the basic framework to extend and play with.

[UPDATE 10-1-2010] View the complete Ragios source with latest revisions
http://github.com/obi-a/Ragios.

 

Tags: , , , , ,

 
Premium Wordpress Plugin