Changeset 364


Ignore:
Timestamp:
Mar 18, 2010, 11:18:41 AM (11 years ago)
Author:
zerodeux
Message:

Refactored reporting and text output, ready for HTML output

Location:
phptop
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • phptop/NEWS

    r363 r364  
    11phptop 0.5 - Unreleased
    22
     3    * New -o|--output-mode option, refactored reporting internally
    34    * Showing sorting column with '>' on text output
    45    * Now checking that -t <value> is numeric
     6    * Now checking that -s <key> uses a known key
     7    * Changes -s usage: now using multiple -s instead comma-list
    58    * Fixed sorting which was not reliable (use proper <=> numeric comparison
    69      operator)
  • phptop/phptop

    r363 r364  
    3838my $full_query;
    3939my $count = 10;
    40 my $sortkeys = 'hit';
     40my @sortkeys;
    4141my $span = 10;
    4242my $path_only;
     43my $output = 'text';
    4344
    4445# Globals
     
    4950my $bogus = 0;
    5051
    51 
    5252sub print_short_help {
    5353    print STDERR <<EOF;
     
    6868  -h, --help           Display this information
    6969  -l, --log path       Logfiles to parse, you may use several -l and wildcards
     70  -o, --output mode    Output mode: text or html (default is $output);
    7071  -p, --path-only      Only print path, skip http://host
    71   -s, --sort key,...   Sort key: hit, time, user, sys, mem or inc (default is $sortkeys)
     72  -s, --sort key       Sort key: hit, time, user, sys, mem or inc (default is @sortkeys)
    7273  -t, --time N         Consider log events from now back to N minutes (default is $span)
    7374  -v, --version        Display version number and copyright info
     75
     76The -s option can be used multiple times to generate several reports in one go.
    7477
    7578Columns explanation:
     
    185188}
    186189
     190sub raw_report {
     191    my $sortkey = shift;
     192
     193    my @headers = map {
     194        my $h = $_;
     195        $h = "$h/hit" if /^(mem|inc)$/;  # Mem and Inc are per-hit values
     196        ucfirst $h;
     197    } @keys;
     198    unshift(@headers, 'URL');
     199
     200    my @sumkeys = qw/hit time user sys/;  # We compute totals for these keys
     201
     202    # Sort queries according to $sortkey (they are all numeric)
     203    my @rows;
     204    my %sum;
     205    foreach my $url (sort { $stat{$b}{$sortkey} <=> $stat{$a}{$sortkey} } keys %stat) {
     206        my $s = $stat{$url};
     207        $sum{$_} += $s->{$_} foreach @sumkeys;
     208
     209        # Continue to loop and only sum totals even if $count records have been rendered
     210        next if @rows >= $count;
     211
     212        my @cells = map { sprintf($_ =~ m/hit|inc/ ? '%d' : '%.1f', $s->{$_}) } @keys;
     213        push(@rows, [ $url, @cells]);
     214    }
     215
     216    my @sums = map { defined $sum{$_} ? sprintf($_ =~ m/hit|inc/ ? '%d' : '%.1f', $sum{$_}) : '' } @keys;
     217    unshift(@sums, "Total (from last $span min)");
     218
     219    return { headers => \@headers, rows => \@rows, sums => \@sums };
     220}
     221
    187222sub text_report {
    188     my $sortkey = shift;
    189 
    190     my %total;
    191     my @tkeys = qw/hit time user sys/;
     223    # Compute all reports at first, we'll align all report columns
     224    my %reports;
     225    $reports{$_} = raw_report($_) foreach @sortkeys;
    192226
    193227    # Limit URL column width, depending on output available columns
     
    197231    die "Terminal width to short, try cheating with COLUMNS env var." if $colmax < 16;
    198232
    199     # Sort queries according to $sortkey (they are all numeric)
    200     my @sorted = sort { $stat{$b}{$sortkey} <=> $stat{$a}{$sortkey} } keys %stat;
    201  
    202233    # Compute URL column width
    203234    my $width = 0;
    204     my $n = 0;
    205     foreach (@sorted) {
    206         last if $n++ >= $count;
    207         my $w = length($_);
    208         $width = $w if $w > $width;
     235    foreach my $r (values %reports) {
     236        foreach (@{$r->{rows}}) {
     237            my $w = length($_->[0]);
     238            $width = $w if $w > $width;
     239        }
    209240    }
    210241    $width = $colmax if $width > $colmax;
    211242
    212     # Header
    213     my @headers = map {
    214         my $h = $_;
    215         $h = "$h/hit" if /^(mem|inc)$/;  # Mem and Inc are per-hit values
    216         $h = ucfirst $h;
    217         $h = ">$h" if $_ eq $sortkey;    # Use '>' to show sorting column
    218         sprintf('%8s', $h);
    219     } @keys;
    220     printf("%-${width}s %s\n", "", join(' ', @headers));
    221 
    222     # Rows
    223     $n = 0;
    224     foreach my $url (@sorted) {
    225         my $s = $stat{$url};
    226         $total{$_} += $s->{$_} foreach @tkeys;
    227         next if $n++ >= $count; # Continue to loop and only sum totals if $count records have been displayed
    228  
    229         my $ul = length($url);
    230         if ($ul > $width) {
    231             $url = substr($url, 0, $width - 3).'...';
     243    my $report_nb = 0;
     244    foreach my $key (@sortkeys) {
     245        my $r = $reports{$key};
     246
     247        # Table separator (starting from 2nd report)
     248        print "--\n" if $report_nb++;
     249   
     250        # Table header
     251        my $h = $r->{headers};
     252        map { $_ = ">$_" if /^$key(\/hit)?$/i } @$h;
     253        printf("%-${width}s %s\n", shift(@$h), join(' ', map { sprintf("%8s", $_) } @$h));
     254
     255        # Rows
     256        foreach my $cell (@{$r->{rows}}) {
     257            printf("%-${width}s %s\n", shift(@$cell), join(' ', map { sprintf("%8s", $_) } @$cell));
    232258        }
    233         my $row = sprintf("%-${width}s", $url);
    234         $row   .= sprintf($_ =~ m/hit|inc/ ? ' %8d' : ' %8.1f', $s->{$_}) foreach @keys;
    235         print "$row\n";
    236     }
    237 
    238     my $footer = sprintf("\n%-${width}s", "Total (from last $span min)");
    239     $footer   .= sprintf($_ =~ m/hit/ ? ' %8d' : ' %8.1f', $total{$_}) foreach @tkeys;
    240     print "$footer\n";
     259
     260        # Sums, totals
     261        my $f = $r->{sums};
     262        printf("%-${width}s %s\n", shift(@$f), join(' ', map { sprintf("%8s", $_) } @$f));
     263    }
     264}
     265
     266sub hmtl_report {
    241267}
    242268
     
    247273    'h|help'         => \$help,
    248274    'l|log=s'        => \@log,
     275    'o|output=s'     => \$output,
    249276    'p|path'         => \$path_only,
    250     's|sort=s'       => \$sortkeys,
     277    's|sort=s'       => \@sortkeys,
    251278    't|time=i'       => \$span,
    252279    'v|version'      => \$version,
     
    254281or print_short_help();
    255282
     283@sortkeys = ('hit') if not @sortkeys;
     284foreach my $k (@sortkeys) {
     285  next if grep { $_ eq $k } @keys;
     286  print STDERR "Unknown sort key '$k'.\n";
     287  exit 1;
     288}
     289
     290if (not $output =~ /^text|html$/) {
     291  print STDERR "Unknown output mode '$output'.\n";
     292  exit 1;
     293}
     294
    256295print_help() if $help;
    257296print_version() if $version;
     
    280319fix_stat();
    281320
    282 my @sortkeyl = split(/,/, $sortkeys);
    283 
    284 my $reportnb = 0;
    285 foreach (@sortkeyl) {
    286     print "--\n" if $reportnb++;
    287     text_report($_);
    288 }
     321text_report() if $output eq 'text';
     322html_report() if $output eq 'html';
Note: See TracChangeset for help on using the changeset viewer.