Changeset 261


Ignore:
Timestamp:
Nov 12, 2009, 10:06:30 PM (11 years ago)
Author:
zerodeux
Message:

Refactored code into functions + awful -t bugfix, was 5x too much

Location:
phptop
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • phptop/NEWS

    r260 r261  
     1phptop 0.3 - unreleased
     2
     3    * Fixed an awful bug about timespan being 5x than necessary (forgot debug code)
     4    * Refactored code with functions and less globals
     5
    16phptop 0.2.2 - 2009-11-06
    27
  • phptop/phptop

    r260 r261  
    2626
    2727my $package_name    = 'phptop';
    28 my $package_version = '0.2.2';
     28my $package_version = '0.3-dev';
    2929my $package_owner   = 'Copyright (C) 2009 Bearstech - http://bearstech.com/';
    3030my $package_url     = 'http://forge.bearstech.com/trac/wiki/PhpTop';
    3131
    32 
     32# Options
    3333my $help;
    3434my $version;
     
    3636my $full_query;
    3737my $count = 10;
    38 my $sortkey = 'hit';
     38my $sortkeys = 'hit';
    3939my $span = 60;
    4040my $path_only;
     41
     42# Globals
     43my @keys = qw/hit time user sys mem mem_max inc inc_max/;
     44my %stat;
     45my $now   = time();
     46my $hits  = 0;
     47my $bogus = 0;
    4148
    4249
     
    5562
    5663Options:
    57   -c, --count N    Limit output to top N URIs (default is $count)
    58   -f, --full-query Consider full URI with CGI parameters
    59   -h, --help       Display this information
    60   -l, --log path   Logfiles to parse, you may use several -l and wildcards
    61   -p, --path-only  Only print path, skip http://host
    62   -s, --sort key   Sort key: hit, time, user, sys, mem or inc (default is $sortkey)
    63   -t, --time N     Consider log events from now back to N minutes (default is $span)
    64   -v, --version    Display version number and copyright info
     64  -c, --count N        Limit output to top N URIs (default is $count)
     65  -f, --full-query     Consider full URI with CGI parameters
     66  -h, --help           Display this information
     67  -l, --log path       Logfiles to parse, you may use several -l and wildcards
     68  -p, --path-only      Only print path, skip http://host
     69  -s, --sort key,...   Sort key: hit, time, user, sys, mem or inc (default is $sortkeys)
     70  -t, --time N         Consider log events from now back to N minutes (default is $span)
     71  -v, --version        Display version number and copyright info
    6572
    6673Columns explanation:
     
    8289}
    8390
    84 
    85 GetOptions(
    86     'c|count=i'      => \$count,
    87     'f|full-query'   => \$full_query,
    88     'h|help'         => \$help,
    89     'l|log=s'        => \@log,
    90     'p|path'         => \$path_only,
    91     's|sort=s'       => \$sortkey,
    92     't|time=s'       => \$span,
    93     'v|version'      => \$version,
    94 )
    95 or print_short_help();
    96 
    97 print_help() if $help;
    98 print_version() if $version;
    99 
    100 my @logfiles;
    101 push(@log, '/var/log/apache2/error*log', '/var/log/apache2/*/error*log') if !@log;
    102 map { push(@logfiles, glob($_)) } @log;
    103 
    104 my $now = time();
    105 $span *= 5;
    106 POSIX::setlocale(POSIX::LC_ALL, 'C'); # Use . as decimal separator
    107 
    108 my %stat;
    109 my $lognb = 0;
    110 my $hits  = 0;
    111 my $bogus = 0;
    112 foreach (@logfiles) {
     91sub parse_log {
     92    my $logfile = shift;
     93
    11394    my $lh;
    114     if (!open($lh, "<$_")) {
    115         warn "$_: $!";
    116         next;
    117     }
    118     $lognb++;
     95    if (!open($lh, "<$logfile")) {
     96        warn "$logfile: $!";
     97        return 0;
     98    }
    11999
    120100  LINE:
     
    167147
    168148    close($lh);
    169 }
    170 
    171 if ($lognb == 0) {
    172     print STDERR "Error: no log files found. Path/globs tried: ".join(", ", @log)."\n";
     149    1;
     150}
     151
     152sub fix_stat {
     153    # Convert memory and include values from total to 'per hit', more useful and meaningful
     154    while (my ($url, $i) = each %stat) {
     155        $i->{'mem_max'} /= 2**20;  # Also scale memory values from bytes to MB
     156        $i->{'mem'} /= $i->{'hit'} * 2**20;
     157        $i->{'inc'} /= $i->{'hit'};
     158    }
     159}
     160
     161sub text_report {
     162    my $sortkey = shift;
     163
     164    # Sort queries according to $sortkey (they are all numeric)
     165    my @sorted = sort { $stat{$b}{$sortkey} - $stat{$a}{$sortkey} } keys %stat;
     166   
     167    # Compute URI column width
     168    my $width = 0;
     169    my $n = 0;
     170    foreach (@sorted) {
     171        last if $n++ >= $count;
     172        my $w = length($_);
     173        $width = $w if $w > $width;
     174    }
     175   
     176    my %total;
     177    my @tkeys = qw/hit time user sys/;
     178    $n = 0;
     179   
     180    printf("%-${width}s %s\n", "", join(' ', map { sprintf('%8s', ucfirst($_ =~ /^(mem|inc)$/ ? "$_/hit" : $_)) } @keys));
     181    foreach (@sorted) {
     182        my $s = $stat{$_};
     183        $total{$_} += $s->{$_} foreach @tkeys;
     184        next if $n++ >= $count; # Continue to loop and only sum totals if $count records have been displayed
     185   
     186        printf("%-${width}s", $_);
     187        printf($_ =~ m/hit|inc/ ? ' %8d' : ' %8.1f', $s->{$_}) foreach @keys;
     188        print "\n";
     189    }
     190    printf("\n%-${width}s", 'Total');
     191    printf($_ =~ m/hit/ ? ' %8d' : ' %8.1f', $total{$_}) foreach @tkeys;
     192    print "\n";
     193}
     194
     195
     196GetOptions(
     197    'c|count=i'      => \$count,
     198    'f|full-query'   => \$full_query,
     199    'h|help'         => \$help,
     200    'l|log=s'        => \@log,
     201    'p|path'         => \$path_only,
     202    's|sort=s'       => \$sortkeys,
     203    't|time=s'       => \$span,
     204    'v|version'      => \$version,
     205)
     206or print_short_help();
     207
     208print_help() if $help;
     209print_version() if $version;
     210
     211POSIX::setlocale(POSIX::LC_ALL, 'C'); # Use . as decimal separator
     212
     213my @logfiles;
     214push(@log, '/var/log/apache2/error*log', '/var/log/apache2/*/error*log') if !@log;
     215map { push(@logfiles, glob($_)) } @log;
     216
     217my $parsed = 0;
     218$parsed += parse_log($_) foreach @logfiles;
     219
     220if ($parsed == 0) {
     221    print STDERR "Error: no log files found/processed. Tried: ".join(", ", @log)."\n";
    173222    exit 2;
    174223}
     
    181230}
    182231
    183 # Convert memory and include values from total to 'per hit', more useful and meaningful
    184 while (my ($url, $i) = each %stat) {
    185     $i->{'mem_max'} /= 2**20;  # Also scale memory values from bytes to MB
    186     $i->{'mem'} /= $i->{'hit'} * 2**20;
    187     $i->{'inc'} /= $i->{'hit'};
    188 }
    189 
    190 # Sort queries according to $sortkey (they are all numeric)
    191 my @keys = qw/hit time user sys mem mem_max inc inc_max/;
    192 my @sorted = sort { $stat{$b}{$sortkey} - $stat{$a}{$sortkey} } keys %stat;
    193 
    194 # Compute URI column width
    195 my $width = 0;
    196 my $n = 0;
    197 foreach (@sorted) {
    198     last if $n++ >= $count;
    199     my $w = length($_);
    200     $width = $w if $w > $width;
    201 }
    202 
    203 my %total;
    204 my @tkeys = qw/hit time user sys/;
    205 $n = 0;
    206 
    207 printf("%-${width}s %s\n", "", join(' ', map { sprintf('%8s', ucfirst($_ =~ /^(mem|inc)$/ ? "$_/hit" : $_)) } @keys));
    208 foreach (@sorted) {
    209     my $s = $stat{$_};
    210     $total{$_} += $s->{$_} foreach @tkeys;
    211     next if $n++ >= $count; # Continue to loop and only sum totals if $count records have been displayed
    212 
    213     printf("%-${width}s", $_);
    214     printf($_ =~ m/hit|inc/ ? ' %8d' : ' %8.1f', $s->{$_}) foreach @keys;
    215     print "\n";
    216 }
    217 printf("\n%-${width}s", 'Total');
    218 printf($_ =~ m/hit/ ? ' %8d' : ' %8.1f', $total{$_}) foreach @tkeys;
    219 print "\n";
     232fix_stat();
     233
     234my @sortkeyl = split(/,/, $sortkeys);
     235text_report($_) foreach @sortkeyl;
Note: See TracChangeset for help on using the changeset viewer.