#!/usr/bin/perl -w
###
# Project: pflogstats
# Module: pflogstats-common-profiling.pm
# Description: Profiling functions
# Copyright: Dr. Peter Bieringer <pbieringer at aerasec dot de>
# AERAsec GmbH <http://www.aerasec.de/>
# License: GNU GPL v2
# CVS: $Id: pflogstats-common-profiling.pm,v 1.5 2003/05/22 14:02:23 rootadm Exp $
###
###
# ChangeLog:
# 0.01
# - initial split-off from common-support
# 0.02
# - make printing of profiling information optional
# 0.03
# - make Perl 5.0 compatible
###
## Todo:
# - correct module function export
##
use strict;
use Proc::ProcessTable; # required by "memusage"
package pflogstats::common::profiling;
## Local constants
my $module_type = "common";
my $module_name = $module_type . "-profiling";
my $module_version = "0.03";
## Export module info
$main::moduleinfo{$module_name}->{'version'} = $module_version;
$main::moduleinfo{$module_name}->{'type'} = $module_type;
$main::moduleinfo{$module_name}->{'name'} = $module_name;
## Global prototyping
## Local prototyping
## Global variables
## Register options
$main::options{'enable-profiling'} = \$main::opts{'enable-profiling'};
## Register calling hooks
$main::hooks{'loop_beforestart'}->{$module_name} = \&loop_beforestart;
$main::hooks{'loop_afterfinish'}->{$module_name} = \&loop_afterfinish;
$main::hooks{'final_end'}->{$module_name} = \&loop_finalend;
$main::hooks{'early_begin'}->{$module_name} = \&loop_earlybegin;
$main::hooks{'help'}->{$module_name} = \&help;
## Local variables
my %statistics;
## Global callable functions
# Help
sub help() {
my $helpstring = "
[--enable-profiling] Enable profiling
";
return $helpstring;
}
# Early begin
sub loop_earlybegin() {
my ($user,$system,$cuser,$csystem) = times;
$statistics{'program'}->{'start'}->{'time'}->{'user'} = $user;
$statistics{'program'}->{'start'}->{'time'}->{'system'} = $system;
my ($mem, $mempercent) = &memusage();
$statistics{'program'}->{'start'}->{'memory'}->{'absolut'} = $mem;
$statistics{'program'}->{'start'}->{'memory'}->{'relative'} = $mempercent;
};
# Before loop starts
sub loop_beforestart() {
my ($user,$system,$cuser,$csystem) = times;
$statistics{'loop'}->{'start'}->{'time'}->{'user'} = $user;
$statistics{'loop'}->{'start'}->{'time'}->{'system'} = $system;
my ($mem, $mempercent) = &memusage();
$statistics{'loop'}->{'start'}->{'memory'}->{'absolut'} = $mem;
$statistics{'loop'}->{'start'}->{'memory'}->{'relative'} = $mempercent;
};
# After loop ends
sub loop_afterfinish() {
my ($user,$system,$cuser,$csystem) = times;
$statistics{'loop'}->{'finish'}->{'time'}->{'user'} = $user;
$statistics{'loop'}->{'finish'}->{'time'}->{'system'} = $system;
my ($mem, $mempercent) = &memusage();
$statistics{'loop'}->{'finish'}->{'memory'}->{'absolut'} = $mem;
$statistics{'loop'}->{'finish'}->{'memory'}->{'relative'} = $mempercent;
};
# Final end
sub loop_finalend() {
my ($user,$system,$cuser,$csystem) = times;
$statistics{'program'}->{'finish'}->{'time'}->{'user'} = $user;
$statistics{'program'}->{'finish'}->{'time'}->{'system'} = $system;
my ($mem, $mempercent) = &memusage();
$statistics{'program'}->{'finish'}->{'memory'}->{'absolut'} = $mem;
$statistics{'program'}->{'finish'}->{'memory'}->{'relative'} = $mempercent;
if (defined $main::opts{'enable-profiling'} ) {
&print_statistics();
};
};
sub print_statistics() {
# Print statistics
print "\n";
print '#'x75 . "\n";
printf "# Timing statistics\n";
printf "# Complete user time : %8.2f sec (%5.2f min)\n", $statistics{'program'}->{'finish'}->{'time'}->{'user'}, $statistics{'program'}->{'finish'}->{'time'}->{'user'} / 60;
printf "# Complete system time : %8.2f sec (%5.2f min)\n", $statistics{'program'}->{'finish'}->{'time'}->{'system'}, $statistics{'program'}->{'finish'}->{'time'}->{'system'} / 60;
printf "# Complete time : %8.2f sec (%5.2f min)\n", $statistics{'program'}->{'finish'}->{'time'}->{'user'} + $statistics{'program'}->{'finish'}->{'time'}->{'system'}, ($statistics{'program'}->{'finish'}->{'time'}->{'user'} + $statistics{'program'}->{'finish'}->{'time'}->{'system'}) / 60;
printf "# Parser loop user time : %8.2f sec (%5.2f min)\n", $statistics{'loop'}->{'finish'}->{'time'}->{'user'} - $statistics{'loop'}->{'start'}->{'time'}->{'user'}, ($statistics{'loop'}->{'finish'}->{'time'}->{'user'} - $statistics{'loop'}->{'start'}->{'time'}->{'user'}) / 60;
printf "# Parser loop system time : %8.2f sec (%5.2f min)\n", $statistics{'loop'}->{'finish'}->{'time'}->{'system'} - $statistics{'loop'}->{'start'}->{'time'}->{'system'}, ($statistics{'loop'}->{'finish'}->{'time'}->{'system'} - $statistics{'loop'}->{'start'}->{'time'}->{'system'}) / 60;
printf "# Parser loop time : %8.2f sec (%5.2f min)\n", $statistics{'loop'}->{'finish'}->{'time'}->{'user'} + $statistics{'loop'}->{'finish'}->{'time'}->{'system'} - $statistics{'loop'}->{'start'}->{'time'}->{'user'} + $statistics{'loop'}->{'start'}->{'time'}->{'system'}, ($statistics{'loop'}->{'finish'}->{'time'}->{'user'} + $statistics{'loop'}->{'finish'}->{'time'}->{'system'} - $statistics{'loop'}->{'start'}->{'time'}->{'user'} + $statistics{'loop'}->{'start'}->{'time'}->{'system'}) / 60;
print "#\n";
printf "# Memory statistics\n";
printf "# On start : %8.3f MByte (%2d %%)\n", $statistics{'program'}->{'start'}->{'memory'}->{'absolut'} / 1048756, $statistics{'program'}->{'start'}->{'memory'}->{'relative'};
printf "# Before parser loop starts : %8.3f MByte (%2d %%)\n", $statistics{'loop'}->{'start'}->{'memory'}->{'absolut'} / 1048756, $statistics{'loop'}->{'start'}->{'memory'}->{'relative'};
printf "# After parser loop ends : %8.3f MByte (%2d %%)\n", $statistics{'loop'}->{'finish'}->{'memory'}->{'absolut'} / 1048756, $statistics{'loop'}->{'finish'}->{'memory'}->{'relative'};
printf "# Loop difference : %8.3f MByte (%2d %%)\n", $statistics{'loop'}->{'finish'}->{'memory'}->{'absolut'} / 1048756 - $statistics{'loop'}->{'start'}->{'memory'}->{'absolut'} / 1048756, $statistics{'loop'}->{'finish'}->{'memory'}->{'relative'} - $statistics{'loop'}->{'start'}->{'memory'}->{'relative'};
printf "# Before program ends : %8.3f MByte (%2d %%)\n", $statistics{'program'}->{'finish'}->{'memory'}->{'absolut'} / 1048756, $statistics{'program'}->{'finish'}->{'memory'}->{'relative'};
printf "# Data memory : %8.3f MByte (%2d %%)\n", ($statistics{'program'}->{'finish'}->{'memory'}->{'absolut'} - $statistics{'program'}->{'start'}->{'memory'}->{'absolut'}) / 1048756, $statistics{'program'}->{'finish'}->{'memory'}->{'relative'} - $statistics{'program'}->{'start'}->{'memory'}->{'relative'};
print "#\n";
printf "# UserTime * DataMemory : %8.0f MByte*sec\n", ($statistics{'program'}->{'finish'}->{'memory'}->{'absolut'} - $statistics{'program'}->{'start'}->{'memory'}->{'absolut'}) / 1048756 * $statistics{'program'}->{'finish'}->{'time'}->{'user'};
print '#'x75 . "\n";
print "\n";
};
## Get memory usage
# Code taken from: http://archive.develooper.com/perl-crypto@perl.org/msg00036.html
# hopefully GPL'ed...
# memusage subroutine
# usage: memusage [processid]
# this subroutine takes only one parameter, the process id for
# which memory usage information is to be returned. If
# undefined, the current process id is assumed.
# Returns array of two values, raw process memory size and
# percentage memory utilisation, in this order. Returns
# undefined if these values cannot be determined.
sub memusage(;$) {
my @results;
my $pid = (defined($_[0])) ? $_[0] : $$;
my $proc = Proc::ProcessTable->new;
my %fields = map { $_ => 1 } $proc->fields;
return undef unless exists $fields{'pid'};
foreach (@{$proc->table}) {
if ($_->pid eq $pid) {
push (@results, $_->size) if exists $fields{'size'};
push (@results, $_->pctmem) if exists $fields{'pctmem'};
};
};
return @results;
};
## End of module
return 1;
syntax highlighted by Code2HTML, v. 0.9.1