2012-04-04 11:33:39 +02:00
|
|
|
#!/usr/bin/perl
|
|
|
|
|
|
|
|
=head1
|
|
|
|
|
|
|
|
# Log vhost port method response_bytes response_time status
|
|
|
|
<IfModule mod_log_config.c>
|
|
|
|
CustomLog "|/usr/share/munin/apache_pipelogger" "%v %p %m %B %D %s"
|
|
|
|
</IfModule>
|
|
|
|
|
|
|
|
=cut
|
|
|
|
# write every n seconds to shared memory
|
|
|
|
local $nsec=7;
|
|
|
|
local $debug=undef;
|
|
|
|
|
|
|
|
use Storable qw(freeze thaw);
|
|
|
|
use List::Util qw(min max);
|
|
|
|
use IPC::ShareLite ':lock';
|
|
|
|
require Data::Dumper if $debug;
|
|
|
|
use Munin::Plugin;
|
|
|
|
|
|
|
|
|
|
|
|
local $share = IPC::ShareLite->new(
|
|
|
|
-key => 'mapl',
|
|
|
|
-create => 1,
|
|
|
|
-destroy => 1,
|
|
|
|
-exclusive => 0,
|
|
|
|
-mode => '0666'
|
|
|
|
) or die $!;
|
|
|
|
|
|
|
|
|
|
|
|
local $SIG{'ALRM'}=\&periodic_write;
|
|
|
|
alarm $nsec;
|
|
|
|
|
|
|
|
|
|
|
|
# drop stored data on reload
|
|
|
|
local %temp=();
|
|
|
|
|
|
|
|
while (<STDIN>) {
|
|
|
|
my ($vhost,$port,$method,$bytes,$time,$status)=split(/\s/,$_);
|
|
|
|
|
|
|
|
# sanity check
|
2012-08-17 17:26:11 +02:00
|
|
|
next unless m/^([\d\w\.\-_]+\s){5}([\d\w\.\-_]+$)/; # escaped "." and "-"
|
2012-04-04 11:33:39 +02:00
|
|
|
|
|
|
|
# sitename to munin fieldname
|
|
|
|
my $vpm=clean_fieldname($vhost);
|
|
|
|
$temp{$vpm}{'label'}=$vhost;
|
|
|
|
$temp{$vpm}{'label'}=~s/www\.//;
|
|
|
|
|
|
|
|
# count all requests
|
|
|
|
$temp{$vpm}{'requests'}++;
|
|
|
|
|
|
|
|
if ($bytes) {
|
|
|
|
$bytes=~s/-/0/;
|
|
|
|
# bytes transmitted
|
|
|
|
$temp{$vpm}{'bytes'}+=$bytes;
|
|
|
|
|
|
|
|
# max bytes
|
|
|
|
$temp{$vpm}{'max_bytes'}=max($temp{$vpm}{'max_bytes'},$bytes);
|
|
|
|
|
|
|
|
# average bytes
|
|
|
|
$temp{$vpm}{'avg_bytes'}=$temp{$vpm}{'bytes'}/$temp{$vpm}{'requests'} || 0 if ($bytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
# count by status / error code
|
|
|
|
$temp{$vpm}{"status"}{$status}++ if $status;
|
|
|
|
|
|
|
|
if ($time) {
|
|
|
|
# min/max execution time
|
|
|
|
$temp{$vpm}{'max_time'}=max($temp{$vpm}{'max_time'},$time);
|
|
|
|
|
|
|
|
# cumulative and average execution time
|
|
|
|
$temp{$vpm}{'cml_time'}+=$time;
|
|
|
|
|
|
|
|
# average time
|
|
|
|
$temp{$vpm}{'avg_time'}=$temp{$vpm}{'cml_time'}/$temp{$vpm}{'requests'} || 0 if ($time);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
sub periodic_write {
|
|
|
|
# begin transaction
|
|
|
|
$share->lock(LOCK_EX);
|
|
|
|
|
|
|
|
# get data (may be updated by other loggers too)
|
2012-08-17 17:26:11 +02:00
|
|
|
my %old=eval{%{thaw($share->fetch)}}; # using eval to suppress thaw error on empty string at the first run
|
2012-04-04 11:33:39 +02:00
|
|
|
|
|
|
|
foreach my $vpm (keys %temp){
|
|
|
|
# merge values
|
|
|
|
$old{$vpm}{'bytes'}+=$temp{$vpm}{'bytes'} if $temp{$vpm}{'bytes'};
|
|
|
|
$old{$vpm}{'requests'}+=$temp{$vpm}{'requests'} if $temp{$vpm}{'requests'};
|
|
|
|
$old{$vpm}{'time'}+=$temp{$vpm}{'time'} if $temp{$vpm}{'time'};
|
|
|
|
$old{$vpm}{'label'}=$temp{$vpm}{'label'};
|
2014-11-23 01:53:50 +01:00
|
|
|
$old{$vpm}{'avg_time'}=sprintf("%d",(($old{$vpm}{'avg_time'}+$temp{$vpm}{'avg_time'})/2)/1000);
|
|
|
|
$old{$vpm}{'max_time'}=max($old{$vpm}{'max_time'},$temp{$vpm}{'max_time'})/1000;
|
2012-04-04 11:33:39 +02:00
|
|
|
$old{$vpm}{'max_bytes'}=max($temp{$vpm}{'max_bytes'},$temp{$vpm}{'max_bytes'});
|
|
|
|
$old{$vpm}{'avg_bytes'}=sprintf("%d",($old{$vpm}{'avg_bytes'}+$temp{$vpm}{'avg_bytes'})/2);
|
|
|
|
|
|
|
|
# reset local counters
|
|
|
|
foreach my $check qw(requests bytes time cml_time max_bytes avg_bytes max_time avg_time) {
|
|
|
|
$temp{$vpm}{$check}=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
# reset status counts
|
|
|
|
foreach my $val (keys %{$temp{$vpm}{'status'}}) {
|
|
|
|
$old{$vpm}{'status'}{$val}+=$temp{$vpm}{'status'}{$val};
|
|
|
|
$temp{$vpm}{'status'}{$val}=0;
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
# save to shm
|
|
|
|
# print Data::Dumper::Dumper(%old) if $debug;
|
|
|
|
$share->store( freeze \%old );
|
|
|
|
|
|
|
|
# end transaction
|
|
|
|
$share->unlock;
|
|
|
|
|
|
|
|
# parse/write every n seconds
|
|
|
|
alarm $nsec;
|
2012-08-17 17:26:11 +02:00
|
|
|
}
|