monittr 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.markdown +75 -0
- data/Rakefile +2 -0
- data/lib/monittr.rb +85 -0
- data/lib/monittr/sinatra/monittr.rb +48 -0
- data/lib/monittr/sinatra/style.css +128 -0
- data/lib/monittr/sinatra/template.erb +96 -0
- data/lib/monittr/version.rb +3 -0
- data/test/fixtures/status.xml +1 -0
- data/test/monittr_test.rb +69 -0
- data/test/sinatra_helper_test.rb +32 -0
- data/test/test_helper.rb +30 -0
- metadata +161 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Karel Minarik
|
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
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# Monittr : A Web Interface for Monit Statistics #
|
2
|
+
|
3
|
+
_Monittr_ provides a _Ruby_ interface for displaying [_Monit_](http://mmonit.com/) statistics in [_Sinatra_](http://www.sinatrarb.com/) based web applications.
|
4
|
+
|
5
|
+
It loads information from the [web server embedded in _Monit_](http://mmonit.com/monit/documentation/monit.html#monit_httpd) and makes it accessible as Ruby objects.
|
6
|
+
|
7
|
+
It also displays the information in HTML with the provided helpers. You can use the default template, or provide your own. The default template is located in `lib/monittr/sinatra/template.erb`.
|
8
|
+
|
9
|
+
![Screenshot: Monittr, a web interface for Monit statistics](https://github.com/karmi/monittr/raw/master/screenshot.png)
|
10
|
+
|
11
|
+
## Installation ##
|
12
|
+
|
13
|
+
$ gem install monittr
|
14
|
+
|
15
|
+
|
16
|
+
## Usage ##
|
17
|
+
|
18
|
+
You can try the interface in a IRB console:
|
19
|
+
|
20
|
+
$ irb -Ilib -rubygems -rmonittr
|
21
|
+
|
22
|
+
You have to pass one or more URLs to a running Monit web server.
|
23
|
+
|
24
|
+
In case you don't have a running Monit handy, fake its output:
|
25
|
+
|
26
|
+
require 'fakeweb'
|
27
|
+
FakeWeb.register_uri(:get, 'http://localhost:2812/_status?format=xml', :body => File.read('test/fixtures/status.xml') ); nil
|
28
|
+
|
29
|
+
Now, retrieve information from the cluster:
|
30
|
+
|
31
|
+
cluster = Monittr::Cluster.new 'http://localhost:2812/_status?format=xml'
|
32
|
+
cluster.servers.size
|
33
|
+
|
34
|
+
server = cluster.servers.first
|
35
|
+
server.system.status
|
36
|
+
server.system.load
|
37
|
+
|
38
|
+
server.filesystems.first.name
|
39
|
+
server.filesystems.first.percent
|
40
|
+
|
41
|
+
server.processes.first.name
|
42
|
+
server.processes.first.cpu
|
43
|
+
server.processes.first.memory
|
44
|
+
|
45
|
+
...
|
46
|
+
|
47
|
+
You can also check out the HTML output by running the example application:
|
48
|
+
|
49
|
+
$ ruby examples/application.rb
|
50
|
+
$ open http://localhost:4567/
|
51
|
+
|
52
|
+
You should see the information about two faked Monit instances in your browser.
|
53
|
+
|
54
|
+
Provide the URLs to _Monit_ instances by setting the appropriate option:
|
55
|
+
|
56
|
+
set :monit_urls, ['http://localhost:2812/_status?format=xml', 'http://localhost:2812/_status?format=xml']
|
57
|
+
|
58
|
+
|
59
|
+
## Customization ##
|
60
|
+
|
61
|
+
It's easy to customize the HTML output by setting the appropriate options in your _Sinatra_ application.
|
62
|
+
|
63
|
+
|
64
|
+
set :template, Proc.new { File.join(root, 'template.erb') }
|
65
|
+
set :stylesheet, '/path/to/my/stylesheet'
|
66
|
+
|
67
|
+
Please see the example application for more.
|
68
|
+
|
69
|
+
## Other Information ##
|
70
|
+
|
71
|
+
See the [_monit_](https://github.com/k33l0r/monit) gem for another Ruby interface to _Monit_.
|
72
|
+
|
73
|
+
-----
|
74
|
+
|
75
|
+
[Karel Minarik](http://karmi.cz)
|
data/Rakefile
ADDED
data/lib/monittr.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
require 'rest-client'
|
3
|
+
require 'ostruct'
|
4
|
+
|
5
|
+
module Monittr
|
6
|
+
|
7
|
+
class Cluster
|
8
|
+
|
9
|
+
attr_reader :servers
|
10
|
+
|
11
|
+
def initialize(urls=[])
|
12
|
+
@servers = urls.map { |url| Server.fetch(url) }
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
# Represents one monitored system instance
|
19
|
+
#
|
20
|
+
class Server
|
21
|
+
|
22
|
+
attr_reader :xml, :system, :filesystems, :processes
|
23
|
+
|
24
|
+
def initialize(xml)
|
25
|
+
@xml = Nokogiri::XML(xml)
|
26
|
+
@system = Services::System.new(@xml.xpath("//service[@type=5]").first)
|
27
|
+
@filesystems = @xml.xpath("//service[@type=0]").map { |xml| Services::Filesystem.new(xml) }
|
28
|
+
@processes = @xml.xpath("//service[@type=3]").map { |xml| Services::Process.new(xml) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.fetch(url=nil)
|
32
|
+
url = url || ENV['MONIT_URL'] || 'http://admin:monit@localhost:2812/_status?format=xml'
|
33
|
+
self.new( RestClient.get(url) )
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
module Services
|
40
|
+
class Base < OpenStruct
|
41
|
+
TYPES = { 0 => "Filesystem", 1 => "Directory", 2 => "File", 3 => "Daemon", 4 => "Connection", 5 => "System" }
|
42
|
+
end
|
43
|
+
|
44
|
+
class System < Base
|
45
|
+
def initialize(xml)
|
46
|
+
super( { :name => xml.xpath('name').first.content,
|
47
|
+
:status => xml.xpath('status').first.content.to_i,
|
48
|
+
:monitored => xml.xpath('monitor').first.content.to_i,
|
49
|
+
:load => (xml.xpath('system/load/avg01').first.content.to_f rescue nil),
|
50
|
+
:cpu => (xml.xpath('system/cpu/user').first.content.to_f rescue nil),
|
51
|
+
:memory => (xml.xpath('system/memory/percent').first.content.to_f rescue nil),
|
52
|
+
:uptime => (xml.xpath('//server/uptime').first.content.to_i rescue nil)
|
53
|
+
} )
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
class Filesystem < Base
|
58
|
+
def initialize(xml)
|
59
|
+
super( { :name => xml.xpath('name').first.content,
|
60
|
+
:status => xml.xpath('status').first.content.to_i.to_i,
|
61
|
+
:monitored => xml.xpath('monitor').first.content.to_i,
|
62
|
+
:percent => xml.xpath('block/percent').first.content.to_f,
|
63
|
+
:usage => xml.xpath('block/usage').first.content,
|
64
|
+
:total => xml.xpath('block/total').first.content
|
65
|
+
} )
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
class Process < Base
|
70
|
+
def initialize(xml)
|
71
|
+
super( { :name => xml.xpath('name').first.content,
|
72
|
+
:status => xml.xpath('status').first.content.to_i,
|
73
|
+
:monitored => xml.xpath('monitor').first.content.to_i,
|
74
|
+
:pid => (xml.xpath('pid').first.content.to_i rescue nil),
|
75
|
+
:uptime => (xml.xpath('uptime').first.content.to_i rescue nil),
|
76
|
+
:memory => (xml.xpath('memory/percent').first.content.to_f rescue nil),
|
77
|
+
:cpu => (xml.xpath('cpu/percent').first.content.to_f rescue nil)
|
78
|
+
|
79
|
+
} )
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'erb'
|
3
|
+
|
4
|
+
module Sinatra
|
5
|
+
module MonittrHTML
|
6
|
+
|
7
|
+
module Helpers
|
8
|
+
|
9
|
+
def monittr
|
10
|
+
@monittr ||= HTML.new(self)
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
|
15
|
+
class HTML
|
16
|
+
|
17
|
+
attr_reader :app
|
18
|
+
|
19
|
+
def initialize(app)
|
20
|
+
@app = app
|
21
|
+
end
|
22
|
+
|
23
|
+
def cluster
|
24
|
+
Monittr::Cluster.new(app.settings.monit_urls)
|
25
|
+
end
|
26
|
+
|
27
|
+
def html
|
28
|
+
ERB.new( File.read( app.settings.template ) ).result(binding)
|
29
|
+
end
|
30
|
+
|
31
|
+
def stylesheet
|
32
|
+
app.settings.stylesheet ? File.read( app.settings.stylesheet ) : ''
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.registered(app)
|
38
|
+
app.helpers MonittrHTML::Helpers
|
39
|
+
|
40
|
+
app.set :monit_urls, ['http://admin:monit@localhost:2812/_status?format=xml']
|
41
|
+
app.set :template, File.expand_path('../template.erb', __FILE__)
|
42
|
+
app.set :stylesheet, File.expand_path('../style.css', __FILE__)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
register MonittrHTML
|
48
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
#monittr
|
2
|
+
{ font-family: sans-serif; }
|
3
|
+
|
4
|
+
#monittr .clear
|
5
|
+
{ clear:both; display:block; overflow:hidden; visibility:hidden; width:0; height:0 }
|
6
|
+
|
7
|
+
#monittr .rounded
|
8
|
+
{ -moz-border-radius: 0.5em;
|
9
|
+
-webkit-border-radius: 0.5em;
|
10
|
+
border-radius: 0.5em }
|
11
|
+
|
12
|
+
#monittr #toggle
|
13
|
+
{ font-size: 80%;
|
14
|
+
text-decoration: underline;
|
15
|
+
text-align: right; }
|
16
|
+
|
17
|
+
#monittr .dot
|
18
|
+
{ text-indent: -9000px;
|
19
|
+
background-color: #ccc;
|
20
|
+
width: 6px; height: 6px;
|
21
|
+
margin: 0.25em 0.25em 0 0;
|
22
|
+
display: block;
|
23
|
+
float: left;
|
24
|
+
-moz-border-radius: 6px;
|
25
|
+
-webkit-border-radius: 6px;
|
26
|
+
border-radius: 6px; }
|
27
|
+
#monittr .dot.running
|
28
|
+
{ background-color: green; }
|
29
|
+
#monittr .dot.failure
|
30
|
+
{ background-color: red; }
|
31
|
+
#monittr .dot.warning
|
32
|
+
{ background-color: orange; }
|
33
|
+
|
34
|
+
#monittr .server
|
35
|
+
{ color: #222;
|
36
|
+
background-color: #F8F8F8;
|
37
|
+
margin: 0.2em 0 0 0;
|
38
|
+
border: 1px solid #ccc; }
|
39
|
+
|
40
|
+
#monittr .server h2
|
41
|
+
{ font-size: 14px;
|
42
|
+
font-weight: normal;
|
43
|
+
background-color: #ccc;
|
44
|
+
padding: 0.5em 0.5em 0.4em 0.5em;
|
45
|
+
margin: 0; }
|
46
|
+
#monittr .server.running h2
|
47
|
+
{ background-color: #66E98A; }
|
48
|
+
#monittr .server.failure h2
|
49
|
+
{ color: #fff;
|
50
|
+
background-color: #CC033E; }
|
51
|
+
#monittr .server.failure h2 *
|
52
|
+
{ color: #fff !important; }
|
53
|
+
|
54
|
+
#monittr .server.expanded h2
|
55
|
+
{ -moz-border-radius-bottomleft: 0;
|
56
|
+
-moz-border-radius-bottomright: 0;
|
57
|
+
-webkit-border-radius-bottomleft: 0;
|
58
|
+
-webkit-border-radius-bottomright: 0
|
59
|
+
border-radius-bottomleft: 0;
|
60
|
+
border-radius-bottomright: 0; }
|
61
|
+
|
62
|
+
#monittr .server h2 small
|
63
|
+
{ font-size: 75%;
|
64
|
+
float: right; }
|
65
|
+
|
66
|
+
#monittr .server .info
|
67
|
+
{ margin-right: 1em; }
|
68
|
+
|
69
|
+
#monittr .server small .info .label
|
70
|
+
{ font-size: 90%;
|
71
|
+
text-transform: uppercase; }
|
72
|
+
#monittr .server small .info .label
|
73
|
+
{ opacity: 0.6; }
|
74
|
+
|
75
|
+
#monittr .server .content
|
76
|
+
{ padding: 0.5em 0 0.5em 0; }
|
77
|
+
|
78
|
+
#monittr .server .segment
|
79
|
+
{ margin-bottom: 1em;
|
80
|
+
padding: 0.25em 0.5em 0.25em 0.5em;
|
81
|
+
float: none;
|
82
|
+
clear: both;
|
83
|
+
border-bottom: 1px solid #E5E5E5; }
|
84
|
+
|
85
|
+
#monittr .server .segment h3
|
86
|
+
{ color: #999;
|
87
|
+
font-size: 80%;
|
88
|
+
font-weight: normal;
|
89
|
+
text-transform: uppercase;
|
90
|
+
margin: 0;
|
91
|
+
padding: 0;
|
92
|
+
float: left;
|
93
|
+
width: 10em; }
|
94
|
+
|
95
|
+
#monittr .server .segment ul
|
96
|
+
{ font-size: 90%;
|
97
|
+
float: left;
|
98
|
+
margin: -0.3em 0 0 0;
|
99
|
+
padding: 0; }
|
100
|
+
|
101
|
+
#monittr .server .segment ul li
|
102
|
+
{ list-style-type: none;
|
103
|
+
padding: 0.25em;
|
104
|
+
border-bottom: 1px solid #ccc; }
|
105
|
+
#monittr .server .segment ul li:last-child
|
106
|
+
{ border-bottom: none; }
|
107
|
+
#monittr .server .segment ul li strong
|
108
|
+
{ width: 20em;
|
109
|
+
display: block;
|
110
|
+
float: left; }
|
111
|
+
|
112
|
+
#monittr .server .segment strong .label
|
113
|
+
{ color: #fff;
|
114
|
+
background-color: #ccc;
|
115
|
+
font-size: 75%;
|
116
|
+
text-transform: uppercase;
|
117
|
+
font-weight: normal;
|
118
|
+
padding: 0.25em 0.5em 0.15em 0.5em;
|
119
|
+
-moz-border-radius: 0.5em;
|
120
|
+
-webkit-border-radius: 0.5em;
|
121
|
+
border-radius: 0.5em; }
|
122
|
+
|
123
|
+
#monittr .server .segment strong .label.running
|
124
|
+
{ background-color: green; }
|
125
|
+
#monittr .server .segment strong .label.warning
|
126
|
+
{ background-color: orange; }
|
127
|
+
#monittr .server .segment strong .label.failure
|
128
|
+
{ background-color: red; }
|
@@ -0,0 +1,96 @@
|
|
1
|
+
<style><%= stylesheet %></style>
|
2
|
+
|
3
|
+
<div id="monittr">
|
4
|
+
|
5
|
+
<p id="toggle">+ Expand all</p>
|
6
|
+
|
7
|
+
<% cluster.servers.each do |server| %>
|
8
|
+
|
9
|
+
<div class="server rounded">
|
10
|
+
<h2 class="rounded">
|
11
|
+
<strong>
|
12
|
+
<span class="dot status <%= server.system.status == 0 ? 'running' : 'failure' %>">·</span>
|
13
|
+
<span class="dot monitored <%= server.system.monitored == 1 ? 'running' : 'failure' %>">·</span>
|
14
|
+
<%= server.system.name %>
|
15
|
+
</strong>
|
16
|
+
|
17
|
+
<small>
|
18
|
+
<span class="info"><span class="label">load: </span><%= server.system.load || 'N/A' %></span>
|
19
|
+
<span class="info"><span class="label">cpu: </span><%= server.system.cpu || 'N/A' %></span>
|
20
|
+
<span class="info"><span class="label">memory: </span><%= server.system.memory || 'N/A' %></span>
|
21
|
+
<span class="info"><span class="label">uptime: </span><%= server.system.uptime || 'N/A' %></span>
|
22
|
+
</small>
|
23
|
+
</h2>
|
24
|
+
|
25
|
+
<div class="content">
|
26
|
+
<div class="segment filesystem">
|
27
|
+
<h3>Filesystem</h3>
|
28
|
+
<ul class="clearfix">
|
29
|
+
<% server.filesystems.each do |fs| %>
|
30
|
+
<li>
|
31
|
+
<strong title="(<%= fs.usage %> of <%= fs.total %>)">
|
32
|
+
<span class="dot status <%= fs.status == 0 ? 'running' : 'failure' %>">·</span>
|
33
|
+
<span class="dot monitored <%= fs.monitored == 1 ? 'running' : 'failure' %>">·</span>
|
34
|
+
<%= fs.name %>
|
35
|
+
</strong>
|
36
|
+
<%= fs.percent %>%
|
37
|
+
</li>
|
38
|
+
<% end %>
|
39
|
+
</ul>
|
40
|
+
<div class="clear"></div>
|
41
|
+
</div><!-- /filesystem -->
|
42
|
+
|
43
|
+
<div class="segment processes">
|
44
|
+
<h3>Processes</h3>
|
45
|
+
<ul>
|
46
|
+
<% server.processes.each do |process| %>
|
47
|
+
<li>
|
48
|
+
<strong>
|
49
|
+
<span class="dot status <%= process.status == 0 ? 'running' : 'failure' %>">·</span>
|
50
|
+
<span class="dot monitored <%= process.monitored == 1 ? 'running' : 'failure' %>">·</span>
|
51
|
+
<%= process.name %>
|
52
|
+
<% unless process.monitored == 1 %><span class="label warning">NOT MONITORED</span><% end %>
|
53
|
+
</strong>
|
54
|
+
|
55
|
+
<small>
|
56
|
+
<span class="info"><span class="label">cpu: </span><%= process.cpu || 'N/A' %></span>
|
57
|
+
<span class="info"><span class="label">memory: </span><%= process.memory || 'N/A' %></span>
|
58
|
+
<span class="info"><span class="label">uptime: </span><%= process.uptime || 'N/A' %></span>
|
59
|
+
</small>
|
60
|
+
</li>
|
61
|
+
<% end %>
|
62
|
+
</ul>
|
63
|
+
<div class="clear"></div>
|
64
|
+
</div><!-- /filesystem -->
|
65
|
+
|
66
|
+
</div><!-- /content -->
|
67
|
+
|
68
|
+
<div class="clear"></div>
|
69
|
+
</div><!-- /server -->
|
70
|
+
<% end %>
|
71
|
+
|
72
|
+
<div class="clear"></div>
|
73
|
+
</div><!-- /monittr -->
|
74
|
+
|
75
|
+
<script>if ('undefined' == typeof jQuery) { document.write("<script type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js\"></"+"script>"); }</script>
|
76
|
+
|
77
|
+
<script>
|
78
|
+
$(function() {
|
79
|
+
$('#monittr .server .content').hide();
|
80
|
+
|
81
|
+
$('#monittr .server h2').click(function() {
|
82
|
+
$(this).parent().toggleClass('expanded').find('.content').toggle('fast', function() { });
|
83
|
+
});
|
84
|
+
|
85
|
+
$('#toggle').toggle(
|
86
|
+
function() {
|
87
|
+
$('#monittr .server .content').show('fast');
|
88
|
+
$(this).html('- Collapse all');
|
89
|
+
},
|
90
|
+
function() {
|
91
|
+
$('#monittr .server .content').hide('fast');
|
92
|
+
$(this).html('+ Expand all');
|
93
|
+
}
|
94
|
+
);
|
95
|
+
});
|
96
|
+
</script>
|
@@ -0,0 +1 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?><monit><server><id>92d1d1a237da200ac04cc19890495214</id><incarnation>1289589073</incarnation><version>5.1.1</version><uptime>937661</uptime><poll>10</poll><startdelay>0</startdelay><localhostname>myapplication.cz</localhostname><controlfile>/usr/local/etc/monitrc</controlfile><httpd><address></address><port>2812</port><ssl>0</ssl></httpd></server><platform><name>FreeBSD</name><release>8.1-RELEASE</release><version>FreeBSD 8.1-RELEASE #0: Mon Jul 19 02:36:49 UTC 2010 root@mason.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC</version><machine>amd64</machine><cpu>4</cpu><memory>8373908</memory></platform><service type="0"><collected_sec>1290526733</collected_sec><collected_usec>927817</collected_usec><name>root</name><status>0</status><status_hint>0</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups><mode>755</mode><uid>0</uid><gid>0</gid><flags>20480</flags><block><percent>22.8</percent><usage>294.5 MB</usage><total>1978.5 MB</total></block><inode><percent>0.8</percent><usage>2382</usage><total>282622</total></inode></service><service type="0"><collected_sec>1290526733</collected_sec><collected_usec>927867</collected_usec><name>tmp</name><status>0</status><status_hint>0</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups><mode>1777</mode><uid>0</uid><gid>0</gid><flags>2101248</flags><block><percent>67.0</percent><usage>281.2 MB</usage><total>476.4 MB</total></block><inode><percent>4.3</percent><usage>2769</usage><total>63230</total></inode></service><service type="0"><collected_sec>1290526733</collected_sec><collected_usec>927885</collected_usec><name>usr</name><status>0</status><status_hint>0</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups><mode>755</mode><uid>0</uid><gid>0</gid><flags>2101248</flags><block><percent>35.1</percent><usage>2125.7 MB</usage><total>7815.5 MB</total></block><inode><percent>4.9</percent><usage>51155</usage><total>1036286</total></inode></service><service type="0"><collected_sec>1290526733</collected_sec><collected_usec>927903</collected_usec><name>var</name><status>0</status><status_hint>0</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups><mode>755</mode><uid>0</uid><gid>0</gid><flags>2101248</flags><block><percent>57.5</percent><usage>26554.6 MB</usage><total>53555.8 MB</total></block><inode><percent>0.1</percent><usage>8038</usage><total>7089150</total></inode></service><service type="3"><collected_sec>1290526733</collected_sec><collected_usec>928167</collected_usec><name>thin_1</name><status>0</status><status_hint>0</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups><name>my_application_thin</name></groups><pid>40199</pid><ppid>1</ppid><uptime>679095</uptime><children>0</children><memory><percent>1.2</percent><percenttotal>1.2</percenttotal><kilobyte>101576</kilobyte><kilobytetotal>101576</kilobytetotal></memory><cpu><percent>0.0</percent><percenttotal>0.0</percenttotal></cpu><unix><path>/var/run/thin/thin.1.sock</path><protocol>DEFAULT</protocol><responsetime>0.000</responsetime></unix></service><service type="3"><collected_sec>1290526733</collected_sec><collected_usec>928169</collected_usec><name>thin_2</name><status>0</status><status_hint>0</status_hint><monitor>0</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups><name>my_application_thin</name></groups></service><service type="3"><collected_sec>1290526733</collected_sec><collected_usec>928391</collected_usec><name>thin_3</name><status>0</status><status_hint>0</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups><name>my_application_thin</name></groups><pid>40070</pid><ppid>1</ppid><uptime>679107</uptime><children>0</children><memory><percent>1.3</percent><percenttotal>1.3</percenttotal><kilobyte>109268</kilobyte><kilobytetotal>109268</kilobytetotal></memory><cpu><percent>0.0</percent><percenttotal>0.0</percenttotal></cpu><unix><path>/var/run/thin/thin.3.sock</path><protocol>DEFAULT</protocol><responsetime>0.000</responsetime></unix></service><service type="3"><collected_sec>1290526733</collected_sec><collected_usec>938417</collected_usec><name>nginx</name><status>0</status><status_hint>0</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups><name>myapplication</name></groups><pid>41305</pid><ppid>1</ppid><uptime>299250</uptime><children>6</children><memory><percent>0.0</percent><percenttotal>0.3</percenttotal><kilobyte>3264</kilobyte><kilobytetotal>29136</kilobytetotal></memory><cpu><percent>0.0</percent><percenttotal>0.0</percenttotal></cpu><port><hostname>localhost</hostname><portnumber>80</portnumber><request>/sign_in</request><protocol>HTTP</protocol><type>TCP</type><responsetime>0.010</responsetime></port></service><service type="3"><collected_sec>1290526733</collected_sec><collected_usec>940124</collected_usec><name>couchdb</name><status>0</status><status_hint>524288</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups><pid>29555</pid><ppid>29554</ppid><uptime>59920</uptime><children>40</children><memory><percent>4.4</percent><percenttotal>7.2</percenttotal><kilobyte>372484</kilobyte><kilobytetotal>608548</kilobytetotal></memory><cpu><percent>4.2</percent><percenttotal>14.5</percenttotal></cpu><port><hostname>127.0.0.1</hostname><portnumber>5984</portnumber><request></request><protocol>DEFAULT</protocol><type>TCP</type><responsetime>0.000</responsetime></port></service><service type="3"><collected_sec>1290526733</collected_sec><collected_usec>938754</collected_usec><name>couchdb_lucene</name><status>0</status><status_hint>524288</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups><pid>32378</pid><ppid>1</ppid><uptime>433976</uptime><children>0</children><memory><percent>2.0</percent><percenttotal>2.0</percenttotal><kilobyte>171184</kilobyte><kilobytetotal>171184</kilobytetotal></memory><cpu><percent>0.0</percent><percenttotal>0.0</percenttotal></cpu><port><hostname>127.0.0.1</hostname><portnumber>5985</portnumber><request></request><protocol>DEFAULT</protocol><type>TCP</type><responsetime>0.000</responsetime></port></service><service type="3"><collected_sec>1290526733</collected_sec><collected_usec>939199</collected_usec><name>redis</name><status>0</status><status_hint>524288</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups><pid>963</pid><ppid>1</ppid><uptime>937659</uptime><children>0</children><memory><percent>11.8</percent><percenttotal>11.8</percenttotal><kilobyte>992948</kilobyte><kilobytetotal>992948</kilobytetotal></memory><cpu><percent>0.2</percent><percenttotal>0.2</percenttotal></cpu><port><hostname>127.0.0.1</hostname><portnumber>6379</portnumber><request></request><protocol>DEFAULT</protocol><type>TCP</type><responsetime>0.000</responsetime></port></service><service type="3"><collected_sec>1290526733</collected_sec><collected_usec>939333</collected_usec><name>refresh_workers</name><status>0</status><status_hint>0</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups><pid>75352</pid><ppid>75350</ppid><uptime>67064</uptime><children>10</children><memory><percent>0.7</percent><percenttotal>9.4</percenttotal><kilobyte>59020</kilobyte><kilobytetotal>787952</kilobytetotal></memory><cpu><percent>0.0</percent><percenttotal>5.9</percenttotal></cpu></service><service type="3"><collected_sec>1290526733</collected_sec><collected_usec>939465</collected_usec><name>enrichment_workers</name><status>0</status><status_hint>0</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups><pid>75434</pid><ppid>75433</ppid><uptime>49821</uptime><children>10</children><memory><percent>0.7</percent><percenttotal>8.4</percenttotal><kilobyte>59384</kilobyte><kilobytetotal>704804</kilobytetotal></memory><cpu><percent>0.0</percent><percenttotal>0.6</percenttotal></cpu></service><service type="3"><collected_sec>1290526733</collected_sec><collected_usec>939601</collected_usec><name>enrichment_manager_workers</name><status>0</status><status_hint>0</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups><pid>14922</pid><ppid>14921</ppid><uptime>655967</uptime><children>1</children><memory><percent>0.6</percent><percenttotal>1.4</percenttotal><kilobyte>57204</kilobyte><kilobytetotal>119852</kilobytetotal></memory><cpu><percent>0.0</percent><percenttotal>0.0</percenttotal></cpu></service><service type="3"><collected_sec>1290526733</collected_sec><collected_usec>939682</collected_usec><name>delete_keyword_workers</name><status>0</status><status_hint>0</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups><pid>12889</pid><ppid>12888</ppid><uptime>656639</uptime><children>1</children><memory><percent>0.6</percent><percenttotal>1.4</percenttotal><kilobyte>56364</kilobyte><kilobytetotal>119656</kilobytetotal></memory><cpu><percent>0.0</percent><percenttotal>0.0</percenttotal></cpu></service><service type="3"><collected_sec>1290526733</collected_sec><collected_usec>939749</collected_usec><name>reports_workers</name><status>0</status><status_hint>0</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups><pid>12934</pid><ppid>12933</ppid><uptime>656624</uptime><children>1</children><memory><percent>0.6</percent><percenttotal>1.4</percenttotal><kilobyte>56908</kilobyte><kilobytetotal>120236</kilobytetotal></memory><cpu><percent>0.0</percent><percenttotal>0.0</percenttotal></cpu></service><service type="3"><collected_sec>1290526733</collected_sec><collected_usec>939824</collected_usec><name>scheduler_workers</name><status>0</status><status_hint>0</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups><pid>12870</pid><ppid>12869</ppid><uptime>656652</uptime><children>1</children><memory><percent>0.6</percent><percenttotal>1.3</percenttotal><kilobyte>56596</kilobyte><kilobytetotal>116260</kilobytetotal></memory><cpu><percent>0.0</percent><percenttotal>0.0</percenttotal></cpu></service><service type="3"><collected_sec>1290526733</collected_sec><collected_usec>939890</collected_usec><name>scheduler</name><status>0</status><status_hint>0</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups><pid>12681</pid><ppid>1</ppid><uptime>656765</uptime><children>0</children><memory><percent>0.7</percent><percenttotal>0.7</percenttotal><kilobyte>66200</kilobyte><kilobytetotal>66200</kilobytetotal></memory><cpu><percent>0.2</percent><percenttotal>0.2</percenttotal></cpu></service><service type="3"><collected_sec>1290526733</collected_sec><collected_usec>939892</collected_usec><name>enrichment_fresh</name><status>0</status><status_hint>0</status_hint><monitor>0</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups></service><service type="5"><collected_sec>1290526733</collected_sec><collected_usec>939894</collected_usec><name>myapplication.cz</name><status>0</status><status_hint>0</status_hint><monitor>1</monitor><monitormode>0</monitormode><pendingaction>0</pendingaction><groups></groups><system><load><avg01>5.28</avg01><avg05>5.66</avg05><avg15>5.06</avg15></load><cpu><user>63.2</user><system>21.8</system></cpu><memory><percent>37.0</percent><kilobyte>3099648</kilobyte></memory></system></service></monit>
|
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Monittr
|
4
|
+
|
5
|
+
class MonittrTest < Test::Unit::TestCase
|
6
|
+
|
7
|
+
context "Cluster" do
|
8
|
+
|
9
|
+
should "be initialized with URLs" do
|
10
|
+
assert_nothing_raised do
|
11
|
+
cluster = Monittr::Cluster.new %w[ http://admin:monit@localhost:2812/_status?format=xml
|
12
|
+
http://admin:monit@localhost:2812/_status?format=xml ]
|
13
|
+
assert_not_nil cluster.servers
|
14
|
+
assert_equal 2, cluster.servers.size
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
context "Server" do
|
21
|
+
|
22
|
+
setup do
|
23
|
+
@server = Server.new( fixture_file('status.xml') )
|
24
|
+
end
|
25
|
+
|
26
|
+
should "fetch info from Monit embedded web server" do
|
27
|
+
assert_nothing_raised { Server.fetch }
|
28
|
+
assert_nothing_raised { Server.fetch('http://admin:monit@localhost:2812/_status?format=xml') }
|
29
|
+
assert_raise(FakeWeb::NetConnectNotAllowedError) { Server.fetch('http://example.com') }
|
30
|
+
end
|
31
|
+
|
32
|
+
should "return system info" do
|
33
|
+
assert_not_nil @server.system
|
34
|
+
assert_equal 0, @server.system.status
|
35
|
+
assert_equal 1, @server.system.monitored
|
36
|
+
assert_equal 'myapplication.cz', @server.system.name
|
37
|
+
assert_equal 5.28, @server.system.load
|
38
|
+
assert_equal 0, @server.system.status
|
39
|
+
assert_equal 937661, @server.system.uptime
|
40
|
+
end
|
41
|
+
|
42
|
+
should "return filesystems info" do
|
43
|
+
assert_not_nil @server.filesystems
|
44
|
+
assert_equal 4, @server.filesystems.size
|
45
|
+
|
46
|
+
filesystem = @server.filesystems.first
|
47
|
+
assert_not_nil filesystem
|
48
|
+
assert_equal 0, filesystem.status
|
49
|
+
assert_equal 1, filesystem.monitored
|
50
|
+
assert_equal 22.8, filesystem.percent
|
51
|
+
end
|
52
|
+
|
53
|
+
should "return processes info" do
|
54
|
+
assert_not_nil @server.processes
|
55
|
+
assert_equal 15, @server.processes.size
|
56
|
+
|
57
|
+
thin = @server.processes.first
|
58
|
+
assert_not_nil thin
|
59
|
+
assert_equal 0, thin.status
|
60
|
+
assert_equal 1, thin.monitored
|
61
|
+
assert_equal 1.2, thin.memory
|
62
|
+
assert_equal 0.0, thin.cpu
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'monittr/sinatra/monittr'
|
4
|
+
|
5
|
+
class ExampleApp < Sinatra::Base
|
6
|
+
register Sinatra::MonittrHTML
|
7
|
+
|
8
|
+
get "/" do
|
9
|
+
monittr.html
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
class SinatraHelperTest < Test::Unit::TestCase
|
14
|
+
include Rack::Test::Methods
|
15
|
+
|
16
|
+
def app
|
17
|
+
ExampleApp
|
18
|
+
end
|
19
|
+
|
20
|
+
context "Sinatra helper" do
|
21
|
+
|
22
|
+
should "display monittr info" do
|
23
|
+
get '/'
|
24
|
+
|
25
|
+
assert last_response.ok?
|
26
|
+
assert last_response.body.include?('myapplication.cz'), "Response body should contain: myapplication.cz"
|
27
|
+
assert last_response.body.include?('thin_1'), "Response body should contain: thin_1"
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../..', __FILE__)
|
2
|
+
require 'rubygems'
|
3
|
+
require 'test/unit'
|
4
|
+
require 'rack/test'
|
5
|
+
require 'shoulda'
|
6
|
+
require 'mocha'
|
7
|
+
require 'fakeweb'
|
8
|
+
require 'pathname'
|
9
|
+
require 'turn' unless ENV["TM_FILEPATH"]
|
10
|
+
|
11
|
+
ENV['RACK_ENV'] = 'test'
|
12
|
+
|
13
|
+
require 'lib/monittr'
|
14
|
+
|
15
|
+
class Test::Unit::TestCase
|
16
|
+
|
17
|
+
def setup
|
18
|
+
FakeWeb.register_uri(:get, 'http://admin:monit@localhost:2812/_status?format=xml', :body => fixture_file('status.xml'))
|
19
|
+
FakeWeb.allow_net_connect = false
|
20
|
+
end
|
21
|
+
|
22
|
+
def fixtures_path
|
23
|
+
Pathname( File.expand_path( '../fixtures', __FILE__ ) )
|
24
|
+
end
|
25
|
+
|
26
|
+
def fixture_file(path)
|
27
|
+
File.read File.expand_path( path, fixtures_path )
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
metadata
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: monittr
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
version: 0.0.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Karel Minarik
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-11-25 00:00:00 +01:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: bundler
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 1
|
29
|
+
- 0
|
30
|
+
- 0
|
31
|
+
version: 1.0.0
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: rest-client
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :runtime
|
45
|
+
version_requirements: *id002
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: nokogiri
|
48
|
+
prerelease: false
|
49
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
segments:
|
54
|
+
- 0
|
55
|
+
version: "0"
|
56
|
+
type: :runtime
|
57
|
+
version_requirements: *id003
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: sinatra
|
60
|
+
prerelease: false
|
61
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
version: "0"
|
68
|
+
type: :runtime
|
69
|
+
version_requirements: *id004
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: shoulda
|
72
|
+
prerelease: false
|
73
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
segments:
|
78
|
+
- 0
|
79
|
+
version: "0"
|
80
|
+
type: :development
|
81
|
+
version_requirements: *id005
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: turn
|
84
|
+
prerelease: false
|
85
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
version: "0"
|
92
|
+
type: :development
|
93
|
+
version_requirements: *id006
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: fakeweb
|
96
|
+
prerelease: false
|
97
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
segments:
|
102
|
+
- 0
|
103
|
+
version: "0"
|
104
|
+
type: :development
|
105
|
+
version_requirements: *id007
|
106
|
+
description: " Monittr provides a Ruby interface for displaying Monit statistics\n in Sinatra based web applications.\n\n It loads information from the web server embedded in Monit and\n makes it accessible as Ruby objects.\n\n It also displays the information in HTML with the provided helpers.\n"
|
107
|
+
email: karmi@karmi.cz
|
108
|
+
executables: []
|
109
|
+
|
110
|
+
extensions: []
|
111
|
+
|
112
|
+
extra_rdoc_files:
|
113
|
+
- README.markdown
|
114
|
+
- LICENSE
|
115
|
+
files:
|
116
|
+
- README.markdown
|
117
|
+
- Rakefile
|
118
|
+
- LICENSE
|
119
|
+
- lib/monittr/sinatra/monittr.rb
|
120
|
+
- lib/monittr/sinatra/style.css
|
121
|
+
- lib/monittr/sinatra/template.erb
|
122
|
+
- lib/monittr/version.rb
|
123
|
+
- lib/monittr.rb
|
124
|
+
- test/fixtures/status.xml
|
125
|
+
- test/monittr_test.rb
|
126
|
+
- test/sinatra_helper_test.rb
|
127
|
+
- test/test_helper.rb
|
128
|
+
has_rdoc: true
|
129
|
+
homepage: http://github.com/karmi/monittr
|
130
|
+
licenses: []
|
131
|
+
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options:
|
134
|
+
- --charset=UTF-8
|
135
|
+
require_paths:
|
136
|
+
- lib
|
137
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
138
|
+
requirements:
|
139
|
+
- - ">="
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
segments:
|
142
|
+
- 0
|
143
|
+
version: "0"
|
144
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
145
|
+
requirements:
|
146
|
+
- - ">="
|
147
|
+
- !ruby/object:Gem::Version
|
148
|
+
segments:
|
149
|
+
- 1
|
150
|
+
- 3
|
151
|
+
- 6
|
152
|
+
version: 1.3.6
|
153
|
+
requirements: []
|
154
|
+
|
155
|
+
rubyforge_project:
|
156
|
+
rubygems_version: 1.3.6
|
157
|
+
signing_key:
|
158
|
+
specification_version: 3
|
159
|
+
summary: Web interface for Monit statistics
|
160
|
+
test_files: []
|
161
|
+
|