rack-monitor 0.2.0 → 0.3.0
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/README.rdoc +7 -3
- data/lib/rack/monitor/monitor_app.rb +28 -2
- data/munin/plugin-conf.d/rack +4 -0
- data/munin/rack_memory +97 -0
- data/munin/rack_requests +82 -0
- data/munin/rack_status_codes +98 -0
- metadata +6 -2
data/README.rdoc
CHANGED
@@ -5,7 +5,7 @@ monitoring tools like Munin.
|
|
5
5
|
|
6
6
|
==Installation
|
7
7
|
|
8
|
-
sudo gem install rack-monitor
|
8
|
+
sudo gem install rack-monitor rack-contrib
|
9
9
|
|
10
10
|
==Basic Usage
|
11
11
|
|
@@ -14,9 +14,13 @@ any Rack-based application. If your application includes a rackup (<tt>.ru</tt>)
|
|
14
14
|
or uses Rack::Builder to construct the application pipeline, simply require
|
15
15
|
and use as follows:
|
16
16
|
|
17
|
+
require 'rack/contrib'
|
17
18
|
require 'rack/monitor'
|
18
19
|
|
19
|
-
|
20
|
+
if ENV['RACK_ENV'] == 'production'
|
21
|
+
use Rack::Access, '/rack_status' => [ '127.0.0.1' ]
|
22
|
+
use Rack::Monitor, :url => '/rack_status', :watch => ['/', '/ping']
|
23
|
+
end
|
20
24
|
|
21
25
|
run app
|
22
26
|
|
@@ -27,7 +31,7 @@ Add this to your <tt>config/environments/production.rb</tt>:
|
|
27
31
|
config.gem "rack-monitor", :lib => "rack/monitor"
|
28
32
|
|
29
33
|
require 'rack/monitor' #Rails bug?
|
30
|
-
config.middleware.use ::Rack::Monitor
|
34
|
+
config.middleware.use ::Rack::Monitor, :url => '/rack_status', :watch => ['/', '/ping']
|
31
35
|
|
32
36
|
You should now see <tt>Rack::Monitor</tt> listed in the middleware pipeline:
|
33
37
|
|
@@ -14,6 +14,12 @@ class MonitorApp
|
|
14
14
|
@options = {:url=>'/rack_status'}.merge(options)
|
15
15
|
sensor_class_names = Rack::Monitor.constants.reject { |s| %q(Sensor MonitorApp).include?(s) }
|
16
16
|
@sensors = sensor_class_names.collect { |s| Rack::Monitor.const_get(s).new }
|
17
|
+
@watches = {}
|
18
|
+
if @options.has_key?(:watch)
|
19
|
+
@options[:watch].each do |path|
|
20
|
+
@watches[path] = [Request.new]
|
21
|
+
end
|
22
|
+
end
|
17
23
|
end
|
18
24
|
|
19
25
|
def call(env, options={})
|
@@ -21,7 +27,15 @@ class MonitorApp
|
|
21
27
|
[200, {'Content-Type' => 'text/plain'}, [monitor_output]]
|
22
28
|
else
|
23
29
|
@sensors.each { |sensor| sensor.before(env) }
|
30
|
+
if @watches.has_key?(env["PATH_INFO"])
|
31
|
+
@watches[env["PATH_INFO"]].each { |sensor| sensor.before(env) }
|
32
|
+
end
|
33
|
+
|
24
34
|
status, headers, body = @app.call(env)
|
35
|
+
|
36
|
+
if @watches.has_key?(env["PATH_INFO"])
|
37
|
+
@watches[env["PATH_INFO"]].each { |sensor| sensor.after(env, status, headers, body) }
|
38
|
+
end
|
25
39
|
@sensors.each { |sensor| sensor.after(env, status, headers, body) }
|
26
40
|
[status, headers, body]
|
27
41
|
end
|
@@ -31,15 +45,27 @@ class MonitorApp
|
|
31
45
|
|
32
46
|
def monitor_output
|
33
47
|
output = ''
|
34
|
-
@sensors
|
48
|
+
output << sensors_output(@sensors)
|
49
|
+
@watches.each { |path, sensors| output << sensors_output(sensors, path) }
|
50
|
+
output
|
51
|
+
end
|
52
|
+
|
53
|
+
def sensors_output(sensors, path = nil)
|
54
|
+
output = ''
|
55
|
+
sensors.each do |sensor|
|
35
56
|
class_name = sensor.class.name.gsub(/^.*::/, '')
|
36
57
|
sensor.collect
|
37
58
|
sensor.measurements.each do |var, desc, value|
|
38
|
-
|
59
|
+
if path
|
60
|
+
output << "[#{class_name}:#{var}:#{path}] #{desc} path #{path}: #{value}\n"
|
61
|
+
else
|
62
|
+
output << "[#{class_name}:#{var}] #{desc}: #{value}\n"
|
63
|
+
end
|
39
64
|
end
|
40
65
|
end
|
41
66
|
output
|
42
67
|
end
|
68
|
+
|
43
69
|
end
|
44
70
|
|
45
71
|
end
|
data/munin/rack_memory
ADDED
@@ -0,0 +1,97 @@
|
|
1
|
+
#!/usr/bin/perl
|
2
|
+
#
|
3
|
+
# Plugin to monitor memory usage of a rack server process.
|
4
|
+
#
|
5
|
+
# This configuration section shows the defaults of the plugin:
|
6
|
+
#
|
7
|
+
# [rack_*]
|
8
|
+
# env.url http://127.0.0.1:%d/rack_status
|
9
|
+
# env.ports 80
|
10
|
+
#
|
11
|
+
# Parameters supported:
|
12
|
+
#
|
13
|
+
# config (required)
|
14
|
+
#
|
15
|
+
# Magic markers - optional - used by installation scripts and munin-config:
|
16
|
+
#
|
17
|
+
#%# family=manual
|
18
|
+
|
19
|
+
my $ret = undef;
|
20
|
+
|
21
|
+
if (! eval "require LWP::UserAgent;")
|
22
|
+
{
|
23
|
+
$ret = "LWP::UserAgent not found";
|
24
|
+
}
|
25
|
+
|
26
|
+
my $URL = exists $ENV{'url'} ? $ENV{'url'} : "http://127.0.0.1:%d/rack_status";
|
27
|
+
my @PORTS = exists $ENV{'ports'} ? split(' ', $ENV{'ports'}) : (80);
|
28
|
+
|
29
|
+
if ( defined $ARGV[0] and $ARGV[0] eq "autoconf" )
|
30
|
+
{
|
31
|
+
if ($ret)
|
32
|
+
{
|
33
|
+
print "no ($ret)\n";
|
34
|
+
exit 1;
|
35
|
+
}
|
36
|
+
|
37
|
+
my $ua = LWP::UserAgent->new(timeout => 30);
|
38
|
+
|
39
|
+
my @badports;
|
40
|
+
foreach my $port (@PORTS) {
|
41
|
+
my $url = sprintf $URL, $port;
|
42
|
+
my $response = $ua->request(HTTP::Request->new('GET',$url));
|
43
|
+
push @badports, $port unless $response->is_success and $response->content =~ /^\[Version:rack_info\]/m;
|
44
|
+
}
|
45
|
+
if (@badports) {
|
46
|
+
print "no (no rack server status on ports @badports)\n";
|
47
|
+
exit 1;
|
48
|
+
} else {
|
49
|
+
print "yes\n";
|
50
|
+
exit 0;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
my %mems;
|
55
|
+
|
56
|
+
if ( defined $ARGV[0] and $ARGV[0] eq "config" )
|
57
|
+
{
|
58
|
+
#&fetch_meminfo;
|
59
|
+
|
60
|
+
print "graph_title Rack memory usage\n";
|
61
|
+
print "graph_args --base 1024 -l 0 --vertical-label Bytes\n"; #--upper-limit ", $mems{'MemTotal'}, "\n";
|
62
|
+
if (scalar(@PORTS) > 1) {
|
63
|
+
print "graph_total Total\n";
|
64
|
+
}
|
65
|
+
print "graph_category Http\n";
|
66
|
+
foreach my $port (@PORTS) {
|
67
|
+
print "memory$port.label Port $port\n";
|
68
|
+
print "memory$port.draw AREA\n";
|
69
|
+
print "memory$port.info Memory used by rack process.\n";
|
70
|
+
}
|
71
|
+
exit 0;
|
72
|
+
}
|
73
|
+
|
74
|
+
my $ua = LWP::UserAgent->new(timeout => 30);
|
75
|
+
|
76
|
+
foreach my $port (@PORTS) {
|
77
|
+
my $url = sprintf $URL, $port;
|
78
|
+
my $response = $ua->request(HTTP::Request->new('GET',$url));
|
79
|
+
if ($response->content =~ /^\[Memory:used\].*:\s+(.+)$/im) {
|
80
|
+
print "memory$port.value $1\n";
|
81
|
+
} else {
|
82
|
+
print "memory$port.value U\n";
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
sub fetch_meminfo
|
87
|
+
{
|
88
|
+
open (IN, "/proc/meminfo") || die "Could not open /proc/meminfo for reading: $!";
|
89
|
+
while (<IN>)
|
90
|
+
{
|
91
|
+
if (/^(\w+):\s*(\d+)\s+kb/i)
|
92
|
+
{
|
93
|
+
$mems{"$1"} = $2 * 1024;
|
94
|
+
}
|
95
|
+
}
|
96
|
+
close (IN);
|
97
|
+
}
|
data/munin/rack_requests
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
#!/usr/bin/perl
|
2
|
+
#
|
3
|
+
# Plugin to monitor requests per second of a rack server process.
|
4
|
+
#
|
5
|
+
# This configuration section shows the defaults of the plugin:
|
6
|
+
#
|
7
|
+
# [rack_*]
|
8
|
+
# env.url http://127.0.0.1:%d/rack_status
|
9
|
+
# env.ports 80
|
10
|
+
#
|
11
|
+
# Parameters supported:
|
12
|
+
#
|
13
|
+
# config (required)
|
14
|
+
#
|
15
|
+
# Magic markers - optional - used by installation scripts and munin-config:
|
16
|
+
#
|
17
|
+
#%# family=manual
|
18
|
+
|
19
|
+
my $ret = undef;
|
20
|
+
|
21
|
+
if (! eval "require LWP::UserAgent;")
|
22
|
+
{
|
23
|
+
$ret = "LWP::UserAgent not found";
|
24
|
+
}
|
25
|
+
|
26
|
+
my $URL = exists $ENV{'url'} ? $ENV{'url'} : "http://127.0.0.1:%d/rack_status";
|
27
|
+
my @PORTS = exists $ENV{'ports'} ? split(' ', $ENV{'ports'}) : (80);
|
28
|
+
|
29
|
+
if ( defined $ARGV[0] and $ARGV[0] eq "autoconf" )
|
30
|
+
{
|
31
|
+
if ($ret)
|
32
|
+
{
|
33
|
+
print "no ($ret)\n";
|
34
|
+
exit 1;
|
35
|
+
}
|
36
|
+
|
37
|
+
my $ua = LWP::UserAgent->new(timeout => 30);
|
38
|
+
|
39
|
+
my @badports;
|
40
|
+
foreach my $port (@PORTS) {
|
41
|
+
my $url = sprintf $URL, $port;
|
42
|
+
my $response = $ua->request(HTTP::Request->new('GET',$url));
|
43
|
+
push @badports, $port unless $response->is_success and $response->content =~ /^\[Version:rack_info\]/m;
|
44
|
+
}
|
45
|
+
if (@badports) {
|
46
|
+
print "no (no rack server status on ports @badports)\n";
|
47
|
+
exit 1;
|
48
|
+
} else {
|
49
|
+
print "yes\n";
|
50
|
+
exit 0;
|
51
|
+
}
|
52
|
+
}
|
53
|
+
|
54
|
+
if ( defined $ARGV[0] and $ARGV[0] eq "config" )
|
55
|
+
{
|
56
|
+
print "graph_title Rack requests\n";
|
57
|
+
print "graph_args --base 1000\n";
|
58
|
+
print "graph_vlabel requests / \${graph_period}\n";
|
59
|
+
if (scalar(@PORTS) > 1) {
|
60
|
+
print "graph_total total\n";
|
61
|
+
}
|
62
|
+
print "graph_category Http\n";
|
63
|
+
foreach my $port (@PORTS) {
|
64
|
+
print "requests$port.label Port $port\n";
|
65
|
+
print "requests$port.type DERIVE\n";
|
66
|
+
print "requests$port.max 1000000\n";
|
67
|
+
print "requests$port.min 0\n";
|
68
|
+
}
|
69
|
+
exit 0;
|
70
|
+
}
|
71
|
+
|
72
|
+
my $ua = LWP::UserAgent->new(timeout => 30);
|
73
|
+
|
74
|
+
foreach my $port (@PORTS) {
|
75
|
+
my $url = sprintf $URL, $port;
|
76
|
+
my $response = $ua->request(HTTP::Request->new('GET',$url));
|
77
|
+
if ($response->content =~ /^\[Request:count\].*:\s+(.+)$/im) {
|
78
|
+
print "requests$port.value $1\n";
|
79
|
+
} else {
|
80
|
+
print "requests$port.value U\n";
|
81
|
+
}
|
82
|
+
}
|
@@ -0,0 +1,98 @@
|
|
1
|
+
#!/usr/bin/perl
|
2
|
+
#
|
3
|
+
# Plugin to monitor status code responses of a rack server process.
|
4
|
+
#
|
5
|
+
# This configuration section shows the defaults of the plugin:
|
6
|
+
#
|
7
|
+
# [rack_*]
|
8
|
+
# env.url http://127.0.0.1:%d/rack_status
|
9
|
+
# env.ports 80
|
10
|
+
#
|
11
|
+
# Parameters supported:
|
12
|
+
#
|
13
|
+
# config (required)
|
14
|
+
#
|
15
|
+
# Magic markers - optional - used by installation scripts and munin-config:
|
16
|
+
#
|
17
|
+
#%# family=manual
|
18
|
+
|
19
|
+
my $ret = undef;
|
20
|
+
|
21
|
+
if (! eval "require LWP::UserAgent;")
|
22
|
+
{
|
23
|
+
$ret = "LWP::UserAgent not found";
|
24
|
+
}
|
25
|
+
|
26
|
+
my $URL = exists $ENV{'url'} ? $ENV{'url'} : "http://127.0.0.1:%d/rack_status";
|
27
|
+
my @PORTS = exists $ENV{'ports'} ? split(' ', $ENV{'ports'}) : (80);
|
28
|
+
|
29
|
+
my %CODES = (200 => 200, 403 => 403, 404 => 404,
|
30
|
+
1 => "1xx", 2 => "2xx", 3 => "3xx", 4 => "4xx", 5 => "5xx");
|
31
|
+
|
32
|
+
if ( defined $ARGV[0] and $ARGV[0] eq "autoconf" )
|
33
|
+
{
|
34
|
+
if ($ret)
|
35
|
+
{
|
36
|
+
print "no ($ret)\n";
|
37
|
+
exit 1;
|
38
|
+
}
|
39
|
+
|
40
|
+
my $ua = LWP::UserAgent->new(timeout => 30);
|
41
|
+
|
42
|
+
my @badports;
|
43
|
+
foreach my $port (@PORTS) {
|
44
|
+
my $url = sprintf $URL, $port;
|
45
|
+
my $response = $ua->request(HTTP::Request->new('GET',$url));
|
46
|
+
push @badports, $port unless $response->is_success and $response->content =~ /^\[Version:rack_info\]/m;
|
47
|
+
}
|
48
|
+
if (@badports) {
|
49
|
+
print "no (no rack server status on ports @badports)\n";
|
50
|
+
exit 1;
|
51
|
+
} else {
|
52
|
+
print "yes\n";
|
53
|
+
exit 0;
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
if ( defined $ARGV[0] and $ARGV[0] eq "config" )
|
58
|
+
{
|
59
|
+
print "graph_title Response codes\n";
|
60
|
+
print "graph_args --base 1000\n";
|
61
|
+
print "graph_category Http\n";
|
62
|
+
my $level = 0;
|
63
|
+
foreach my $code (sort(keys(%CODES))) {
|
64
|
+
print "status${code}.label Status $CODES{$code}\n";
|
65
|
+
print "status${code}.type DERIVE\n";
|
66
|
+
if ($level == 0) {
|
67
|
+
print "status${code}.draw AREA\n";
|
68
|
+
} else {
|
69
|
+
print "status${code}.draw STACK\n";
|
70
|
+
}
|
71
|
+
print "status${code}.max 1000000\n";
|
72
|
+
print "status${code}.min 0\n";
|
73
|
+
$level++;
|
74
|
+
}
|
75
|
+
exit 0;
|
76
|
+
}
|
77
|
+
|
78
|
+
my $ua = LWP::UserAgent->new(timeout => 30);
|
79
|
+
|
80
|
+
my $request_total = 0;
|
81
|
+
my %status_total = {};
|
82
|
+
foreach my $code (keys(%CODES)) { $status_total{$code} = 0; }
|
83
|
+
|
84
|
+
foreach my $port (@PORTS) {
|
85
|
+
my $url = sprintf $URL, $port;
|
86
|
+
my $response = $ua->request(HTTP::Request->new('GET',$url));
|
87
|
+
if ($response->content =~ /^\[Request:count\].*:\s+(.+)$/im) {
|
88
|
+
$request_total += $1;
|
89
|
+
}
|
90
|
+
foreach my $code (keys(%CODES)) {
|
91
|
+
if ($response->content =~ /^\[Request:status$code\].*:\s+(.+)$/im) {
|
92
|
+
$status_total{$code} += $1;
|
93
|
+
}
|
94
|
+
}
|
95
|
+
}
|
96
|
+
foreach my $code (sort(keys(%CODES))) {
|
97
|
+
print "status${code}.value $status_total{$code}\n";
|
98
|
+
}
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rack-monitor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pirmin Kalberer
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-16 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -29,6 +29,10 @@ files:
|
|
29
29
|
- lib/rack/monitor/sensors/memory.rb
|
30
30
|
- lib/rack/monitor/sensors/request.rb
|
31
31
|
- lib/rack/monitor/sensors/version.rb
|
32
|
+
- munin/plugin-conf.d/rack
|
33
|
+
- munin/rack_memory
|
34
|
+
- munin/rack_requests
|
35
|
+
- munin/rack_status_codes
|
32
36
|
- LICENSE
|
33
37
|
- README.rdoc
|
34
38
|
has_rdoc: true
|