rack-monitor 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|