2
0
mirror of https://github.com/munin-monitoring/contrib.git synced 2018-11-08 00:59:34 +01:00

apache_status: add a new multigraph plugin to replace the old apache_* from the main repository.

This plugin uses a single requests to parse all the statistics instead
of making three of them, reducing the overhead, and uses the
multigraph capabilities to generate the same graphs. The naming is
compatible so that it should be a clean update from the previous
plugins.

This also merges in apache_average_requests (and apache_request_rate)
which, albeit not as relevant, also parsed the same file.
This commit is contained in:
Diego Elio Pettenò 2012-11-05 12:23:46 -08:00
parent 4895666d4d
commit 1b2574a43a
3 changed files with 289 additions and 169 deletions

View File

@ -1,128 +0,0 @@
#!/usr/bin/perl
# -*- cperl -*-
=head1 NAME
apache_average_request - Munin plugin to monitor the average request to
Apache servers. It handles a list of ports passed in from a plugin
configuration file.
=head1 APPLICABLE SYSTEMS
Apache HTTP servers with C</server-status> enabled.
=head1 CONFIGURATION
Enable stats in apache first!:
<VirtualHost 127.0.0.1:80>
<Location /server-status>
SetHandler server-status
AuthUserFile /route/to/auth.file
AuthName Login-Stats
AuthType Basic
require valid-user
</Location>
</VirtualHost>
And now in munin conf:
[apache_*]
env.url http://USER:PASS@127.0.0.1/server-status?auto
env.ports 80
=head1 AUTHOR
Ricardo Fraile <rfrail3@yahoo.es>
Unknown
=head1 LICENSE
GPLv2
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf
=cut
use strict;
use warnings;
use Munin::Plugin;
my $ret = undef;
if (! eval "require LWP::UserAgent;")
{
$ret = "LWP::UserAgent not found";
if ( ! defined $ARGV[0] ) {
die $ret;
}
}
my $URL = exists $ENV{'url'} ? $ENV{'url'} : "http://127.0.0.1:%d/server-status?auto";
my @PORTS = exists $ENV{'ports'} ? split(' ', $ENV{'ports'}) : (80);
if ( defined $ARGV[0] and $ARGV[0] eq "autoconf" )
{
if ($ret)
{
print "no ($ret)\n";
exit 0;
}
my $ua = LWP::UserAgent->new(timeout => 30);
foreach my $port (@PORTS) {
my $url = sprintf $URL, $port;
my $response = $ua->request(HTTP::Request->new('GET',$url));
if ($response->is_success) {
if ($response->content =~ /^Total Accesses:/im ){
next;
}
else {
print "no (ExtendedStatus option for apache"
. " mod_status is missing on port $port)\n";
exit 0;
}
}
elsif ($response->code == 404) {
print "no (apache server-status not found. check if mod_status is enabled)\n";
exit 0;
}
else {
print "no (Port $port: ". $response->message .")\n";
exit 0;
}
}
print "yes\n";
exit 0;
}
if ( defined $ARGV[0] and $ARGV[0] eq "config" )
{
print "graph_title Average apache request\n";
print "graph_title Average apache Requests per second\n";
print "graph_vlabel average reqs/sec\n";
print "graph_scale no\n";
print "graph_category apache\n";
print "request.label Average apache reqs/sec\n";
exit 0;
}
my $ua = LWP::UserAgent->new(timeout => 30);
foreach my $port (@PORTS) {
my $url = sprintf $URL, $port;
my $response = $ua->request(HTTP::Request->new('GET',$url));
if ($response->content =~ /^ReqPerSec:\s+(.+)$/im) {
print "request.value $1\n";
} else {
print "request.value U\n";
}
}
# vim:syntax=perl

View File

@ -1,41 +0,0 @@
#!/usr/bin/env ruby
require 'rubygems'
require 'json'
require 'open-uri'
if ARGV.first == 'config'
puts 'graph_category Apache'
puts 'graph_title Requests per second'
puts 'graph_vlabel reqs/sec'
puts 'graph_scale no'
puts 'requests_per_second.label Apache reqs/sec'
exit 0
end
STATUS_URL = 'http://localhost/server-status?auto'
TMPFILE = '/tmp/apache-status-monitor'
SECONDS_BEFORE_STALE = 900
begin
previous_sample = File.exists?(TMPFILE) ? JSON.parse(File.open(TMPFILE, 'r').read) : {}
output = {}
apache_status = open(STATUS_URL).read
new_total_requests = apache_status.match(/Total Accesses: (\d+)$/)[1].to_i #subtract one to account for request we just made!
sample_duration = previous_sample['updated_at'] ? Time.now - Time.at(previous_sample['updated_at'].to_i) : nil
if sample_duration && sample_duration < SECONDS_BEFORE_STALE
output['requests_per_second'] = "%0.2f" % ((new_total_requests - 1 - previous_sample['total_requests'].to_i) / sample_duration.to_f)
else
output = {}
end
# Write back to tmpfile
new_tmp_data = {'total_requests' => new_total_requests, 'updated_at' => Time.now.to_i}
File.open(TMPFILE, 'w') { |f| f.puts(new_tmp_data.to_json)}
puts "requests_per_second.value #{output['requests_per_second']}"
rescue Exception => e
puts "Exception: #{e.message}"
exit -1
end

289
plugins/apache/apache_status Executable file
View File

@ -0,0 +1,289 @@
#!/usr/bin/env perl
# -*- cperl -*-
=head1 NAME
apache_status - Munin multigraph plugin to monitor Apache statistics.
=head1 NOTES
This plugin will produce multiple graphs showing:
- the number of accesses to Apache servers;
- the number of apache processes running on the machine;
- the volume of data sent from Apache servers;
- the average requests per second to Apache servers.
=head1 APPLICABLE SYSTEMS
Apache HTTP servers with C</server-status> enabled.
=head1 CONFIGURATION
The plugin needs access to http://localhost/server-status?auto (or
modify the URL for another host). See your Apache documentation on
how to set up this URL in your httpd.conf. Apache needs ExtendedStatus
enabled for this plugin to work.
Tip: To see if it's already set up correctly, just run this plugin
with the parameter "autoconf". If you get a "yes", everything should
work like a charm already.
This configuration section shows the defaults of the plugin:
[apache_status]
env.url http://127.0.0.1:%d/server-status?auto
env.ports 80
The %d in the url will be replaced with the port. The default port is
80 as shown.
The port list is a space separated list of ports. NOTE that one
single Apache can have several open ports, and the plugin needs only
to contact one to get the servers global status. The list of ports is
only needed if you have several B<different> Apaches configured on
your host.
If you need authenticated access to the URL you can specify the
username and password in the URL. For example:
[apache_status]
env.url http://munin:spamalot@localhost/server-status?auto
This will provide for HTTP basic authentication.
=head1 INTERPRETATION
=head2 APACHE ACCESES
The graph shows the number of accesses (pages and other items served)
globally on the Apache server.
=head2 APACHE PROCESSES
The graph shows the number of Apache processes running on the
machine, and in addition separate "busy" and "idle" servers count.
If there is a flat ceiling effect on the graph where the number of
servers does not increase any more, in spite of no idle servers, then
the server has probably reached its C<MaxClients> setting. In this
case it's very likely that some clients are getting connection refused
or some other problem when connecting to your server. In this case
increase the C<MaxClients> setting. Unless there is also no more free
memory.
=head2 APACHE VOLUME
The graph shows the Apache HTTP servers global data volume in
bytes. I.e. how many bytes the server has served.
If there is a flat ceiling effect on the graph you may have reached
some kind of bandwidth limit on your outgoing connection.
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf
=head1 BUGS
Does not support digest authentication.
=head1 AUTHOR
Rewritten by Diego Elio Pettenò <flameeyes@flameeyes.eu> based upon
original apache_accesses, apache_processes and apache_volume plugins
of unknown origin.
=head1 LICENSE
GPLv2
=cut
use strict;
use warnings;
use Munin::Plugin;
my $ret = undef;
if (! eval "require LWP::UserAgent;") {
$ret = "LWP::UserAgent not found";
if ( ! defined $ARGV[0] ) {
die $ret;
}
}
my $URL = exists $ENV{'url'} ? $ENV{'url'} : "http://127.0.0.1:%d/server-status?auto";
my @PORTS = exists $ENV{'ports'} ? split(' ', $ENV{'ports'}) : (80);
my $UA = LWP::UserAgent->new(timeout => 30,
agent => sprintf("munin/%s (libwww-perl/%s)", $Munin::Common::Defaults::MUNIN_VERSION, $LWP::VERSION));
if ( defined $ARGV[0] and $ARGV[0] eq "autoconf" ) {
if ($ret) {
print "no ($ret)\n";
exit 0;
}
foreach my $port (@PORTS) {
my $url = sprintf $URL, $port;
my $response = $UA->request(HTTP::Request->new('GET',$url));
if ($response->is_success) {
if ($response->content =~ /^Total Accesses:/im ) {
next;
} else {
print "no (ExtendedStatus option for apache"
. " mod_status is missing on port $port)\n";
exit 0;
}
} elsif ($response->code == 404) {
print "no (apache server-status not found. check if mod_status is enabled)\n";
exit 0;
} else {
print "no (Port $port: ". $response->message .")\n";
exit 0;
}
}
print "yes\n";
exit 0;
}
if ( defined $ARGV[0] and $ARGV[0] eq "config" ) {
print <<END;
multigraph apache_accesses
graph_title Apache accesses
graph_args --base 1000 -l 0
graph_vlabel accesses / \${graph_period}
graph_category apache
END
foreach my $port (@PORTS) {
print <<END;
accesses$port.label port $port
accesses$port.type DERIVE
accesses$port.info The number of accesses (pages and other items served) globally on the Apache server
END
print_thresholds("accesses$port");
}
print <<END;
multigraph apache_processes
graph_title Apache processes
graph_args --base 1000 -l 0
graph_vlabel processes
graph_total total
graph_category apache
END
print "graph_order ";
foreach my $port (@PORTS) {
print "busy$port idle$port free$port ";
}
print "\n";
foreach my $port (@PORTS) {
print <<END;
busy$port.label busy servers on port $port
busy$port.draw LINE2
idle$port.label idle servers on port $port
idle$port.draw STACK
free$port.label free slots on port $port
free$port.draw STACK
END
print_thresholds("busy$port");
print_thresholds("idle$port");
print_thresholds("free$port");
}
print <<END;
multigraph apache_volume
graph_title Apache volume
graph_args --base 1024 -l 0
graph_vlabel bytes per \${graph_period}
graph_category apache
END
foreach my $port (@PORTS) {
print <<END;
volume$port.cdef volume$port,1024,*
volume$port.label port $port
volume$port.type DERIVE
END
print_thresholds("volume$port");
}
print <<END;
multigraph apache_average_requests
graph_title Average Apache requests per second
graph_args --base 1000 -l 0
graph_vlabel average reqs/sec
graph_category apache
END
foreach my $port (@PORTS) {
print <<END;
average$port.label port $port
END
}
exit 0;
}
my %multigraphs = (
accesses => "multigraph apache_accesses\n",
processes => "multigraph apache_processes\n",
volume => "multigraph apache_volume\n",
average => "multigraph apache_average_requests\n"
);
foreach my $port (@PORTS) {
my $url = sprintf $URL, $port;
my $response = $UA->request(HTTP::Request->new('GET',$url));
if ($response->content =~ /^Total Accesses:\s+(.+)$/im) {
$multigraphs{accesses} .= "accesses$port.value $1\n";
} else {
$multigraphs{accesses} .= "accesses$port.value U\n";
}
if ($response->content =~ /^Busy(?:Servers|Workers):\s+(.+)$/im) {
$multigraphs{processes} .= "busy$port.value $1\n";
} else {
$multigraphs{processes} .= "busy$port.value U\n";
}
if ($response->content =~ /^Idle(?:Servers|Workers):\s+(.+)$/im) {
$multigraphs{processes} .= "idle$port.value $1\n";
} else {
$multigraphs{processes} .= "idle$port.value U\n";
}
if ($response->content =~ /^(Scoreboard: .*)$/m) {
my $count = () = $1 =~ /\./g;
$multigraphs{processes} .= "free$port.value $count\n";
} else {
$multigraphs{processes} .= "free$port.value U\n";
}
if ($response->content =~ /^Total kBytes:\s+(.+)$/im) {
$multigraphs{volume} .= "volume$port.value $1\n";
} else {
$multigraphs{volume} .= "volume$port.value U\n";
}
if ($response->content =~ /^ReqPerSec:\s+(.+)$/im) {
$multigraphs{average} .= "average$port.value $1\n";
} else {
$multigraphs{average} .= "average$port.value U\n";
}
}
foreach my $graph (keys %multigraphs) {
print $multigraphs{$graph};
}
# vim:syntax=perl