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 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
- use Rack::Monitor if ENV['RACK_ENV'] == 'production'
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.each do |sensor|
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
- output << "[#{class_name}:#{var}] #{desc}: #{value}\n"
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
@@ -0,0 +1,4 @@
1
+ [rack*]
2
+ user www-data
3
+ env.url http://127.0.0.1:%d/rack_status
4
+ env.ports 3000
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
+ }
@@ -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.2.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-05 00:00:00 +01:00
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