/usr/local/CPAN/Apache2-Instrument/Apache2/Instrument/Strace.pm
package Apache2::Instrument::Strace;
use strict;
our $VERSION = '0.01';
use base qw(Apache2::Instrument);
use Apache2::Const qw(OK);
use constant STRACE => "/usr/bin/strace";
sub before {
my ($class, $r, $notes) = @_;
my $pid = $$;
my $cmd = STRACE;
my @args = ("-c", "-p", $pid);
my $strace = open(my $out_fh, "$cmd @args 2>&1 |");
$notes->{out} = $out_fh;
$notes->{pid} = $strace;
return OK;
}
sub after {
my ($class, $r, $notes) = @_;
kill INT => $notes->{pid};
return OK;
}
sub report {
my ($class, $r, $notes) = @_;
my $out = $notes->{out};
my @info;
my %syscalls;
while (<$out>) {
#% time seconds usecs/call calls errors syscall
if (/([0-9\.]+)\s+([0-9.]+)\s+(\d+)\s+(\d+)\s+((\d+)\s+)?(\S+)/) {
my ($time, $seconds, $usecs_call, $calls, $errors, $syscall) = ($1, $2, $3, $4, $6, $7);
next if $syscall eq 'total';
$syscalls{$syscall} = {
# name => $syscall,
time => $time,
seconds => $seconds,
usecs_call => $usecs_call,
calls => $calls,
$errors ? ( errors => $errors ) : (),
};
}
}
my @info = map { {$_ => $syscalls{$_}}}
sort { $syscalls{$b}{time} <=> $syscalls{$a}{time} ||
$syscalls{$b}{seconds} <=> $syscalls{$a}{seconds} ||
$syscalls{$b}{calls} <=> $syscalls{$a}{calls} }
keys %syscalls;
return \@info;
}