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 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