#!/usr/bin/perl -w # # DESCRIPTION: calamaris - statistic package for diverse Proxy-Cache-Servers # $VERSION = '2.99.4.5'; # # Copyright (C) 1997-2006, 2013, 2015 # Cord Beermann # # URL: http://Calamaris.Cord.de/ # Announcement-Mailing-list: send Mail with 'subscribe' in the Mail-Body to # Calamaris-announce-request@Cord.de # # AUTHORS: Cord Beermann # Michael Pophal # # Thanks to these contributors, bug reporters, and feature requesters: # John Heaton # Andreas Lamprecht # Kenny Ng # Claus Langhans # Andreas Jung # Ernst Heiri # Shamil R. Yahin # Thoralf Freitag # Marco Paganini # Michael Riedel # Kris Boulez # Mark Visser # Gary Palmer # Stefan Watermann # Roar Smith # Bernd Lienau # Gary Lindstrom # Jost Krieger # Gerd Michael Hoffmann # Gerold Meerkoetter # Iain Lea # Emmanuel Adeline # John Line # Christos Cheretakis # Ryan Donnelly # Richard Vaughan # Jonas Luster # Clare Lahiff # Toni Andjelkovic # Chris Teakle # Dancer Vesperman # Vincent ? # Elrond ? # Holger Marzen # Panagiotis Christias # Patrik Rak # Steve Snyder # Michael Copeland # Warren Brown # Andy Nik # Frank Roechter # Antonio Casado Rodríguez # Pavol Adamec # Ram Cherukuri # Marco Koch # Stephen Welker # Christian Niederdorfer # Klaus Brinkmeyer # Filip ? # Matt Hubbard # James Crocker # Enrico Ardizzoni # Shawn Switenky # Jarkko Saloranta # Jigar Rasalawala # Philipp Frauenfelder # Alexey Markov # Mark Güthling # Sergey Zarubin # Helge Oldach # Michael R. Schwarzbach # Radu - Eosif Mihailescu # Steffen Sledz # Kenytt Avery # SO Kwok Tsun # Chris Knight # ycdtosa ? # Peter W. Osel # Pawel Worach # Franck Bourdonnec # Chris Clemson # Scott Tregear # Sythos ? # Dmitriy # Daniel Echeverry # Laurent Licour # This program is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the Free # Software Foundation; either version 2 of the License, or (at your option) # any later version. # (If you modify and want to publish it under the name 'Calamaris', please ask # me. I don't want to confuse the 'audience' with many different versions of # the same name and/or Version number. (This is not part of the license, it # is only a favour i asked of you.)) # This program is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # more details. # You should have received a copy of the GNU General Public License along with # this program; if not, write to the Free Software Foundation, Inc., 59 Temple # Place - Suite 330, Boston, MA 02111-1307, USA. # A Perl script is "correct" if it gets the job done before your boss fires # you. # -- 'Programming Perl Second Edition' # by Larry Wall, Tom Christiansen & Randal L. Schwartz # If you have to remove this, read the README! require 5.002; # if you can't use Graphics, you should point this to a directory where calamaris/*.pm is located. use lib '/usr/share'; use Getopt::Long; use Sys::Hostname; Getopt::Long::Configure("bundling"); GetOptions( "all-useful-reports|a" => \$opt_a, "benchmark|b=i" => \$opt_b, "cache-input-file|i=s" => \$opt_i, "cache-output-file|o=s" => \$opt_o, "config-file=s" => \$opt_config_file, "copyright|C" => \$opt_C, "domain-report|d=i" => \$opt_d, "domain-report-limit=i" => \$opt_domain_report_limit, "domain-report-n-level|N=i" => \$opt_N, "dump-loop|L" => \$opt_L, "errorcode-distribution-report" => \$opt_errorcode_distribution, "generate-index" => \$opt_generate_index, "help|h" => \$opt_h, "hostname|H=s" => \$opt_H, "input-format|f=s" => \$opt_f, "image-type=s" => \$opt_image_type, "ipfilter-exclude=s" => \$opt_ipfilter_exclude, "ipfilter-include=s" => \$opt_ipfilter_include, "logo|l=s" => \$opt_l, "meta|M=s" => \$opt_M, "no-input|z" => \$opt_z, "output-file=s" => \$opt_output_file, "output-file-prefix=s" => \$opt_output_file_prefix, "output-format|F=s" => \$opt_F, "output-path=s" => \$opt_output_path, "peak-report|p=s" => \$opt_p, "performance-report|P=i" => \$opt_P, "performance-report_adjust|T=i" => \$opt_T, "requester-report|r=i" => \$opt_r, "requester-report-no-dns-lookup|n" => \$opt_n, "requester-report-use-user-info|u" => \$opt_u, "requester-report-with-targets|R=i" => \$opt_R, "response-time-report" => \$opt_response_time, "show-reports|S=s" => \$opt_S, "size-distribution-report|D=i" => \$opt_D, "sort-order|O" => \$opt_O, "status-report|s" => \$opt_s, "time-interval|I=s" => \$opt_I, "type-report|t=i" => \$opt_t, "type-report-ignore-case|c" => \$opt_c, "unit|U=s" => \$opt_U, "verbose|v" => \$opt_v, "version|V" => \$opt_V, ); readconfig(); print "$USAGE\n\n" if $opt_h; print "Calamaris $VERSION\n\n" if $opt_V; print "$COPYRIGHT\n\n$LICENSE\n\n$HOMEPAGE\n" if $opt_C or $opt_h or $opt_V; exit 0 if $opt_h or $opt_C or $opt_V; if ($usage_err) { print STDERR "run '$0 -h' for help.\n\n"; exit 1; } # initialize variables $test_string = "\nTest results:\n\n" if $test; $counter = $hier = $hier_direct = $hier_direct_size = $hier_direct_time = $hier_parent = $hier_parent_size = $hier_parent_time = $hier_sibling = $hier_sibling_size = $hier_sibling_time = $hier_size = $hier_time = $invalid = $ordered_tcp_req_time_max = $ordered_tcp_req_time_max_interval = $ordered_udp_req_time_max = $ordered_udp_req_time_max_interval = $peak_all_hour = $peak_all_hour_time = $peak_all_min = $peak_all_min_time = $peak_all_sec = $peak_all_sec_time = $peak_tcp_hour = $peak_tcp_hour_time = $peak_tcp_min = $peak_tcp_min_time = $peak_tcp_sec = $peak_tcp_sec_time = $peak_udp_hour = $peak_udp_hour_time = $peak_udp_min = $peak_udp_min_time = $peak_udp_sec = $peak_udp_sec_time = $size = $skipped = $tcp = $tcp_hit = $tcp_hit_size = $tcp_hit_time = $tcp_miss = $tcp_miss_none = $tcp_miss_none_size = $tcp_miss_none_time = $tcp_miss_size = $tcp_miss_time = $tcp_size = $tcp_time = $time = $time_end = $time_run = $udp = $udp_hit = $udp_hit_size = $udp_hit_time = $udp_miss = $udp_miss_size = $udp_miss_time = $udp_size = $udp_time = 0; $time_begin = 1e10; @months = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); undef(%udp_reqtime_size); undef(%udp_hit_reqtime_size); undef(%udp_hit_reqtime); undef(%tcp_reqtime_size); undef(%tcp_hit_reqtime_size); undef(%tcp_hit_reqtime); undef(%perf_ip); readcache() if ($opt_i); unless ($opt_z) { while ( defined( $line = <> ) ) { if ( not defined $opt_f or $opt_f eq 'auto' ) { if ( $line =~ m#^\s*\d+\.\d+\s+\d+\s+[\w\-\.:]+\s+\w+/\d+\s+\d+\s+\w+\s+\S+\s+\S+\s+\w+/\S+\s+\S+$# ) { $opt_f = 'squid'; print STDERR "guessing... using '-f squid'\n" if ($opt_v); last; } elsif ( $line =~ m#^\d+\s+\d+\s+[\w\-\.:]+\s+\w+/\d+\s+\d+\s+\w+\s+\S+\s+\S+\s+\w+/\S+\s+\S+$# ) { $opt_f = 'its'; print STDERR "guessing... using '-f its'\n" if ($opt_v); last; } elsif ( $line =~ m#^\d+\.\d+\s+\d+\s+[\w\-\.:]+\s+\w+/\d+\s+\d+\s+\w+\s+\S+\s+\S+\s+\w+/\S+$# ) { $opt_f = 'squid-old'; print STDERR "guessing... using '-f squid-old'\n" if ($opt_v); last; } elsif ( $line =~ m#^\d+\.\d+\s+\d+\s+[\w\-\.:]+\s+\w+/\d+\s+\d+\s+\w+\s+\S+\s+\S+\s+\w+/\S+\s+(\S|; c)+\s+\S+$# ) { $opt_f = 'nc'; print STDERR "guessing... using '-f nc'\n" if ($opt_v); last; } elsif ( $line =~ s/^\s*#\s*Fields:\s*// ) { $opt_f = 'elff'; print STDERR "guessing... using '-f elff'\n" if ($opt_v); last; } elsif ( $line =~ s/^\s*format=\s*// ) { $opt_f = 'nse'; print STDERR "guessing... using '-f nse'\n" if ($opt_v); last; } elsif ( $line =~ m#^\d+\.\d+\s+\d+\s+[\w\-\.:]+\s+\w+/\-?\d+\s+\d+\s+\w+\s+\S+\s+\S+\s+\w+/\S+\s+\S+\s+# ) { $opt_f = 'squid-extended'; print STDERR "guessing... using '-f squid-extended'\n" if ($opt_v); last; } elsif ( $line =~ m#^[\w\-\.:]+\s+\S+\s+\S+\s+\[.+\]\s+\"\w+\s+\S+\s+\S+\"\s+\d+\s+\d+\s+\S+(\s+\[.*\]\s+\[.*\])?$# ) { print STDERR "$0: The first line of the input looks to me as if you switched 'emulate_httpd_log' to on. I can't parse that format. Please read the README on this.\n\n"; exit(1); } elsif ( $line =~ m/^\s*(#|$)/ ) { print STDERR "skipping: $line\n" if ($opt_v); next; } else { print STDERR "$0: I don't know this input format. Please check the input. If you\'re sure that the following line is NOT corrupt and the error also occurs with the recent version of Calamaris (see the README for pointers and known bugs) then report it with the following line to . Thank You.\n\n$line\n\n"; exit(1); } } else { last; } } if ( not defined $opt_f or $opt_f eq 'auto' ) { print "\nno requests found\n"; exit(0); } # IP Filter my %filter_ip; if ($opt_ipfilter_exclude or $opt_ipfilter_include) { my $to_split = ($opt_ipfilter_exclude) ? $opt_ipfilter_exclude : $opt_ipfilter_include; foreach ( split /:/, $to_split ) { $ip = new NetAddr::IP( (split /\//, $_) ); foreach ( $ip->split('32') ) { $filter_ip{$_->addr()} = 1; } } } print STDERR "print a hash-sign for each $opt_b lines:\n" if ($opt_b); $loop = ' for ( ; $line; $line = <> ) {'; if ( $opt_f eq 'squid' ) { $loop .= ' $line =~ s#^\s+##; ( $log_date, $log_reqtime, $log_requester, $log_status, $log_size, $log_method, $log_url, $log_ident, $log_hier, $log_content, $foo ) = split ( /\s+/, $line ); if ( not defined $foo or not defined $log_content or $foo ne \'\' or $log_content eq \'\' or $log_reqtime < 0 or $log_date !~ m#^\d+\.\d{3}$# ) {'; } elsif ( $opt_f eq 'squid-extended' ) { $loop .= ' $line =~ s/ \[[^\[\]]*\]//g; ( $log_date, $log_reqtime, $log_requester, $log_status, $log_size, $log_method, $log_url, $log_ident, $log_hier, $log_content) = split ( /\s+/, $line, 10 ); chomp($log_content); if ( not defined $log_content or $log_content eq \'\' or $log_reqtime < 0 or $log_date !~ m#^\d+\.\d{3}$# ) {'; } elsif ( $opt_f eq 'its' ) { $loop .= ' ( $log_date, $log_reqtime, $log_requester, $log_status, $log_size, $log_method, $log_url, $log_ident, $log_hier, $log_content, $foo ) = split ( /\s+/, $line ); if ( not defined $foo or not defined $log_content or $foo ne \'\' or $log_content eq \'\' or $log_reqtime < 0 or $log_date !~ m#^\d+$# ) {'; } elsif ( $opt_f eq 'squid-old' ) { $loop .= ' ( $log_date, $log_reqtime, $log_requester, $log_status, $log_size, $log_method, $log_url, $log_ident, $log_hier, $foo ) = split ( /\s+/, $line ); unless ( not defined $foo or not defined $log_hier or $foo ne \'\' or $log_hier eq \'\' or $log_reqtime < 0 or $log_date !~ m#^\d+\.\d{3}$# ) {'; } elsif ( $opt_f eq 'nc' ) { $loop .= ' $line =~ s#\; c#\;_c#og; # Hack to handle buggy logfiles of NetCache V3.2.x ( $log_date, $log_reqtime, $log_requester, $log_status, $log_size, $log_method, $log_url, $log_ident, $log_hier, $log_content, $log_abort, $foo ) = split ( /\s+/, $line ); if ( not defined $foo or not defined $log_abort or $foo ne \'\' or $log_abort eq \'\' or $log_reqtime < 0 or $log_date !~ m#^\d+\.\d{3}$# ) {'; } elsif ( $opt_f eq 'elff' ) { @fields = split ( /\s+/, $line ); $loop .= ' use Time::Local; if ( $line =~ m#^'; foreach (@fields) { $tmpline1 .= '\s+' if ($tmpline1); if ( $_ eq 'date' ) { $tmpline1 .= '(\d+)-(\d+)-(\d+)'; $tmpline2 .= ' $log_year = $' . ++$offset . '; $log_month = $' . ++$offset . '; $log_day = $' . ++$offset . ';'; } elsif ( $_ eq 'time' ) { $tmpline1 .= '(\d+):(\d+):(\d+)'; $tmpline2 .= ' $log_hour = $' . ++$offset . '; $log_min = $' . ++$offset . '; $log_sec = $' . ++$offset . ';'; } elsif ( $_ eq 'x-timestamp' ) { $tmpline1 .= '(\d+\.\d+)'; $tmpline2 .= ' $log_date = $' . ++$offset . ';'; $log_date = 0; } elsif ( $_ eq 'c-ip' ) { $tmpline1 .= '([\w\-\.:]+)'; $tmpline2 .= ' $log_requester = $' . ++$offset . ';'; } elsif ( $_ eq 'cs-authname' or $_ eq 'x-remote-id' or $_ eq 'x-username' or $_ eq 'cs-username' ) { $tmpline1 .= '(\S+)'; $tmpline2 .= ' $log_ident = $' . ++$offset . ';'; } elsif ( $_ eq 's-ip' or $_ eq 's-sitename' or $_ eq 'sc-filter-result' or $_ eq 'sc-filter-category' or $_ eq 'x-virus-id' ) { $tmpline1 .= '[\w\-\.]+'; } elsif ( $_ eq 'cs-method' ) { $tmpline1 .= '([\w\-]+)'; $tmpline2 .= ' $log_method = $' . ++$offset . ';'; } elsif ( $_ eq 'cs-uri' ) { $tmpline1 .= '(\S+)'; $tmpline2 .= ' $log_url = $' . ++$offset . ';'; } elsif ( $_ eq 'cs-uri-scheme' ) { $tmpline1 .= '(\S+)'; $tmpline2 .= ' $log_cs_uri_scheme = $' . ++$offset . ';'; } elsif ( $_ eq 'cs-host' ) { $tmpline1 .= '(\S+)'; $tmpline2 .= ' $log_cs_host = $' . ++$offset . ';'; } elsif ( $_ eq 'cs-uri-path' ) { $tmpline1 .= '(\S+)'; $tmpline2 .= ' $log_cs_uri_path = $' . ++$offset . ';'; } elsif ( $_ eq 'cs-uri-stem' or $_ eq 'cs-uri-query' or $_ eq 'x-note' ) { $tmpline1 .= '\S+'; } elsif ( $_ eq 'c-version' ) { $tmpline1 .= '\w+/[\d\.]+'; } elsif ( $_ eq 'sc-status' ) { $tmpline1 .= '(\d+)'; $tmpline2 .= ' $log_code = $' . ++$offset . ';'; } elsif ( $_ eq 'sc-bytes' or $_ eq 'bytes' ) { $tmpline1 .= '(\d+)'; $tmpline2 .= ' $log_size = $' . ++$offset . ';'; } elsif ( $_ eq 'cs-bytes' ) { $tmpline1 .= '\d+'; } elsif ( $_ eq 'x-elapsed-milliseconds' ) { $tmpline1 .= '(\d+)'; $tmpline2 .= ' $log_reqtime = $' . ++$offset . ';'; } elsif ( $_ eq 'time-taken' ) { $tmpline1 .= '([\d\.]+)'; $tmpline2 .= ' $log_reqtime = $' . ++$offset . ' * 1000;'; } elsif ( $_ eq 'cs(User-Agent)' or $_ eq 'cs(Cookie)' or $_ eq 'cs(Referer)' or $_ eq 'sc(Referer)' or $_ eq 'cs(X-Forwarded-For)' or $_ eq 'x-hiername') { $tmpline1 .= '(\"[^\"]*\"|-)'; $tmpline2 .= ' ++$offset;'; } elsif ( $_ eq 'cs(Content-Type)' ) { $tmpline1 .= '(\"[^\"]*\"|-)'; $tmpline2 .= ' $log_content = $' . ++$offset . ';'; } elsif ( $_ eq 'cached' ) { $tmpline1 .= '(\d+)'; $tmpline2 .= ' $log_cached = $' . ++$offset . ';'; } elsif ( $_ eq 'x-transaction' ) { $tmpline1 .= '(\w+\/[\d\-]+)'; $tmpline2 .= ' $log_status = $' . ++$offset . ';'; $log_status = 0; } elsif ( $_ eq 'x-fill-proxy-ip' ) { $tmpline1 .= '([\w\-\.]+)'; $tmpline2 .= ' $log_proxy_ip = $' . ++$offset . ';'; } elsif ( $_ eq 'x-origin-ip' ) { $tmpline1 .= '([\w\-\.]+)'; $tmpline2 .= ' $log_origin_ip = $' . ++$offset . ';'; } elsif ( $_ eq 'x-hiercode' ) { $tmpline1 .= '([\w\-\.\/]+)'; $tmpline2 .= ' $log_hier = $' . ++$offset . ';'; $log_hier = 0; } elsif ( $_ eq 's-hierarchy' ) { $tmpline1 .= '([\w\-\.\/]+)'; $tmpline2 .= ' $log_hierarchy = $' . ++$offset . ';'; } elsif ( $_ eq 's-action' ) { $tmpline1 .= '([\w\-\.\/]+)'; $tmpline2 .= ' $log_s_action = $' . ++$offset . ';'; } elsif ( $_ eq 's-supplier-name' ) { $tmpline1 .= '([\w\-\.\/]+)'; $tmpline2 .= ' $log_supplier_name = $' . ++$offset . ';'; } elsif ( $_ eq 'rs(Content-Type)' ) { $tmpline1 .= '\"[^\"]*\"'; } else { print STDERR "$0: I don't know this input format. Please check the input. If you\'re sure that the following is NOT corrupt and the error also occurs with the recent version of Calamaris (see the README for pointers and known bugs) then report it with the following line to . Thank You.\n\n$_\n\n"; exit(1); } } foreach $pattern ( qw(date time c-ip cs-method cs-uri sc-status sc-bytes time-taken cached x-fill-proxy-ip x-origin-ip) ) { unless ( grep $pattern, @fields ) { print STDERR "$0: Your input file format is missing at least the field \'$pattern\'. I can\'t parse it. Sorry. If you think that this field isn't important to you, please report this error to . Thank You.\n\n"; exit(1); } } foreach $pattern (qw(cs-authname)) { unless ( grep $pattern, @fields ) { if ( $pattern eq 'cs-authname' ) { $tmpline2 .= ' $log_ident = "-";'; } } } $loop .= $tmpline1 . '.?$# ) {' . $tmpline2; $loop .= ' $log_date = timegm( $log_sec, $log_min, $log_hour, $log_day, $log_month - 1, $log_year - 1900 );' unless defined $log_date; $loop .= ' if ($log_s_action) { $log_status = "$log_s_action/$log_code"; } else { $log_status = "$log_cached/$log_code"; }' unless defined $log_status; $loop .= ' if ( $log_hierarchy and $log_supplier_name ) { $log_hier = "$log_hierarchy/$log_supplier_name"; } elsif ( $log_origin_ip ne \'-\' ) { $log_hier = "DIRECT/$log_origin_ip"; } elsif ( $log_proxy_ip ne \'-\' ) { if ( $log_cached eq \'0\' ) { $log_hier = "PARENT_MISS/$log_proxy_ip"; } else { $log_hier = "PARENT_HIT/$log_proxy_ip"; } } else { $log_hier = "NONE/-"; }' unless defined $log_hier; $loop .= ' } else {'; while ( defined( $line = <> ) ) { last unless $line =~ /^\s*#/; } } elsif ( $opt_f eq 'nse' ) { $line =~ s#^format=##og; @fields = split ( /\s+/, $line ); $loop .= ' use Time::Local; if ( $line =~ m#^'; foreach (@fields) { $tmpline1 .= '\s+' if ($tmpline1); if ( $_ eq '[%SYSDATE%]' ) { $tmpline1 .= '\[(\d+)/(\w+)/(\d+):(\d+):(\d+):(\d+)\s+\S+\]'; $tmpline2 .= ' $log_day = $' . ++$offset . '; $log_month = $' . ++$offset . '; $log_year = $' . ++$offset . '; $log_hour = $' . ++$offset . '; $log_min = $' . ++$offset . '; $log_sec = $' . ++$offset . ';'; } elsif ( $_ eq '%Ses->client.ip%' ) { $tmpline1 .= '([\w\-\.:]+)'; $tmpline2 .= ' $log_requester = $' . ++$offset . ';'; } elsif ( $_ eq '%Req->vars.pauth-user%' ) { $tmpline1 .= '(\S+)'; $tmpline2 .= ' $log_ident = $' . ++$offset . ';'; } elsif ( $_ eq '%Req->vars.remote-status%' or $_ eq '%Req->vars.r2p-cl%' or $_ eq '%Req->vars.cli-status%' or $_ eq '%Req->vars.svr-status%' or $_ eq '%Req->vars.cch-status%' ) { $tmpline1 .= '[\w\-\.]+'; } elsif ( $_ eq '"%Req->reqpb.proxy-request%"' ) { $tmpline1 .= '\"(\w+)\s+([^\"]+)\s*\S*\"'; $tmpline2 .= ' $log_method = $' . ++$offset . '; $log_url = $' . ++$offset . ';'; } elsif ( $_ eq '%Req->srvhdrs.clf-status%' ) { $tmpline1 .= '([\d\-]+)'; $tmpline2 .= ' $log_code = $' . ++$offset . ';'; } elsif ( $_ eq '%Req->vars.p2c-cl%' ) { $tmpline1 .= '([\d\-]+)'; $tmpline2 .= ' $log_size = $' . ++$offset . ';'; } elsif ( $_ eq '%Req->headers.content-length%' or $_ eq '%Req->vars.p2r-cl%' or $_ eq '%Req->vars.c2p-hl%' or $_ eq '%Req->vars.p2c-hl%' or $_ eq '%Req->vars.p2r-hl%' or $_ eq '%Req->vars.r2p-hl%' ) { $tmpline1 .= '[\d\-]+'; } elsif ( $_ eq '%Req->vars.xfer-time%' ) { $tmpline1 .= '([\d\.]+)'; $tmpline2 .= ' $log_reqtime = $' . ++$offset . ' * 1000;'; } elsif ( $_ eq '%route%' ) { $tmpline1 .= '(\d+)'; $tmpline2 .= ' $log_cached = $' . ++$offset . ';'; } elsif ( $_ eq '%Req->vars.actual-route%' ) { $tmpline1 .= '(\S+)'; $tmpline2 .= ' $log_hier = $' . ++$offset . '; if ( $log_hier =~ m#[\(\)]# ) { $log_hier =~ s#^(\w+)(\((\S+)\))?$#$1/$3#; $log_status = \'TCP_MISS/-\'; } elsif ( $log_hier =~ m#-# ) { $log_hier = $log_hier . \'/-\'; $log_status = \'TCP_HIT/-\'; } else { $log_hier = $log_hier . \'/-\'; $log_status = \'TCP_MISS/-\'; }'; } elsif ( $_ eq '-' ) { $tmpline1 .= '-'; } else { print STDERR "$0: I don't know this input format. Please check the input. If you\'re sure that the following is NOT corrupt and the error also occurs with the recent version of Calamaris (see the README for pointers and known bugs) then report it with the following line to . Thank You.\n\n$_\n\n"; exit(1); } } foreach $pattern ( qw(%Ses->client.ip% [%SYSDATE%] %Req->reqpb.proxy-request% %Req->srvhdrs.clf-status% %Req->vars.p2c-cl% %Req->vars.xfer-time%) ) { unless ( grep $pattern, @fields ) { print STDERR "$0: Your input file format is missing at least the field \'$pattern\'. I can\'t parse it. Sorry. If you think that this field isn't important to you, please report this error to . Thank You.\n\n"; exit(1); } } foreach $pattern (qw(%Req->vars.pauth-user% %Req->vars.actual-route%)) { unless ( grep /$pattern/, @fields ) { if ( $pattern eq '%Req->vars.pauth-user%' ) { $tmpline2 .= ' $log_ident = "-";'; } elsif ( $pattern eq '%Req->vars.actual-route%' ) { $tmpline2 .= ' $log_hier = \'-/-\'; $log_status = \'-/-\';'; } } } $loop .= $tmpline1 . '.?$# ) {' . $tmpline2 . ' $monthcount = -1; foreach $month (@months) { $monthcount++; last if ( $month eq $log_month ); } $log_date = timegm( $log_sec, $log_min, $log_hour, $log_day, $monthcount, $log_year - 1900 ); } else {'; while ( defined( $line = <> ) ) { last unless $line =~ /^\s*#/; } } else { print STDERR "$0: unknown value at -f -option: \"$opt_f\"\n\n$USAGE\n\n"; exit 1; } $loop .= ' chomp($line);'; $loop .= ' warn(\'invalid line: "\' . $line . "\"\n");' if $opt_v; $loop .= ' $invalid++; next; }'; $loop .= ' if (($log_date < $interval_begin) or ($log_date > $interval_end)) { $skipped++; next; } ' if $opt_I; $loop .= ' if($filter_ip{$log_requester}) { $skipped++; next; } ' if $opt_ipfilter_exclude; $loop .= ' if(! $filter_ip{$log_requester}) { $skipped++; next; } ' if $opt_ipfilter_include; $loop .= ' $log_reqtime = .1 if $log_reqtime == 0; ( $log_hitfail, $log_code ) = split \'/\', $log_status; $log_size = 0 if ( $log_size eq \'-\' ); $log_url = "$log_cs_uri_scheme://$log_cs_host/$log_cs_uri_path" unless ($log_url); $log_url =~ s/\?.*$/?/; @url = split m#[/\\\]#o, $log_url; ( $urlprot, $urlhost, $urlext ) = (@url)[ 0, 2, $#url ]; $urlext = \'.\' if $#url <= 2; if ( $#url <= -1 ) { $urlext = \'.\'; $urlprot = $urlhost = \'\'; } $urlext = \'.\' if ( $urlext =~ m#[\?;&\$,!@=|%]#o or $log_method eq \'POST\' ); unless ( defined $urlhost ) { $urlhost = $urlprot;'; $loop .= ' $log_content = ' unless $opt_f eq 'squid-old' or $opt_f eq 'elff' or $opt_f eq 'nse'; $loop .= ' $urlprot = \'\'; $urlext = \'.\'; } $urlhost =~ s#^.*@##o; $urlhost =~ s#[:\?].*$##o; $urlhost =~ tr/A-Z/a-z/; @urlext = split \'\.\', $urlext; $urlext = (@urlext)[$#urlext]; $urlext = \'\' if $#urlext <= 0;'; $loop .= ' $urlext =~ tr/A-Z/a-z/;' if $opt_c; $loop .= ' if ( $urlhost =~ m#^(([0-9][0-9]{0,2}\.){3})[0-9][0-9]{0,2}$#o ) {'; $loop .= ' $urlhost = $1 . \'*\';' unless $opt_N == -1; $loop .= ' $urltld = \'\'; } elsif ( $urlhost =~ m#^(.*\.([^\.]+\.)?)?([^\.]+\.([^\.]+))\.?$#o ) { @list = split \'\.\', $urlhost; $urltld = pop @list;'; if ( $opt_N != -1 ) { $loop .= ' $urlhost = $urltld;'; for ( $i = $opt_N; $i != 1; $i-- ) { $loop .= ' $urlhost = pop (@list) . \'.\' . $urlhost if $#list >= 0;'; } $loop .= ' $urlhost = pop (@list) . \'.\' . $urlhost if ( $urltld =~ m#^(a[rtu]|br|c[no]|hk|i[dlm]|jp|kr|l[by]|m[oxy]|nz|p[elnry]|sg|t[hrw]|u[aks]|ve|yu|za)$#o and $#list >= 0 ); $urlhost = \'*.\' . $urlhost if $#list >= 0; $urltld = \'*.\' . $urltld;'; } $loop .= ' } elsif ( $urlhost =~ m#([!a-z0-9\.\-]|\.\.)#o ) { $urlhost = $urltld = $urlext = $urlprot = \'\'; } else { $urltld = $urlhost; }'; if ($opt_n) { $loop .= ' $requester = $log_requester;'; } else { $loop .= ' $requester = getfqdn($log_requester);'; } $loop .= ' $requester = $log_ident . \'@\' . $requester if $log_ident ne \'-\';' if $opt_u; $loop .= ' ( $log_hier_method, $log_hier_host ) = ( split \'/\', $log_hier )[ 0, 1 ];'; $loop .= ' $log_content = \'\' if $log_content eq \'-\'; $log_content =~ tr/A-Z/a-z/; $log_content =~ s#\s+.*##; $log_content = ' unless $opt_f eq 'squid-old' or $opt_f eq 'elff' or $opt_f eq 'nse'; $loop .= ' $urlhost = $urltld = $urlext = $urlprot = \'\' if ( $log_code =~ m#^[45]#o );'; $loop .= " print STDERR '#' if (0 == (\$counter % $opt_b));" if $opt_b; $loop .= ' $counter++; $size += $log_size; $time += $log_reqtime; $method{$log_method} = $method_size{$log_method} = $method_time{$log_method} = 0 unless defined $method{$log_method}; $method{$log_method}++; $method_size{$log_method} += $log_size; $method_time{$log_method} += $log_reqtime; $time_begin = $log_date if $log_date < $time_begin; $time_end = $log_date if $log_date > $time_end;'; if ( defined $opt_p ) { $loop .= ' if (@peak_all) { if ( $log_date < $peak_all[$#peak_all] ) { $peak_warn = \'Peak values are most likely wrong due to unsorted input!\'; undef(@peak_all); undef(@peak_udp); undef(@peak_tcp); $peak_all_min_pointer = $peak_all_sec_pointer = $peak_tcp_min_pointer = $peak_tcp_sec_pointer = $peak_udp_min_pointer = $peak_udp_sec_pointer = 0; chomp($line); warn( \'unsorted input: "\' . $line . "\"\n" ) if $opt_v; } }'; if ( $opt_p eq 'old' ) { $loop .= ' $peak_all_sec_pointer++; $peak_all_min_pointer++; unshift ( @peak_all, $log_date ); $peak_all_sec_pointer-- while $peak_all[ $peak_all_sec_pointer - 1 ] < ( $log_date - 1 ); $peak_all_min_pointer-- while $peak_all[ $peak_all_min_pointer - 1 ] < ( $log_date - 60 ); pop (@peak_all) while $peak_all[$#peak_all] < ( $log_date - 3600 ); if ( $peak_all_hour < @peak_all ) { $peak_all_hour = @peak_all; $peak_all_hour_time = $log_date - 3600; } if ( $peak_all_min < $peak_all_min_pointer ) { $peak_all_min = $peak_all_min_pointer; $peak_all_min_time = $log_date - 60; } if ( $peak_all_sec < $peak_all_sec_pointer ) { $peak_all_sec = $peak_all_sec_pointer; $peak_all_sec_time = $log_date - 1; }'; } elsif ( $opt_p eq 'new' ) { $loop .= ' $date_hour = int( ( $log_date - ( $log_reqtime / 1000 ) ) / 3600 ) * 3600; foreach $i ( ( $date_hour / 3600 ) .. int( $log_date / 3600 ) ) { $peak_all_hour{ $i * 3600 } = $peak_all_hour_size{ $i * 3600 } = 0 unless defined $peak_all_hour{ $i * 3600 }; $peak_all_hour{ $i * 3600 }++; $peak_all_hour_size{ $i * 3600 } += $log_size / int( $log_reqtime / 3600000 + 1 ); } $peak_all_sec_pointer++; unshift ( @peak_all, $log_date ); $peak_all_sec_pointer-- while $peak_all[ $peak_all_sec_pointer - 1 ] < ( $log_date - 1 ); pop (@peak_all) while $peak_all[$#peak_all] < ( $log_date - 60 ); if ( $peak_all_min < @peak_all ) { $peak_all_min = @peak_all; $peak_all_min_time = $log_date - 60; } if ( $peak_all_sec < $peak_all_sec_pointer ) { $peak_all_sec = $peak_all_sec_pointer; $peak_all_sec_time = $log_date - 1; }'; } else { print STDERR "$0: unknown value at -p -option: \"$opt_p\"\n\n$USAGE\n\n"; exit 1; } } $loop .= ' if ( ( $log_method =~ m#^ICP_#o ) or ( $log_status =~ m#^ICP#o ) ) { $udp++; $udp_size += $log_size; $udp_time += $log_reqtime;'; $loop .= ' $udp_reqtime{$log_reqtime} = $udp_hit_reqtime{$log_reqtime} = $udp_reqtime_size{$log_reqtime} = $udp_hit_reqtime_size{$log_reqtime} = 0 unless defined $udp_reqtime{$log_reqtime}; $udp_reqtime{$log_reqtime}++; $udp_reqtime_size{$log_reqtime} += $log_size;' if $opt_response_time; $loop .= ' $udp_code{$log_code} = $udp_code_time{$log_code} = $udp_code_size{$log_code} = $udp_hit_code{$log_code} = $udp_hit_code_size{$log_code} = 0 unless defined $udp_code{$log_code}; $udp_code{$log_code}++; $udp_code_time{$log_code} += $log_reqtime; $udp_code_size{$log_code} += $log_size;' if $opt_errorcode_distribution; $loop .= ' $udp_requester{$requester} = $udp_requester_size{$requester} = $udp_requester_time{$requester} = $udp_hit_requester{$requester} = $udp_hit_requester_size{$requester} = 0 unless defined $udp_requester{$requester}; $udp_requester{$requester}++; $udp_requester_size{$requester} += $log_size; $udp_requester_time{$requester} += $log_reqtime;' if ($opt_r); $loop .= ' $udp_requester_urlhost{$requester}{$urlhost} = $udp_requester_urlhost_size{$requester}{$urlhost} = $udp_requester_urlhost_time{$requester}{$urlhost} = $udp_hit_requester_urlhost{$requester}{$urlhost} = $udp_hit_requester_urlhost_size{$requester}{$urlhost} = 0 unless defined $udp_requester_urlhost{$requester}{$urlhost}; $udp_requester_urlhost{$requester}{$urlhost}++; $udp_requester_urlhost_size{$requester}{$urlhost} += $log_size; $udp_requester_urlhost_time{$requester}{$urlhost} += $log_reqtime;' if ($opt_R); if ( not defined $opt_p ) { } elsif ( $opt_p eq 'old' ) { $loop .= ' $peak_udp_sec_pointer++; $peak_udp_min_pointer++; unshift ( @peak_udp, $log_date ); $peak_udp_sec_pointer-- while $peak_udp[ $peak_udp_sec_pointer - 1 ] < ( $log_date - 1 ); $peak_udp_min_pointer-- while $peak_udp[ $peak_udp_min_pointer - 1 ] < ( $log_date - 60 ); pop @peak_udp while $peak_udp[$#peak_udp] < ( $log_date - 3600 ); if ( $peak_udp_hour < @peak_udp ) { $peak_udp_hour = @peak_udp; $peak_udp_hour_time = $log_date - 3600; } if ( $peak_udp_min < $peak_udp_min_pointer ) { $peak_udp_min = $peak_udp_min_pointer; $peak_udp_min_time = $log_date - 60; } if ( $peak_udp_sec < $peak_udp_sec_pointer ) { $peak_udp_sec = $peak_udp_sec_pointer; $peak_udp_sec_time = $log_date - 1; }'; } elsif ( $opt_p eq 'new' ) { $loop .= ' foreach $i ( ( $date_hour / 3600 ) .. int( $log_date / 3600 ) ) { $peak_udp_hour{ $i * 3600 } = $peak_udp_hour_size{ $i * 3600 } = 0 unless defined $peak_udp_hour{ $i * 3600 }; $peak_udp_hour{ $i * 3600 }++; $peak_udp_hour_size{ $i * 3600 } += $log_size / int( $log_reqtime / 3600000 + 1 ); } $peak_udp_sec_pointer++; unshift ( @peak_udp, $log_date ); $peak_udp_sec_pointer-- while $peak_udp[ $peak_udp_sec_pointer - 1 ] < ( $log_date - 1 ); pop @peak_udp while $peak_udp[$#peak_udp] < ( $log_date - 60 ); if ( $peak_udp_min < @peak_udp ) { $peak_udp_min = @peak_udp; $peak_udp_min_time = $log_date - 60; } if ( $peak_udp_sec < $peak_udp_sec_pointer ) { $peak_udp_sec = $peak_udp_sec_pointer; $peak_udp_sec_time = $log_date - 1; }'; } $loop .= ' if ( $log_hitfail =~ m#^(UDP|ICP)_HIT#o ) { $udp_hit++; $udp_hit_size += $log_size; $udp_hit_time += $log_reqtime;'; $loop .= ' $udp_hit_reqtime{$log_reqtime}++; $udp_hit_reqtime_size{$log_reqtime} += $log_size;' if $opt_response_time; $loop .= ' $udp_hit_code{$log_code}++; $udp_hit_code_size{$log_code} += $log_size;' if $opt_errorcode_distribution; $loop .= ' $udp_hit_requester{$requester}++; $udp_hit_requester_size{$requester} += $log_size;' if $opt_r; $loop .= ' $udp_hit_requester_urlhost{$requester}{$urlhost}++; $udp_hit_requester_urlhost_size{$requester}{$urlhost} += $log_size;' if ($opt_R); $loop .= ' $udp_hit{$log_hitfail} = $udp_hit_size{$log_hitfail} = $udp_hit_time{$log_hitfail} = 0 unless defined $udp_hit{$log_hitfail}; $udp_hit{$log_hitfail}++; $udp_hit_size{$log_hitfail} += $log_size; $udp_hit_time{$log_hitfail} += $log_reqtime;' if ($opt_s); $loop .= ' } else { $udp_miss++; $udp_miss_size += $log_size; $udp_miss_time += $log_reqtime;'; $loop .= ' $udp_miss{$log_hitfail} = $udp_miss_size{$log_hitfail} = $udp_miss_time{$log_hitfail} = 0 unless defined $udp_miss{$log_hitfail}; $udp_miss{$log_hitfail}++; $udp_miss_size{$log_hitfail} += $log_size; $udp_miss_time{$log_hitfail} += $log_reqtime;' if ($opt_s); $loop .= ' } } else { $tcp++; $tcp_size += $log_size; $tcp_time += $log_reqtime;'; $loop .= ' $tcp_reqtime{$log_reqtime} = $tcp_hit_reqtime{$log_reqtime} = $tcp_reqtime_size{$log_reqtime} = $tcp_hit_reqtime_size{$log_reqtime} = 0 unless defined $tcp_reqtime{$log_reqtime}; $tcp_reqtime{$log_reqtime}++; $tcp_reqtime_size{$log_reqtime} += $log_size;' if $opt_response_time; $loop .= ' $tcp_code{$log_code} = $tcp_code_time{$log_code} = $tcp_code_size{$log_code} = $tcp_hit_code_size{$log_code} = $tcp_hit_code{$log_code} = 0 unless defined $tcp_code{$log_code}; $tcp_code{$log_code}++; $tcp_code_time{$log_code} += $log_reqtime; $tcp_code_size{$log_code} += $log_size;' if $opt_errorcode_distribution; $loop .= ' $perf_date = ( int( ( $log_date + ' . "( $opt_T * 60 ) ) / ( 60 * $opt_P ) ) * 60 * $opt_P ) - ( $opt_T * 60 );" . ' unless ( defined $perf_counter{$perf_date} ) { $perf_counter{$perf_date} = $perf_size{$perf_date} = $perf_tcp_hit_size{$perf_date} = $perf_tcp_miss_size{$perf_date} = $perf_hier_direct_size{$perf_date} = $perf_tcp_hit{$perf_date} = $perf_hier_sibling_size{$perf_date} = $perf_hier_parent_size{$perf_date} = 0; $perf_time{$perf_date} = $perf_tcp_hit_time{$perf_date} = $perf_tcp_miss_time{$perf_date} = $perf_hier_direct_time{$perf_date} = $perf_hier_sibling_time{$perf_date} = $perf_hier_parent_time{$perf_date} = .0000000001; } $perf_counter{$perf_date}++; $perf_ip{$perf_date}{$log_requester} = 1; $perf_size{$perf_date} += $log_size; $perf_time{$perf_date} += $log_reqtime;' if ($opt_P); $loop .= ' $tcp_requester{$requester} = $tcp_requester_size{$requester} = $tcp_requester_time{$requester} = $tcp_hit_requester{$requester} = $tcp_hit_requester_size{$requester} = 0 unless defined $tcp_requester{$requester}; $tcp_requester{$requester}++; $tcp_requester_size{$requester} += $log_size; $tcp_requester_time{$requester} += $log_reqtime;' if ($opt_r); $loop .= ' $distribution = $log_size ? int( log($log_size) / log($opt_D) ) : -1; $tcp_distribution{$distribution} = $tcp_distribution_size{$distribution} = $tcp_distribution_time{$distribution} = $tcp_hit_distribution{$distribution} = $tcp_hit_distribution_size{$distribution} = 0 unless defined $tcp_distribution{$distribution}; $tcp_distribution{$distribution}++; $tcp_distribution_size{$distribution} += $log_size; $tcp_distribution_time{$distribution} += $log_reqtime;' if ($opt_D); $loop .= ' $tcp_requester_urlhost{$requester}{$urlhost} = $tcp_requester_urlhost_size{$requester}{$urlhost} = $tcp_requester_urlhost_time{$requester}{$urlhost} = $tcp_hit_requester_urlhost{$requester}{$urlhost} = $tcp_hit_requester_urlhost_size{$requester}{$urlhost} = 0 unless defined $tcp_requester_urlhost{$requester}{$urlhost}; $tcp_requester_urlhost{$requester}{$urlhost}++; $tcp_requester_urlhost_size{$requester}{$urlhost} += $log_size; $tcp_requester_urlhost_time{$requester}{$urlhost} += $log_reqtime;' if ($opt_R); $loop .= ' $tcp_urlhost{$urlhost} = $tcp_urlhost_size{$urlhost} = $tcp_urlhost_time{$urlhost} = $tcp_hit_urlhost{$urlhost} = $tcp_hit_urlhost_size{$urlhost} = 0 unless defined $tcp_urlhost{$urlhost}; $tcp_urlhost{$urlhost}++; $tcp_urlhost_size{$urlhost} += $log_size; $tcp_urlhost_time{$urlhost} += $log_reqtime; $tcp_urltld{$urltld} = $tcp_urltld_size{$urltld} = $tcp_urltld_time{$urltld} = $tcp_hit_urltld{$urltld} = $tcp_hit_urltld_size{$urltld} = 0 unless defined $tcp_urltld{$urltld}; $tcp_urltld{$urltld}++; $tcp_urltld_time{$urltld} += $log_reqtime; $tcp_urltld_size{$urltld} += $log_size;' if ($opt_d); $loop .= ' $tcp_urlprot{$urlprot} = $tcp_urlprot_size{$urlprot} = $tcp_hit_urlprot{$urlprot} = $tcp_hit_urlprot_size{$urlprot} = 0 unless defined $tcp_urlprot{$urlprot}; $tcp_urlprot{$urlprot}++; $tcp_urlprot_time{$urlprot} += $log_reqtime; $tcp_urlprot_size{$urlprot} += $log_size;' if ($opt_t); if ( not defined $opt_p ) { } elsif ( $opt_p eq 'old' ) { $loop .= ' $peak_tcp_sec_pointer++; $peak_tcp_min_pointer++; unshift ( @peak_tcp, $log_date ); $peak_tcp_sec_pointer-- while $peak_tcp[ $peak_tcp_sec_pointer - 1 ] < ( $log_date - 1 ); $peak_tcp_min_pointer-- while $peak_tcp[ $peak_tcp_min_pointer - 1 ] < ( $log_date - 60 ); pop (@peak_tcp) while $peak_tcp[$#peak_tcp] < ( $log_date - 3600 ); if ( $peak_tcp_hour < @peak_tcp ) { $peak_tcp_hour = @peak_tcp; $peak_tcp_hour_time = $log_date - 3600; } if ( $peak_tcp_min < $peak_tcp_min_pointer ) { $peak_tcp_min = $peak_tcp_min_pointer; $peak_tcp_min_time = $log_date - 60; } if ( $peak_tcp_sec < $peak_tcp_sec_pointer ) { $peak_tcp_sec = $peak_tcp_sec_pointer; $peak_tcp_sec_time = $log_date - 1; }'; } elsif ( $opt_p eq 'new' ) { $loop .= ' foreach $i ( $date_hour / 3600 .. int( $log_date / 3600 ) ) { $peak_tcp_hour{ $i * 3600 } = $peak_tcp_hour_size{ $i * 3600 } = 0 unless defined $peak_tcp_hour{ $i * 3600 }; $peak_tcp_hour{ $i * 3600 }++; $peak_tcp_hour_size{ $i * 3600 } += $log_size / int( $log_reqtime / 3600000 + 1 ); } $peak_tcp_sec_pointer++; unshift ( @peak_tcp, $log_date ); $peak_tcp_sec_pointer-- while $peak_tcp[ $peak_tcp_sec_pointer - 1 ] < ( $log_date - 1 ); pop (@peak_tcp) while $peak_tcp[$#peak_tcp] < ( $log_date - 60 ); if ( $peak_tcp_min < @peak_tcp ) { $peak_tcp_min = @peak_tcp; $peak_tcp_min_time = $log_date - 60; } if ( $peak_tcp_sec < $peak_tcp_sec_pointer ) { $peak_tcp_sec = $peak_tcp_sec_pointer; $peak_tcp_sec_time = $log_date - 1; }'; } $loop .= ' $tcp_content{$log_content} = $tcp_content_size{$log_content} = $tcp_content_time{$log_content} = $tcp_hit_content{$log_content} = $tcp_hit_content_size{$log_content} = 0 unless defined $tcp_content{$log_content}; $tcp_content{$log_content}++; $tcp_content_time{$log_content} += $log_reqtime; $tcp_content_size{$log_content} += $log_size;' unless $opt_f eq 'squid-old' or $opt_f eq 'elff' or $opt_f eq 'nse'; $loop .= ' $tcp_urlext{$urlext} = $tcp_urlext_size{$urlext} = $tcp_urlext_time{$urlext} = $tcp_hit_urlext{$urlext} = $tcp_hit_urlext_size{$urlext} = $tcp_urlext_fresh{$urlext} = $tcp_urlext_stale{$urlext} = $tcp_urlext_refresh{$urlext} = $tcp_urlext_mod{$urlext} = $tcp_urlext_unmod{$urlext} = 0 unless defined $tcp_urlext{$urlext}; $tcp_urlext{$urlext}++; $tcp_urlext_time{$urlext} += $log_reqtime; $tcp_urlext_size{$urlext} += $log_size;' if ($opt_t); $loop .= ' $tcp_urlext_fresh{$urlext}++ if grep { /^$log_hitfail$/ } @{$fresh_tags{$opt_f}}; $tcp_urlext_stale{$urlext}++ if grep { /^$log_hitfail$/ } @{$stale_tags{$opt_f}}; $tcp_urlext_refresh{$urlext}++ if grep { /^$log_hitfail$/ } @{$refresh_tags{$opt_f}}; $tcp_urlext_mod{$urlext}++ if grep { /^$log_hitfail$/ } @{$mod_tags{$opt_f}}; $tcp_urlext_unmod{$urlext}++ if grep { /^$log_hitfail$/ } @{$unmod_tags{$opt_f}};' if ($object_freshness_report and $opt_t); if ( $opt_f eq 'elff' ) { $loop .= ' if ( $log_hitfail eq \'1\' or $log_hitfail =~ m#^(TCP_HIT|HIT_)#o ) {'; } else { $loop .= ' if ( $log_hitfail =~ m#^TCP_(\w*HIT|REDIRECT|REFRESH_UNMODIFIED)#o ) {'; } $loop .= ' $tcp_hit++; $tcp_hit_size += $log_size; $tcp_hit_time += $log_reqtime;'; $loop .= ' $tcp_hit_reqtime{$log_reqtime}++; $tcp_hit_reqtime_size{$log_reqtime} += $log_size;' if $opt_response_time; $loop .= ' $tcp_hit_code{$log_code}++; $tcp_hit_code_size{$log_code} += $log_size;' if $opt_errorcode_distribution; $loop .= ' $perf_tcp_hit{$perf_date}++; $perf_tcp_hit_size{$perf_date} += $log_size; $perf_tcp_hit_time{$perf_date} += $log_reqtime;' if ($opt_P); $loop .= ' $tcp_hit{$log_hitfail} = $tcp_hit_size{$log_hitfail} = $tcp_hit_time{$log_hitfail} = 0 unless defined $tcp_hit{$log_hitfail}; $tcp_hit{$log_hitfail}++; $tcp_hit_size{$log_hitfail} += $log_size; $tcp_hit_time{$log_hitfail} += $log_reqtime;' if ($opt_s) and $opt_f ne 'elff'; $loop .= ' $tcp_hit_requester{$requester}++; $tcp_hit_requester_size{$requester} += $log_size;' if ($opt_r); $loop .= ' $tcp_hit_requester_urlhost{$requester}{$urlhost}++; $tcp_hit_requester_urlhost_size{$requester}{$urlhost} += $log_size;' if ($opt_R); $loop .= ' $tcp_hit_distribution{$distribution}++; $tcp_hit_distribution_size{$distribution} += $log_size;' if ($opt_D); $loop .= ' $tcp_hit_urlhost{$urlhost}++; $tcp_hit_urlhost_size{$urlhost} += $log_size; $tcp_hit_urltld{$urltld}++; $tcp_hit_urltld_size{$urltld} += $log_size;' if ($opt_d); $loop .= ' $tcp_hit_content{$log_content}++; $tcp_hit_content_time{$log_content} += $log_reqtime; $tcp_hit_content_size{$log_content} += $log_size;' unless $opt_f eq 'squid-old' or $opt_f eq 'elff' or $opt_f eq 'nse'; $loop .= ' $tcp_hit_urlext{$urlext}++; $tcp_hit_urlext_size{$urlext} += $log_size; $tcp_hit_urlprot{$urlprot}++; $tcp_hit_urlprot_size{$urlprot} += $log_size;' if ($opt_t); $loop .= ' } elsif ( $log_hier_method =~ m#EMPTY|NONE|NULL|UNKNOWN|^\-$#o or $log_hitfail =~ m#^ERR_#o ) { $tcp_miss_none++; $tcp_miss_none_size += $log_size; $tcp_miss_none_time += $log_reqtime;' if $opt_f ne 'elff'; $loop .= ' $tcp_miss_none{$log_hitfail} = $tcp_miss_none_size{$log_hitfail} = $tcp_miss_none_time{$log_hitfail} = 0 unless defined $tcp_miss_none{$log_hitfail}; $tcp_miss_none{$log_hitfail}++; $tcp_miss_none_size{$log_hitfail} += $log_size; $tcp_miss_none_time{$log_hitfail} += $log_reqtime;' if ($opt_s) and $opt_f ne 'elff'; $loop .= ' } else { $tcp_miss++; $tcp_miss_size += $log_size; $tcp_miss_time += $log_reqtime;'; $loop .= ' $perf_tcp_miss_size{$perf_date} += $log_size; $perf_tcp_miss_time{$perf_date} += $log_reqtime;' if ($opt_P); $loop .= ' $tcp_miss{$log_hitfail} = $tcp_miss_size{$log_hitfail} = $tcp_miss_time{$log_hitfail} = 0 unless defined $tcp_miss{$log_hitfail}; $tcp_miss{$log_hitfail}++; $tcp_miss_size{$log_hitfail} += $log_size; $tcp_miss_time{$log_hitfail} += $log_reqtime;' if ($opt_s) and $opt_f ne 'elff'; $loop .= ' $tcp_miss_requester{$requester} = $tcp_miss_requester_size{$requester} = 0 unless defined $tcp_miss_requester{$requester}; $tcp_miss_requester{$requester}++; $tcp_miss_requester_size{$requester} += $log_size;' if ($opt_r); $loop .= ' } if ( $log_hier_method !~ m#EMPTY|NONE|NULL|UNKNOWN|^\-$#o ) { $hier++; $hier_size += $log_size; $hier_time += $log_reqtime; if ( $log_hier_method =~ m#DIRECT|ORIGINAL_DST|PINNED|SOURCE_FASTEST#o ) { $hier_direct++; $hier_direct_size += $log_size; $hier_direct_time += $log_reqtime;'; $loop .= ' $perf_hier_direct_size{$perf_date} += $log_size; $perf_hier_direct_time{$perf_date} += $log_reqtime;' if ($opt_P); $loop .= ' $hier_direct{$log_hier_method} = $hier_direct_size{$log_hier_method} = $hier_direct_time{$log_hier_method} = 0 unless defined $hier_direct{$log_hier_method}; $hier_direct{$log_hier_method}++; $hier_direct_size{$log_hier_method} += $log_size; $hier_direct_time{$log_hier_method} += $log_reqtime;' if ($opt_s) and $opt_f ne 'elff'; $loop .= ' } elsif ( $log_hier_method =~ m#(CACHE_DIGEST|NEIGHBOR|PARENT|SIBLING)_\w*HIT|SIBLING#o ) { $hier_sibling++; $hier_sibling_size += $log_size; $hier_sibling_time += $log_reqtime;'; $loop .= ' $perf_hier_sibling_size{$perf_date} += $log_size; $perf_hier_sibling_time{$perf_date} += $log_reqtime;' if ($opt_P); $loop .= ' $hier_sibling{$log_hier_method} = $hier_sibling_size{$log_hier_method} = $hier_sibling_time{$log_hier_method} = 0 unless defined $hier_sibling{$log_hier_method}; $hier_sibling{$log_hier_method}++; $hier_sibling_size{$log_hier_method} += $log_size; $hier_sibling_time{$log_hier_method} += $log_reqtime;' if ($opt_s) and $opt_f ne 'elff'; $loop .= ' $hier_neighbor{$log_hier_host} = $hier_neighbor_size{$log_hier_host} = $hier_neighbor_time{$log_hier_host} = 0 unless defined $hier_neighbor{$log_hier_host}; $hier_neighbor{$log_hier_host}++; $hier_neighbor_size{$log_hier_host} += $log_size; $hier_neighbor_time{$log_hier_host} += $log_reqtime;'; $loop .= ' $hier_neighbor_status{$log_hier_host}{$log_hier_method} = $hier_neighbor_status_size{$log_hier_host}{$log_hier_method} = $hier_neighbor_status_time{$log_hier_host}{$log_hier_method} = 0 unless defined $hier_neighbor_status{$log_hier_host}{$log_hier_method}; $hier_neighbor_status{$log_hier_host}{$log_hier_method}++; $hier_neighbor_status_size{$log_hier_host}{$log_hier_method} += $log_size; $hier_neighbor_status_time{$log_hier_host}{$log_hier_method} += $log_reqtime;' if ($opt_s); $loop .= ' } elsif ( $log_hier_method =~ m#(ANY|CLOSEST|DEFAULT|FIRST_UP|PASSTHROUGH|ROUNDROBIN|SINGLE)_PARENT|CARP|PARENT_MISS|PARENT|PROXY#o ) { $hier_parent++; $hier_parent_size += $log_size; $hier_parent_time += $log_reqtime;'; $loop .= ' $perf_hier_parent_size{$perf_date} += $log_size; $perf_hier_parent_time{$perf_date} += $log_reqtime;' if ($opt_P); $loop .= ' $hier_parent{$log_hier_method} = $hier_parent_size{$log_hier_method} = $hier_parent_time{$log_hier_method} = 0 unless defined $hier_parent{$log_hier_method}; $hier_parent{$log_hier_method}++; $hier_parent_size{$log_hier_method} += $log_size; $hier_parent_time{$log_hier_method} += $log_reqtime;' if ($opt_s) and $opt_f ne 'elff'; $loop .= ' $hier_neighbor{$log_hier_host} = $hier_neighbor_size{$log_hier_host} = $hier_neighbor_time{$log_hier_host} = 0 unless defined $hier_neighbor{$log_hier_host}; $hier_neighbor{$log_hier_host}++; $hier_neighbor_size{$log_hier_host} += $log_size; $hier_neighbor_time{$log_hier_host} += $log_reqtime;'; $loop .= ' $hier_neighbor_status{$log_hier_host}{$log_hier_method} = $hier_neighbor_status_size{$log_hier_host}{$log_hier_method} = $hier_neighbor_status_time{$log_hier_host}{$log_hier_method} = 0 unless defined $hier_neighbor_status{$log_hier_host}{$log_hier_method}; $hier_neighbor_status{$log_hier_host}{$log_hier_method}++; $hier_neighbor_status_size{$log_hier_host}{$log_hier_method} += $log_size; $hier_neighbor_status_time{$log_hier_host}{$log_hier_method} += $log_reqtime;' if ($opt_s); $loop .= ' } else { chomp($log_hier_method); unless ( defined $errormsg ) { print STDERR " Please check the following error(s). If you\'re sure that the offending line(s) are NOT corrupt and the error also occurs with the recent version of Calamaris (see the README for pointers and known bugs) then report them. Don\'t send me thousands of similar errors. use . Thank You. " unless $errormsg; $errormsg = 1; } warn( " unknown log_hier_method: \"$log_hier_method\" found in line $counter of input: $line" ); } } } }'; $time_run = time - $time_run; print STDERR "$loop\n" if $opt_L; eval $loop; die $@ if $@; $time_run = time - $time_run; } ### Yea! File read. Now for something completely different ;-) if ( $counter == 0 ) { print "\nno requests found\n"; exit(0); } $loginterval = convertdate($time_begin) . ' - ' . convertdate($time_end); $timestamp = convertdate($time_begin,1) . '-' . convertdate($time_end,1); if ($path) { $path =~ s#%t#$timestamp#g if $timestamp; $path =~ s#%h#$host_name#g if $host_name; $path =~ s#%%#%#g; } if ($filename) { $filename =~ s#%t#$timestamp#g if $timestamp; $filename =~ s#%h#$host_name#g if $host_name; $filename =~ s#%%#%#g; } if ($file_prefix) { $file_prefix =~ s#%t#$timestamp#g if $timestamp; $file_prefix =~ s#%h#$host_name#g if $host_name; $file_prefix =~ s#%%#%#g; } open( CACHE, ">$opt_o" ) or die ("$0: can't open $opt_o for writing: $!\n") if ($opt_o); # Summary $report_index = 0; @format = ( 53, 14, 10 ); writecache( $report_index, $time_begin, $time_end, $counter, $size, $time, $invalid, $time_run, $udp, $udp_size, $udp_time, $udp_hit, $udp_hit_size, $udp_hit_time, $udp_miss, $udp_miss_size, $udp_miss_time, $tcp, $tcp_size, $tcp_time, $tcp_hit, $tcp_hit_size, $tcp_hit_time, $tcp_miss, $tcp_miss_size, $tcp_miss_time, $tcp_miss_none, $tcp_miss_none_size, $tcp_miss_none_time, $hier, $hier_size, $hier_time, $hier_direct, $hier_direct_size, $hier_direct_time, $hier_sibling, $hier_sibling_size, $hier_sibling_time, $hier_parent, $hier_parent_size, $hier_parent_time ); outstart($report_index); outheader( $report_index, 'Calamaris statistics', '', '' ); outseperator($report_index); outline( $report_index, '', 'lines parsed:', 'lines', $counter ); outline( $report_index, '', 'invalid lines:', 'lines', $invalid ); outline( $report_index, '', 'skipped lines:', 'lines', $skipped ) if ($opt_I or $opt_ipfilter_exclude or $opt_ipfilter_include); outline( $report_index, '', 'parse time:', 'sec', $time_run ); outline( $report_index, '', 'parse speed:', 'lines/sec', $time_run ? ( $counter + $invalid + $skipped ) / $time_run : ( $counter + $invalid + $skipped ) ); outseperator($report_index); outheader( $report_index, 'Proxy statistics', '', '' ); outseperator($report_index); outline( $report_index, '', 'Total amount:', 'requests', $tcp + $udp); outline( $report_index, '', 'unique hosts/users:', 'hosts', scalar keys %tcp_requester ) if $opt_r; outline( $report_index, '', 'Total Bandwidth:', 'Byte', kilomegagigatera( $tcp_size + $udp_size, $format[2] ) ); @format = ( 53, 14, '10%' ); $peak_all_hour_size_time = ( sort { $peak_all_hour_size{$b} <=> $peak_all_hour_size{$a} } keys(%peak_all_hour_size) )[0] or $peak_all_hour_size_time = $peak_all_hour_size{0} = 0; outline( $report_index, '', 'Max. Bandwidth usage:', 'MBit/sec', $peak_all_hour_size{$peak_all_hour_size_time} * 8 / ( 1024**2 * 3600 ) ) if $opt_p; outline( $report_index, '', 'Proxy efficiency (HIT [kB/sec] / DIRECT [kB/sec]):', 'factor', ($tcp_hit_time and ($tcp_miss_size + $tcp_miss_none_size)) ? $tcp_hit_size/$tcp_hit_time * ($tcp_miss_none_time + $tcp_miss_time) / ($tcp_miss_size + $tcp_miss_none_size) : 0 ); outline( $report_index, '', 'Average speed increase:', '%', ($tcp_miss_size + $tcp_miss_none_size) ? 100 * ( -1 + $tcp_size/$tcp_time * ($tcp_miss_none_time + $tcp_miss_time) / ($tcp_miss_size + $tcp_miss_none_size)) : 0 ); @format = ( 53, 14, 10 ); if ($opt_response_time) { # average response time $reqtime_sum = $reqtime_num = $avg_udp_reqtime = $avg_tcp_reqtime = 0; my $skipped = 0; foreach $reqtime ( keys %udp_reqtime ) { if ($reqtime > $response_time_limit) { $skipped += $tcp_reqtime{$reqtime}; next; } $reqtime_sum += $reqtime * $udp_reqtime{$reqtime}; $reqtime_num += $tcp_reqtime{$reqtime} if $tcp_reqtime{$reqtime}; } $avg_udp_reqtime = ($reqtime_num) ? $reqtime_sum / $reqtime_num : '0'; my $time_skipped = ($response_time_limit == $response_time_report_interval[$#response_time_report_interval]) ? '' : " (requests > $response_time_limit msec skipped)"; my $skipped_percent = (($skipped+$reqtime_num) ? round(100*$reqtime_num/($skipped+$reqtime_num),2) : 100 ) . ' percent'; outline( $report_index, '', "UDP response time of $skipped% requests$time_skipped:", 'msec', kilomegagigatera( $avg_udp_reqtime, $format[2] ) ) if ($avg_udp_reqtime); $skipped = 0; $reqtime_sum = $reqtime_num = 0; foreach $reqtime ( keys %tcp_reqtime ) { if ($reqtime > $response_time_limit) { $skipped += $tcp_reqtime{$reqtime}; next; } $reqtime_sum += $reqtime * $tcp_reqtime{$reqtime}; $reqtime_num += $tcp_reqtime{$reqtime}; } $avg_tcp_reqtime = ($reqtime_num) ? $reqtime_sum / $reqtime_num : '0'; $skipped_percent = (($skipped+$reqtime_num) ? round(100*$reqtime_num/($skipped+$reqtime_num),2) : 100 ) . '%'; outline( $report_index, '', "TCP response time of $skipped_percent requests$time_skipped:", 'msec', kilomegagigatera( $avg_tcp_reqtime, $format[2] ) ) if ($avg_tcp_reqtime); } outseperator($report_index); outheader( $report_index, 'Cache statistics', '', ''); outseperator($report_index); outline( $report_index, '', 'Total amount cached:', 'requests', $tcp_hit + $udp_hit ); @format = ( 53, 14, '10%' ); outline( $report_index, '', 'Request hit rate:', '%', ($tcp + $udp) ? 100 * ($tcp_hit + $udp_hit) / ($tcp + $udp) : 0 ); @format = ( 53, 14, 10 ); outline( $report_index, '', 'Bandwidth savings:', 'Byte', kilomegagigatera( $tcp_hit_size + $udp_hit_size, $format[2] ) ); @format = ( 53, 14, '10%' ); outline( $report_index, '', 'Bandwidth savings in Percent (Byte hit rate):', '%', ($tcp_size + $udp_size) ? 100 * ($tcp_hit_size + $udp_hit_size) / ($tcp_size + $udp_size) : 0 ); @format = ( 53, 14, 10 ); if ($opt_D) { # Object sizes $cached_obj_size = $cached_obj_num = $obj_size = $obj_num = $avg_cached_obj_size = $avg_direct_obj_size = $avg_all_obj_size = 0; foreach $distribution ( sort { $a <=> $b } keys(%tcp_distribution) ) { $cached_obj_size += $tcp_hit_distribution_size{$distribution}; $cached_obj_num += $tcp_hit_distribution{$distribution}; $obj_size += $tcp_distribution_size{$distribution}; $obj_num += $tcp_distribution{$distribution}; } $avg_cached_obj_size = $cached_obj_size / $cached_obj_num if $cached_obj_num; $avg_direct_obj_size = ($obj_size - $cached_obj_size) / ($obj_num - $cached_obj_num) if $obj_num - $cached_obj_num; $avg_all_obj_size = $obj_size / $obj_num if $obj_num; outline( $report_index, '', 'Average cached object size:', 'Byte', kilomegagigatera( $avg_cached_obj_size, $format[2] ) ); outline( $report_index, '', 'Average direct object size:', 'Byte', kilomegagigatera( $avg_direct_obj_size, $format[2] ) ); outline( $report_index, '', 'Average object size:', 'Byte', kilomegagigatera( $avg_all_obj_size, $format[2] ) ); } $max_value[$report_index] = '- - -'; outseperator($report_index); outstop($report_index); # Incoming request peak per protocol $report_index = 1; @format = ( 3, 4, 18, 5, 18, 7, 18 ); if ( not defined $opt_p ) { } elsif ( $opt_p eq 'old' ) { writecache( $report_index, $peak_udp_sec, $peak_udp_sec_time, $peak_udp_min, $peak_udp_min_time, $peak_udp_hour, $peak_udp_hour_time, $peak_tcp_sec, $peak_tcp_sec_time, $peak_tcp_min, $peak_tcp_min_time, $peak_tcp_hour, $peak_tcp_hour_time, $peak_all_sec, $peak_all_sec_time, $peak_all_min, $peak_all_min_time, $peak_all_hour, $peak_all_hour_time ); outstart($report_index); outheader( $report_index, 'prt', ' sec', 'peak begins at', ' min', 'peak begins at', ' hour', 'peak begins at' ); outseperator($report_index); outline( $report_index, '', 'UDP', $peak_udp_sec, convertdate($peak_udp_sec_time), $peak_udp_min, convertdate($peak_udp_min_time), $peak_udp_hour, convertdate($peak_udp_hour_time) ); outline( $report_index, '', 'TCP', $peak_tcp_sec, convertdate($peak_tcp_sec_time), $peak_tcp_min, convertdate($peak_tcp_min_time), $peak_tcp_hour, convertdate($peak_tcp_hour_time) ); outseperator($report_index); outline( $report_index, '', 'ALL', $peak_all_sec, convertdate($peak_all_sec_time), $peak_all_min, convertdate($peak_all_min_time), $peak_all_hour, convertdate($peak_all_hour_time) ); $max_value[$report_index] = '- - -'; outstop($report_index); } elsif ( $opt_p eq 'new' ) { $peak_udp_hour_time = ( sort { $peak_udp_hour{$b} <=> $peak_udp_hour{$a} } keys(%peak_udp_hour) )[0] or $peak_udp_hour_time = $peak_udp_hour{0} = 0; $peak_udp_hour_size_time = ( sort { $peak_udp_hour_size{$b} <=> $peak_udp_hour_size{$a} } keys(%peak_udp_hour_size) )[0] or $peak_udp_hour_size_time = $peak_udp_hour_size{0} = 0; $peak_tcp_hour_time = ( sort { $peak_tcp_hour{$b} <=> $peak_tcp_hour{$a} } keys(%peak_tcp_hour) )[0] or $peak_tcp_hour_time = $peak_tcp_hour{0} = 0; $peak_tcp_hour_size_time = ( sort { $peak_tcp_hour_size{$b} <=> $peak_tcp_hour_size{$a} } keys(%peak_tcp_hour_size) )[0] or $peak_tcp_hour_size_time = $peak_tcp_hour_size{0} = 0; $peak_all_hour_time = ( sort { $peak_all_hour{$b} <=> $peak_all_hour{$a} } keys(%peak_all_hour) )[0] or $peak_all_hour_time = $peak_all_hour{0} = 0; $peak_all_hour_size_time = ( sort { $peak_all_hour_size{$b} <=> $peak_all_hour_size{$a} } keys(%peak_all_hour_size) )[0] or $peak_all_hour_size_time = $peak_all_hour_size{0} = 0; writecache( $report_index, $peak_udp_sec, $peak_udp_sec_time, $peak_udp_min, $peak_udp_min_time, $peak_udp_hour{$peak_udp_hour_time}, $peak_udp_hour_time, $peak_udp_hour_size{$peak_udp_hour_size_time}, $peak_udp_hour_size_time, $peak_tcp_sec, $peak_tcp_sec_time, $peak_tcp_min, $peak_tcp_min_time, $peak_tcp_hour{$peak_tcp_hour_time}, $peak_tcp_hour_time, $peak_tcp_hour_size{$peak_tcp_hour_size_time}, $peak_tcp_hour_size_time, $peak_all_sec, $peak_all_sec_time, $peak_all_min, $peak_all_min_time, $peak_all_hour{$peak_all_hour_time}, $peak_all_hour_time, $peak_all_hour_size{$peak_all_hour_size_time}, $peak_all_hour_size_time ); outstart($report_index); outheader( $report_index, 'prt', ' sec', 'peak begins at', ' min', 'peak begins at', ' hour', 'peak begins at' ); outseperator($report_index); outline( $report_index, '', 'UDP', $peak_udp_sec, convertdate($peak_udp_sec_time), $peak_udp_min, convertdate($peak_udp_min_time), $peak_udp_hour{$peak_udp_hour_time}, convertdate($peak_udp_hour_time) ); outline( $report_index, '', 'TCP', $peak_tcp_sec, convertdate($peak_tcp_sec_time), $peak_tcp_min, convertdate($peak_tcp_min_time), $peak_tcp_hour{$peak_tcp_hour_time}, convertdate($peak_tcp_hour_time) ); outseperator($report_index); outline( $report_index, '', 'ALL', $peak_all_sec, convertdate($peak_all_sec_time), $peak_all_min, convertdate($peak_all_min_time), $peak_all_hour{$peak_all_hour_time}, convertdate($peak_all_hour_time) ); $max_value[$report_index] = '- - -'; outstop($report_index); # Incoming transfer volume per protocol $report_index = 2; @format = ( 5, 8, 18 ); outstart($report_index); outheader( $report_index, 'proto', ' kB/hour', 'peak begins at' ); outseperator($report_index); outline( $report_index, '', 'UDP', $peak_udp_hour_size{$peak_udp_hour_size_time} / 1024, convertdate($peak_udp_hour_size_time) ); outline( $report_index, '', 'TCP', $peak_tcp_hour_size{$peak_tcp_hour_size_time} / 1024, convertdate($peak_tcp_hour_size_time) ); outseperator($report_index); outline( $report_index, '', 'ALL', $peak_all_hour_size{$peak_all_hour_size_time} / 1024, convertdate($peak_all_hour_size_time) ); $max_value[$report_index] = '- - -'; outstop($report_index); } # Incoming requests by method $report_index = 3; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 30, 9, '%', 'spr', 8, '%', 'kbps' ); outstart($report_index); if ( $counter == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); outimg($report_index) if ($outtype_graph); outheader( $report_index, 'method', ' request', '% ', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '% ', 'auto' ); outseperator($report_index); foreach $method ( sort { ${"method$sortorder"}{$b} <=> ${"method$sortorder"}{$a} } keys(%method) ) { push @xaxis, $method; push @yaxis1, $method{$method}; push @yaxis2, $method_size{$method}; writecache( $report_index, $method, $method{$method}, $method_size{$method}, $method_time{$method} ); outline( $report_index, 'toggle', $method, $method{$method}, 100 * $method{$method} / $counter, $method_time{$method} / ( 1000 * $method{$method} ), kilomegagigatera( $method_size{$method}, $format[4] ), $size ? 100 * $method_size{$method} / $size : 0, $method_size{$method} / ( 1.024 * $method_time{$method} ) ); } outseperator($report_index); outline( $report_index, '2', 'Sum', $counter, 100, $time / ( $counter * 1000 ), kilomegagigatera( $size, $format[4] ), 100, $size / ( 1.024 * $time ) ); outgraph($report_index, \@graph_legend, $x_scale, \@xaxis, \@yaxis1, \@yaxis2) if ($outtype_graph and $xaxis[0]); $max_value[$report_index] = 'most requested method ' . htmlescape($xaxis[0]) . ' ' . ($opt_O ? kilomegagigatera($yaxis2[0], 6) . ' Byte' : $yaxis1[0] . ' Requests' ); } outstop($report_index); # Incoming UDP-requests by status $report_index = 4; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 30, 9, '%', 'mspr', 8, '%', 'kbps' ); outstart($report_index); if ( $udp == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); outimg($report_index) if ($outtype_graph); outheader( $report_index, 'status', ' request', '% ', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '% ', 'auto' ); outseperator($report_index); if ( $udp_hit == 0 ) { outline( $report_index, '', 'HIT', 0, 0, 0, 0, 0, 0 ); push @xaxis, 'HIT'; push @yaxis1, 0; push @yaxis2, 0; } else { push @xaxis, 'HIT'; push @yaxis1, $udp_hit; push @yaxis2, $udp_hit_size; outline( $report_index, '', 'HIT', $udp_hit, 100 * $udp_hit / $udp, $udp_hit_time / (1000 * $udp_hit), kilomegagigatera( $udp_hit_size, $format[4] ), $udp_size ? 100 * $udp_hit_size / $udp_size : 0, $udp_hit_size / ( 1.024 * $udp_hit_time ) ); foreach $hitfail ( sort { ${"udp_hit$sortorder"}{$b} <=> ${"udp_hit$sortorder"}{$a} } keys(%udp_hit) ) { writecache( "$report_index.1", $hitfail, $udp_hit{$hitfail}, $udp_hit_size{$hitfail}, $udp_hit_time{$hitfail} ); outline( $report_index, '', ' ' . $hitfail, $udp_hit{$hitfail}, 100 * $udp_hit{$hitfail} / $udp, $udp_hit_time{$hitfail} / (1000 * $udp_hit{$hitfail}), kilomegagigatera( $udp_hit_size{$hitfail}, $format[4] ), $udp_size ? 100 * $udp_hit_size{$hitfail} / $udp_size : 0, $udp_hit_size{$hitfail} / ( 1.024 * $udp_hit_time{$hitfail} ) ); } } if ( $udp_miss == 0 ) { outline( $report_index, '', 'MISS', 0, 0, 0, 0, 0, 0 ); push @xaxis, 'MISS'; push @yaxis1, $udp_miss; push @yaxis2, $udp_miss_size; } else { push @xaxis, 'MISS'; push @yaxis1, $udp_miss; push @yaxis2, $udp_miss_size; outline( $report_index, '', 'MISS', $udp_miss, 100 * $udp_miss / $udp, $udp_miss_time / (1000 * $udp_miss), kilomegagigatera( $udp_miss_size, $format[4] ), $udp_size ? 100 * $udp_miss_size / $udp_size : 0, $udp_miss_size / ( 1.024 * $udp_miss_time ) ); foreach $hitfail ( sort { ${"udp_miss$sortorder"}{$b} <=> ${"udp_miss$sortorder"}{$a} } keys(%udp_miss) ) { writecache( "$report_index.2", $hitfail, $udp_miss{$hitfail}, $udp_miss_size{$hitfail}, $udp_miss_time{$hitfail} ); outline( $report_index, '', ' ' . $hitfail, $udp_miss{$hitfail}, 100 * $udp_miss{$hitfail} / $udp, $udp_miss_time{$hitfail} / (1000 * $udp_miss{$hitfail}), kilomegagigatera( $udp_miss_size{$hitfail}, $format[4] ), $udp_size ? 100 * $udp_miss_size{$hitfail} / $udp_size : 0, $udp_miss_size{$hitfail} / ( 1.024 * $udp_miss_time{$hitfail} ) ); } } outseperator($report_index); outline( $report_index, '2', 'Sum', $udp, 100, $udp_time / (1000 * $udp), kilomegagigatera( $udp_size, $format[4] ), 100, $udp_size / ( 1.024 * $udp_time ) ); outgraph( $report_index, \@graph_legend, $x_scale, \@xaxis, \@yaxis1, \@yaxis2) if ($outtype_graph and $xaxis[0]); # find max value my ($max, $maxi) = ($opt_O) ? maxi(@yaxis2) : maxi(@yaxis1); if (defined($maxi) and defined($xaxis[$maxi])) { $max_value[$report_index] = 'most incoming request by status to ' . htmlescape($xaxis[$maxi]) . ' ' . ($opt_O ? kilomegagigatera($yaxis2[$maxi], 6) . ' Byte' : $yaxis1[$maxi] . ' Requests'); } } outstop($report_index); # Incoming TCP-requests by status $report_index = 5; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 30, 9, '%', 'spr', 8, '%', 'kbps' ); outstart($report_index); if ( $tcp_hit + $tcp_miss + $tcp_miss_none == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); outimg($report_index) if ($outtype_graph); outheader( $report_index, 'status', ' request', '% ', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '% ', 'auto' ); outseperator($report_index); if ( $tcp_hit == 0 ) { outline( $report_index, '', 'HIT', 0, 0, 0, 0, 0, 0 ); push @xaxis, 'HIT'; push @yaxis1, 0; push @yaxis2, 0; } else { push @xaxis, 'HIT'; push @yaxis1, $tcp_hit; push @yaxis2, $tcp_hit_size; outline( $report_index, 'toggle', 'HIT', $tcp_hit, 100 * $tcp_hit / $tcp, $tcp_hit_time / ( 1000 * $tcp_hit ), kilomegagigatera( $tcp_hit_size, $format[4] ), $tcp_size ? 100 * $tcp_hit_size / $tcp_size : 0, $tcp_hit_size / ( 1.024 * $tcp_hit_time ) ); foreach $hitfail ( sort { ${"tcp_hit$sortorder"}{$b} <=> ${"tcp_hit$sortorder"}{$a} } keys(%tcp_hit) ) { writecache( "$report_index.1", $hitfail, $tcp_hit{$hitfail}, $tcp_hit_size{$hitfail}, $tcp_hit_time{$hitfail} ); outline( $report_index, 'toggle', ' ' . $hitfail, $tcp_hit{$hitfail}, 100 * $tcp_hit{$hitfail} / $tcp, $tcp_hit_time{$hitfail} / ( 1000 * $tcp_hit{$hitfail} ), kilomegagigatera( $tcp_hit_size{$hitfail}, $format[4] ), $tcp_size ? 100 * $tcp_hit_size{$hitfail} / $tcp_size : 0, $tcp_hit_size{$hitfail} / ( 1.024 * $tcp_hit_time{$hitfail} ) ); } } if ( $tcp_miss == 0 ) { outline( $report_index, '', 'MISS', 0, 0, 0, 0, 0, 0 ); push @xaxis, 'MISS'; push @yaxis1, 0; push @yaxis2, 0; } else { push @xaxis, 'MISS'; push @yaxis1, $tcp_miss; push @yaxis2, $tcp_miss_size; outline( $report_index, 'toggle', 'MISS', $tcp_miss, 100 * $tcp_miss / $tcp, $tcp_miss_time / ( 1000 * $tcp_miss ), kilomegagigatera( $tcp_miss_size, $format[4] ), $tcp_size ? 100 * $tcp_miss_size / $tcp_size : 0, $tcp_miss_size / ( 1.024 * $tcp_miss_time ) ); foreach $hitfail ( sort { ${"tcp_miss$sortorder"}{$b} <=> ${"tcp_miss$sortorder"}{$a} } keys(%tcp_miss) ) { writecache( "$report_index.2", $hitfail, $tcp_miss{$hitfail}, $tcp_miss_size{$hitfail}, $tcp_miss_time{$hitfail} ); outline( $report_index, 'toggle', ' ' . $hitfail, $tcp_miss{$hitfail}, 100 * $tcp_miss{$hitfail} / $tcp, $tcp_miss_time{$hitfail} / ( 1000 * $tcp_miss{$hitfail} ), kilomegagigatera( $tcp_miss_size{$hitfail}, $format[4] ), $tcp_size ? 100 * $tcp_miss_size{$hitfail} / $tcp_size : 0, $tcp_miss_size{$hitfail} / ( 1.024 * $tcp_miss_time{$hitfail} ) ); } } if ( $tcp_miss_none == 0 ) { outline( $report_index, '', 'ERROR', 0, 0, 0, 0, 0, 0 ); push @xaxis, 'ERROR'; push @yaxis1, 0; push @yaxis2, 0; } else { push @xaxis, 'ERROR'; push @yaxis1, $tcp_miss_none; push @yaxis2, $tcp_miss_none_size; outline( $report_index, 'toggle', 'ERROR', $tcp_miss_none, 100 * $tcp_miss_none / $tcp, $tcp_miss_none_time / ( 1000 * $tcp_miss_none ), kilomegagigatera( $tcp_miss_none_size, $format[4] ), $tcp_size ? 100 * $tcp_miss_none_size / $tcp_size : 0, $tcp_miss_none_size / ( 1.024 * $tcp_miss_none_time ) ); foreach $hitfail ( sort { ${"tcp_miss_none$sortorder"}{$b} <=> ${"tcp_miss_none$sortorder"}{$a} } keys(%tcp_miss_none) ) { writecache( "$report_index.3", $hitfail, $tcp_miss_none{$hitfail}, $tcp_miss_none_size{$hitfail}, $tcp_miss_none_time{$hitfail} ); outline( $report_index, 'toggle', ' ' . $hitfail, $tcp_miss_none{$hitfail}, 100 * $tcp_miss_none{$hitfail} / $tcp, $tcp_miss_none_time{$hitfail} / ( 1000 * $tcp_miss_none{$hitfail} ), kilomegagigatera( $tcp_miss_none_size{$hitfail}, $format[4] ), $tcp_size ? 100 * $tcp_miss_none_size{$hitfail} / $tcp_size : 0, $tcp_miss_none_size{$hitfail} / ( 1.024 * $tcp_miss_none_time{$hitfail} ) ); } } outseperator($report_index); outline( $report_index, '2', 'Sum', $tcp, 100, $tcp_time / ( 1000 * $tcp ), kilomegagigatera( $tcp_size, $format[4] ), 100, $tcp_size / ( 1.024 * $tcp_time ) ); outgraph( $report_index, \@graph_legend, $x_scale, \@xaxis, \@yaxis1, \@yaxis2) if ($outtype_graph and $xaxis[0]); # find max value my ($max, $maxi) = ($opt_O) ? maxi(@yaxis2) : maxi(@yaxis1); if (defined($maxi) and defined($xaxis[$maxi])) { $max_value[$report_index] = 'most incoming request by status to ' . htmlescape($xaxis[$maxi]) . ' ' . ($opt_O ? kilomegagigatera($yaxis2[$maxi], 6) . " Byte" : $yaxis1[$maxi]. " Requests" ); } } outstop($report_index); # Outgoing requests by status $report_index = 6; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 30, 9, '%', 'spr', 8, '%', 'kbps' ); outstart($report_index); if ( $hier == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); outimg($report_index) if ($outtype_graph); outheader( $report_index, 'status', ' request', '% ', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '% ', 'auto' ); outseperator($report_index); if ( $hier_direct == 0 ) { outline( $report_index, '', 'DIRECT', 0, 0, 0, 0, 0, 0 ); push @xaxis, 'DIRECT'; push @yaxis1, 0; push @yaxis2, 0; } else { push @xaxis, 'DIRECT Fetch from Source'; push @yaxis1, $hier_direct; push @yaxis2, $hier_direct_size; outline( $report_index, 'toggle', 'DIRECT Fetch from Source', $hier_direct, 100 * $hier_direct / $hier, $hier_direct_time / ( 1000 * $hier_direct ), kilomegagigatera( $hier_direct_size, $format[4] ), $hier_size ? 100 * $hier_direct_size / $hier_size : 0, $hier_direct_size / ( 1.024 * $hier_direct_time ) ); foreach $hitfail ( sort { ${"hier_direct$sortorder"}{$b} <=> ${"hier_direct$sortorder"}{$a} } keys(%hier_direct) ) { writecache( "$report_index.1", $hitfail, $hier_direct{$hitfail}, $hier_direct_size{$hitfail}, $hier_direct_time{$hitfail} ); outline( $report_index, 'toggle', ' ' . $hitfail, $hier_direct{$hitfail}, 100 * $hier_direct{$hitfail} / $hier, $hier_direct_time{$hitfail} / ( 1000 * $hier_direct{$hitfail} ), kilomegagigatera( $hier_direct_size{$hitfail}, $format[4] ), $hier_size ? 100 * $hier_direct_size{$hitfail} / $hier_size : 0, $hier_direct_size{$hitfail} / ( 1.024 * $hier_direct_time{$hitfail} ) ); } } if ( $hier_sibling == 0 ) { outline( $report_index, '', 'SIBLING', 0, 0, 0, 0, 0, 0 ); push @xaxis, 'SIBLING'; push @yaxis1, 0; push @yaxis2, 0; } else { push @xaxis, 'HIT on Sibling or Parent Cache'; push @yaxis1, $hier_sibling; push @yaxis2, $hier_sibling_size; outline( $report_index, 'toggle', 'HIT on Sibling or Parent Cache', $hier_sibling, 100 * $hier_sibling / $hier, $hier_sibling_time / ( 1000 * $hier_sibling ), kilomegagigatera( $hier_sibling_size, $format[4] ), $hier_size ? 100 * $hier_sibling_size / $hier_size : 0, $hier_sibling_size / ( 1.024 * $hier_sibling_time ) ); foreach $hitfail ( sort { ${"hier_sibling$sortorder"}{$b} <=> ${"hier_sibling$sortorder"}{$a} } keys(%hier_sibling) ) { writecache( "$report_index.2", $hitfail, $hier_sibling{$hitfail}, $hier_sibling_size{$hitfail}, $hier_sibling_time{$hitfail} ); outline( $report_index, 'toggle', ' ' . $hitfail, $hier_sibling{$hitfail}, 100 * $hier_sibling{$hitfail} / $hier, $hier_sibling_time{$hitfail} / ( 1000 * $hier_sibling{$hitfail} ), kilomegagigatera( $hier_sibling_size{$hitfail}, $format[4] ), $hier_size ? 100 * $hier_sibling_size{$hitfail} / $hier_size : 0, $hier_sibling_size{$hitfail} / ( 1.024 * $hier_sibling_time{$hitfail} ) ); } } if ( $hier_parent == 0 ) { outline( $report_index, '', 'PARENT', 0, 0, 0, 0, 0, 0 ); push @xaxis, 'PARENT'; push @yaxis1, 0; push @yaxis2, 0; } else { push @xaxis, 'FETCH from Parent Cache'; push @yaxis1, $hier_parent; push @yaxis2, $hier_parent_size; outline( $report_index, 'toggle', 'FETCH from Parent Cache', $hier_parent, 100 * $hier_parent / $hier, $hier_parent_time / ( 1000 * $hier_parent ), kilomegagigatera( $hier_parent_size, $format[4] ), $hier_size ? 100 * $hier_parent_size / $hier_size : 0, $hier_parent_size / ( 1.024 * $hier_parent_time ) ); foreach $hitfail ( sort { ${"hier_parent$sortorder"}{$b} <=> ${"hier_parent$sortorder"}{$a} } keys(%hier_parent) ) { writecache( "$report_index.3", $hitfail, $hier_parent{$hitfail}, $hier_parent_size{$hitfail}, $hier_parent_time{$hitfail} ); outline( $report_index, 'toggle', ' ' . $hitfail, $hier_parent{$hitfail}, 100 * $hier_parent{$hitfail} / $hier, $hier_parent_time{$hitfail} / ( 1000 * $hier_parent{$hitfail} ), kilomegagigatera( $hier_parent_size{$hitfail}, $format[4] ), $hier_size ? 100 * $hier_parent_size{$hitfail} / $hier_size : 0, $hier_parent_size{$hitfail} / ( 1.024 * $hier_parent_time{$hitfail} ) ); } } outseperator($report_index); outline( $report_index, '2', 'Sum', $hier, 100, $hier_time / ( 1000 * $hier ), kilomegagigatera( $hier_size, $format[4] ), 100, $hier_size / ( 1.024 * $hier_time ) ); outgraph($report_index, \@graph_legend, $x_scale, \@xaxis, \@yaxis1, \@yaxis2) if ($outtype_graph and $xaxis[0]); # find max value my ($max, $maxi) = ($opt_O) ? maxi(@yaxis2) : maxi(@yaxis1); if (defined($maxi) and defined($xaxis[$maxi])) { $max_value[$report_index] = 'most outgoing request to ' . htmlescape($xaxis[$maxi]) . ' ' . ($opt_O ? kilomegagigatera($yaxis2[$maxi], 6) . ' Byte' : $yaxis1[$maxi]. ' Requests' ); } } outstop($report_index); # Outgoing requests by destination $report_index = 7; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 30, 9, '%', 'spr', 8, '%', 'kbps' ); outstart($report_index); if ( $hier == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); outimg($report_index) if ($outtype_graph); outheader( $report_index, 'neighbor type', ' request', '% ', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '% ', 'auto' ); outseperator($report_index); outline( $report_index, 'toggle', 'DIRECT', $hier_direct, 100 * $hier_direct / $hier, $hier_direct_time / ( 1000 * $hier_direct ), kilomegagigatera( $hier_direct_size, $format[4] ), $hier_size ? 100 * $hier_direct_size / $hier_size : 0, $hier_direct_size / ( 1.024 * $hier_direct_time ) ) unless $hier_direct == 0; push @xaxis, 'DIRECT' unless $hier_direct == 0; push @yaxis1, $hier_direct unless $hier_direct == 0; push @yaxis2, $hier_direct_size unless $hier_direct == 0; foreach $neighbor ( sort { ${"hier_neighbor$sortorder"}{$b} <=> ${"hier_neighbor$sortorder"}{$a} } keys(%hier_neighbor) ) { push @xaxis, $neighbor; push @yaxis1, $hier_neighbor{$neighbor}; push @yaxis2, $hier_neighbor_size{$neighbor}; writecache( "$report_index.1", $neighbor, $hier_neighbor{$neighbor}, $hier_neighbor_size{$neighbor}, $hier_neighbor_time{$neighbor} ); outline( $report_index, 'toggle', $neighbor, $hier_neighbor{$neighbor}, 100 * $hier_neighbor{$neighbor} / $hier, $hier_neighbor_time{$neighbor} / ( 1000 * $hier ), kilomegagigatera( $hier_neighbor_size{$neighbor}, $format[4] ), $hier_size ? 100 * $hier_neighbor_size{$neighbor} / $hier_size : 0, $hier_neighbor_size{$neighbor} / ( 1.024 * $hier_neighbor_time{$neighbor} ) ); foreach $status ( sort { ${"hier_neighbor_status$sortorder"}{$neighbor}{$b} <=> ${"hier_neighbor_status$sortorder"}{$neighbor}{$a} } keys(%{$hier_neighbor_status{$neighbor} } ) ) { writecache( "$report_index.2", $neighbor, $status, $hier_neighbor_status{$neighbor}{$status}, $hier_neighbor_status_size{$neighbor}{$status}, $hier_neighbor_status_time{$neighbor}{$status} ); outline( $report_index, 'toggle', ' ' . $status, $hier_neighbor_status{$neighbor}{$status}, 100 * $hier_neighbor_status{$neighbor}{$status} / $hier, $hier_neighbor_status_time{$neighbor}{$status} / ( 1000 * $hier_neighbor_status{$neighbor}{$status} ), kilomegagigatera( $hier_neighbor_status_size{$neighbor}{$status}, $format[4] ), $hier_size ? 100 * $hier_neighbor_status_size{$neighbor}{$status} / $hier_size : 0, $hier_neighbor_status_size{$neighbor}{$status} / ( 1.024 * $hier_neighbor_status_time{$neighbor}{$status} ) ); } } outseperator($report_index); outline( $report_index, '2', 'Sum', $hier, 100, $hier_time / ( 1000 * $hier ), kilomegagigatera( $hier_size, $format[4] ), 100, $hier_size / ( 1.024 * $hier_time ) ); outgraph( $report_index, \@graph_legend, $x_scale, \@xaxis, \@yaxis1, \@yaxis2) if ($outtype_graph and $xaxis[0]); # find max value my ($max, $maxi) = ($opt_O) ? maxi(@yaxis2) : maxi(@yaxis1); if (defined($maxi) and defined($xaxis[$maxi])) { $max_value[$report_index] = 'most requested destination ' . htmlescape($xaxis[$maxi]) . ' ' . ($opt_O ? kilomegagigatera($yaxis2[$maxi], 6) . ' Byte' : $yaxis1[$maxi] . ' Requests'); } } outstop($report_index); # Request-destinations by ${N}-level-domain $report_index = 8; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 32, 9, '%', '%', 'off', 8, '%', '%', 'off' ); if ($opt_d) { outstart($report_index); if ( $tcp == 0 ) { outline( $report_index, '', 'no matching requests' ); outstop($report_index); } else { my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); $max_x_data = ($opt_d < $x_scale and $opt_d != -1) ? $opt_d : $x_scale; $i = 0; outimg($report_index) if ($outtype_graph); @counter = keys %tcp_urlhost; $other_urlhost = $#counter + 1; $other = $tcp; $other_size = $tcp_size; $other_hit = $tcp_hit; $other_time = $tcp_time; $other_hit_size = $tcp_hit_size; $other_count = $opt_d; outheader( $report_index, 'destination', ' request', '% ', 'hit-%', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '% ', 'hit-%', 'auto' ); outseperator($report_index); foreach $urlhost ( sort { ${"tcp_urlhost$sortorder"}{$b} <=> ${"tcp_urlhost$sortorder"}{$a} } keys(%tcp_urlhost) ) { next if $urlhost eq ''; $other_urlhost--; $other -= $tcp_urlhost{$urlhost}; $other_size -= $tcp_urlhost_size{$urlhost}; $other_time -= $tcp_urlhost_time{$urlhost}; $other_hit -= $tcp_hit_urlhost{$urlhost}; $other_hit_size -= $tcp_hit_urlhost_size{$urlhost}; $i++; push @xaxis, $urlhost if ($i < $max_x_data); push @yaxis1, $tcp_urlhost{$urlhost} if ($i < $max_x_data); push @yaxis2, $tcp_urlhost_size{$urlhost} if ($i < $max_x_data); push @yaxis3, $tcp_urlhost{$urlhost} ? $tcp_hit_urlhost{$urlhost} / $tcp_urlhost{$urlhost} : 0 if ($i < $max_x_data); push @yaxis4, $tcp_urlhost_size{$urlhost} ? $tcp_hit_urlhost_size{$urlhost} / $tcp_urlhost_size{$urlhost} : 0 if ($i < $max_x_data); writecache( $report_index, $urlhost, $tcp_urlhost{$urlhost}, $tcp_urlhost_size{$urlhost}, $tcp_hit_urlhost{$urlhost}, $tcp_hit_urlhost_size{$urlhost}, $tcp_urlhost_time{$urlhost} ); outline( $report_index, 'toggle', $urlhost, $tcp_urlhost{$urlhost}, 100 * $tcp_urlhost{$urlhost} / $tcp, 100 * $tcp_hit_urlhost{$urlhost} / $tcp_urlhost{$urlhost}, $tcp_urlhost_time{$urlhost} / (1000 * $tcp_urlhost{$urlhost}), kilomegagigatera( $tcp_urlhost_size{$urlhost}, $format[5] ), $tcp_size ? 100 * $tcp_urlhost_size{$urlhost} / $tcp_size : 0, $tcp_urlhost_size{$urlhost} ? 100 * $tcp_hit_urlhost_size{$urlhost} / $tcp_urlhost_size{$urlhost} : 0, $tcp_urlhost_time{$urlhost} ? $tcp_urlhost_size{$urlhost} / ( 1.024 * $tcp_urlhost_time{$urlhost} ) : 0 ); last if ( ( --$other_count == 0 and $other != 1 ) or ($tcp_urlhost{$urlhost} < $opt_domain_report_limit) ); } if ($other) { push @xaxis, ''; push @yaxis1, $other; push @yaxis2, $other_size; push @yaxis3, $other ? $other_hit / $other : 0; push @yaxis4, $other_size ? $other_hit_size / $other_size : 0; $max_x_data = ( $opt_d < $x_scale and $opt_d != -1 ) ? $opt_d + 1 : $x_scale + 1; writecache( $report_index, '', $other, $other_size, $other_hit, $other_hit_size, $other_time ); $other_urlhost = '' unless $show_other_tcp_urlhost; outline( $report_index, '', 'other: ' . $other_urlhost . " $N-level-domains", $other, 100 * $other / $tcp, 100 * $other_hit / $other, $other_time / (1000 * $other), kilomegagigatera( $other_size, $format[5] ), $tcp_size ? 100 * $other_size / $tcp_size : 0, $other_size ? 100 * $other_hit_size / $other_size : 0, $other_size ? $other_size/ (1.024 * $other_time ) : 0 ); } outseperator($report_index); outline( $report_index, '2', 'Sum', $tcp, 100, 100 * $tcp_hit / $tcp, $tcp_time / (1000 * $tcp), kilomegagigatera( $tcp_size, $format[5] ), 100, $tcp_size ? 100 * $tcp_hit_size / $tcp_size : 0, $tcp_time ? $tcp_size / ( 1.024 * $tcp_time ) : 0 ); outgraph($report_index, \@graph_legend, $max_x_data, \@xaxis, \@yaxis1, \@yaxis2, \@yaxis3, \@yaxis4) if ($outtype_graph and $xaxis[0]); $max_value[$report_index] = "most requested $N-level-domain " . htmlescape($xaxis[0]) . ' ' . ($opt_O ? kilomegagigatera($yaxis2[0], 6) . ' Byte' : $yaxis1[0] . ' Requests'); test( $report_index, \%tcp_urlhost, \%tcp_urlhost_size, \%tcp_urlhost_time, 'tcp') if $test; outstop($report_index); # Request-destinations by toplevel-domain $report_index = 9; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 32, 9, '%', '%', 'off', 8, '%', '%', 'off' ); outstart($report_index); @xaxis = @yaxis1 = @yaxis2 = @yaxis3 = @yaxis4 = (); $max_x_data = ($opt_d < $x_scale and $opt_d != -1) ? $opt_d : $x_scale; $i = 0; outimg($report_index) if ($outtype_graph); outheader( $report_index, 'destination', ' request', '% ', 'hit-%', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '% ', 'hit-%', 'auto' ); outseperator($report_index); @counter = keys %tcp_urltld; $other_tld = $#counter + 1; $other = $tcp; $other_size = $tcp_size; $other_hit = $tcp_hit; $other_time = $tcp_time; $other_hit_size = $tcp_hit_size; $other_count = $opt_d; foreach $urltld ( sort { ${"tcp_urltld$sortorder"}{$b} <=> ${"tcp_urltld$sortorder"}{$a} } keys(%tcp_urltld) ) { next if $urltld eq ''; $other_tld--; $other -= $tcp_urltld{$urltld}; $other_size -= $tcp_urltld_size{$urltld}; $other_time -= $tcp_urltld_time{$urltld}; $other_hit -= $tcp_hit_urltld{$urltld}; $other_hit_size -= $tcp_hit_urltld_size{$urltld}; $i++; push @xaxis, $urltld if ($i < $max_x_data); push @yaxis1, $tcp_urltld{$urltld} if ($i < $max_x_data); push @yaxis2, $tcp_urltld_size{$urltld} if ($i < $max_x_data); push @yaxis3, $tcp_urltld{$urltld} ? $tcp_hit_urltld{$urltld} / $tcp_urltld{$urltld} : 0 if ($i < $max_x_data); push @yaxis4, $tcp_urltld_size{$urltld} ? $tcp_hit_urltld_size{$urltld} / $tcp_urltld_size{$urltld} : 0 if ($i < $max_x_data); writecache( $report_index, $urltld, $tcp_urltld{$urltld}, $tcp_urltld_size{$urltld}, $tcp_hit_urltld{$urltld}, $tcp_hit_urltld_size{$urltld}, $tcp_urltld_time{$urltld} ); outline( $report_index, 'toggle', $urltld, $tcp_urltld{$urltld}, 100 * $tcp_urltld{$urltld} / $tcp, 100 * $tcp_hit_urltld{$urltld} / $tcp_urltld{$urltld}, $tcp_urltld_time{$urltld} / (1000 * $tcp_urltld{$urltld}), kilomegagigatera( $tcp_urltld_size{$urltld}, $format[5] ), $tcp_size ? 100 * $tcp_urltld_size{$urltld} / $tcp_size : 0, $tcp_urltld_size{$urltld} ? 100 * $tcp_hit_urltld_size{$urltld} / $tcp_urltld_size{$urltld} : 0, $tcp_urltld_time{$urltld} ? $tcp_urltld_size{$urltld} / ( 1.024 * $tcp_urltld_time{$urltld} ) : 0 ); last if ( ( --$other_count == 0 and $other != 1 ) or ($tcp_urltld{$urltld} < $opt_domain_report_limit) ); } if ($other) { push @xaxis, ''; push @yaxis1, $other; push @yaxis2, $other_size; push @yaxis3, $other ? $other_hit / $other : 0; push @yaxis4, $other_size ? $other_hit_size / $other_size : 0; $max_x_data = ( $opt_d < $x_scale and $opt_d != -1 ) ? $opt_d + 1 : $x_scale + 1; writecache( $report_index, '', $other, $other_size, $other_hit, $other_hit_size, $other_time ); $other_tld = '' unless $show_other_tcp_urltld; outline( $report_index, '', 'other: ' . $other_tld . ' top-level-domains', $other, 100 * $other / $tcp, 100 * $other_hit / $other, $other_time / (1000 * $other), kilomegagigatera( $other_size, $format[5] ), $tcp_size ? 100 * $other_size / $tcp_size : 0, $other_size ? 100 * $other_hit_size / $other_size : 0, $other_size ? $other_size/ (1.024 * $other_time ) : 0 ); } outseperator($report_index); outline( $report_index, '2', 'Sum', $tcp, 100, 100 * $tcp_hit / $tcp, $tcp_time / (1000 * $tcp), kilomegagigatera( $tcp_size, $format[5] ), 100, $tcp_size ? 100 * $tcp_hit_size / $tcp_size : 0, $tcp_time ? $tcp_size / ( 1.024 * $tcp_time ) : 0 ); outgraph($report_index, \@graph_legend, $max_x_data, \@xaxis, \@yaxis1, \@yaxis2, \@yaxis3, \@yaxis4) if ($outtype_graph and $xaxis[0]); outstop($report_index); test( $report_index, \%tcp_urltld, \%tcp_urltld_size, \%tcp_urltld_time, 'tcp') if $test; $max_value[$report_index] = 'most requested toplevel-domain ' . htmlescape($xaxis[0]) . ' ' . ($opt_O ? kilomegagigatera($yaxis2[0], 6) . " Byte" : $yaxis1[0]. " Requests"); } } # TCP-Request-protocol $report_index = 10; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 32, 9, '%', '%', 'off', 8, '%', '%', 'off' ); if ($opt_t) { outstart($report_index); if ( $tcp == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); $max_x_data = ($opt_t < $x_scale and $opt_t != -1) ? $opt_t : $x_scale; $i = 0; outimg($report_index) if ($outtype_graph); outheader( $report_index, 'protocol', ' request', '% ', 'hit-%', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '% ', 'hit-%', 'auto' ); outseperator($report_index); foreach $urlprot ( sort { ${"tcp_urlprot$sortorder"}{$b} <=> ${"tcp_urlprot$sortorder"}{$a} } keys(%tcp_urlprot) ) { push @xaxis, $urlprot; push @yaxis1, $tcp_urlprot{$urlprot}; push @yaxis2, $tcp_urlprot_size{$urlprot}; push @yaxis3, $tcp_urlprot{$urlprot} ? $tcp_hit_urlprot{$urlprot} / $tcp_urlprot{$urlprot} : 0; push @yaxis4, $tcp_urlprot_size{$urlprot} ? $tcp_hit_urlprot_size{$urlprot} / $tcp_urlprot_size{$urlprot} : 0; writecache( $report_index, $urlprot, $tcp_urlprot{$urlprot}, $tcp_urlprot_size{$urlprot}, $tcp_hit_urlprot{$urlprot}, $tcp_hit_urlprot_size{$urlprot}, $tcp_urlprot_time{$urlprot} ); outline( $report_index, 'toggle', $urlprot, $tcp_urlprot{$urlprot}, 100 * $tcp_urlprot{$urlprot} / $tcp, 100 * $tcp_hit_urlprot{$urlprot} / $tcp_urlprot{$urlprot}, $tcp_urlprot_time{$urlprot} / (1000 * $tcp_urlprot{$urlprot}), kilomegagigatera( $tcp_urlprot_size{$urlprot}, $format[5] ), $tcp_size ? 100 * $tcp_urlprot_size{$urlprot} / $tcp_size : 0, $tcp_urlprot_size{$urlprot} ? 100 * $tcp_hit_urlprot_size{$urlprot} / $tcp_urlprot_size{$urlprot} : 0, $tcp_urlprot_time{$urlprot} ? $tcp_urlprot_size{$urlprot} / ( 1.024 * $tcp_urlprot_time{$urlprot} ) : 0 ); } outseperator($report_index); outline( $report_index, '2', 'Sum', $tcp, 100, 100 * $tcp_hit / $tcp, $tcp_time / (1000 * $tcp), kilomegagigatera( $tcp_size, $format[5] ), 100, $tcp_size ? 100 * $tcp_hit_size / $tcp_size : 0, $tcp_size / $tcp_time ); outgraph($report_index, \@graph_legend, $max_x_data, \@xaxis, \@yaxis1, \@yaxis2, \@yaxis3, \@yaxis4) if ($outtype_graph and $xaxis[0]); test( $report_index, \%tcp_urlprot, \%tcp_urlprot_size, \%tcp_urlprot_time, 'tcp') if $test; # find max value my ($max, $maxi) = ($opt_O) ? maxi(@yaxis2) : maxi(@yaxis1); if (defined($maxi) and defined($xaxis[$maxi])) { $max_value[$report_index] = 'most requested protocol ' . htmlescape($xaxis[$maxi]) . ' ' . ($opt_O ? kilomegagigatera($yaxis2[$maxi], 6) . ' Byte' : $yaxis1[0] . ' Requests'); } } outstop($report_index); # Requested content-type $report_index = 11; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 32, 9, '%', '%', 'off', 8, '%', '%', 'off' ); if ( %tcp_content ) { outstart($report_index); if ( $tcp == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); $max_x_data = ($opt_t < $x_scale and $opt_t != -1) ? $opt_t : $x_scale; $i = 0; outimg($report_index) if ($outtype_graph); @counter = keys %tcp_content; $other_content = $#counter + 1; $other = $tcp; $other_size = $tcp_size; $other_time = $tcp_time; $other_hit = $tcp_hit; $other_hit_size = $tcp_hit_size; $other_count = $opt_t; outheader( $report_index, 'content-type', ' request', '% ', 'hit-%', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '% ', 'hit-%', 'auto' ); outseperator($report_index); foreach $content ( sort { ${"tcp_content$sortorder"}{$b} <=> ${"tcp_content$sortorder"}{$a} } keys(%tcp_content) ) { next if $content eq ''; $other_content--; $other -= $tcp_content{$content}; $other_size -= $tcp_content_size{$content}; $other_time -= $tcp_content_time{$content}; $other_hit -= $tcp_hit_content{$content}; $other_hit_size -= $tcp_hit_content_size{$content}; $i++; push @xaxis, $content if ($i < $max_x_data); push @yaxis1, $tcp_content{$content} if ($i < $max_x_data); push @yaxis2, $tcp_content_size{$content} if ($i < $max_x_data); push @yaxis3, $tcp_content{$content} ? $tcp_hit_content{$content} / $tcp_content{$content} : 0 if ($i < $max_x_data); push @yaxis4, $tcp_content_size{$content} ? $tcp_hit_content_size{$content} / $tcp_content_size{$content} : 0 if ($i < $max_x_data); writecache( $report_index, $content, $tcp_content{$content}, $tcp_content_size{$content}, $tcp_hit_content{$content}, $tcp_hit_content_size{$content}, $tcp_content_time{$content} ); outline( $report_index, 'toggle', $content, $tcp_content{$content}, 100 * $tcp_content{$content} / $tcp, 100 * $tcp_hit_content{$content} / $tcp_content{$content}, $tcp_content_time{$content} / (1000 * $tcp_content{$content}), kilomegagigatera( $tcp_content_size{$content}, $format[5] ), $tcp_size ? 100 * $tcp_content_size{$content} / $tcp_size : 0, $tcp_content_size{$content} ? 100 * $tcp_hit_content_size{$content} / $tcp_content_size{$content} : 0, $tcp_content_time{$content} ? $tcp_content_size{$content} / ( 1.024 * $tcp_content_time{$content} ) : 0 ); last if ( --$other_count == 0 and $other != 1 ); } if ($other) { push @xaxis, ''; push @yaxis1, $other; push @yaxis2, $other_size; push @yaxis3, $other ? $other_hit / $other : 0; push @yaxis4, $other_size ? $other_hit_size / $other_size : 0; $max_x_data = ($opt_t < $x_scale and $opt_t != -1) ? $opt_t + 1 : $x_scale + 1; writecache( $report_index, '', $other, $other_size, $other_hit, $other_hit_size, $other_time ); $other_content = '' unless $show_other_tcp_content; outline( $report_index, '', 'other: ' . $other_content . ' content-types', $other, 100 * $other / $tcp, 100 * $other_hit / $other, $other_time / (1000 * $other), kilomegagigatera( $other_size, $format[5] ), $tcp_size ? 100 * $other_size / $tcp_size : 0, $other_size ? 100 * $other_hit_size / $other_size : 0, $other_size ? $other_size/ (1.024 * $other_time ) : 0 ); } outseperator($report_index); outline( $report_index, '2', 'Sum', $tcp, 100, 100 * $tcp_hit / $tcp, $tcp_time / (1000 * $tcp), kilomegagigatera( $tcp_size, $format[5] ), 100, $tcp_size ? 100 * $tcp_hit_size / $tcp_size : 0, $tcp_time ? $tcp_size / ( 1.024 * $tcp_time ) : 0 ); outgraph($report_index, \@graph_legend, $max_x_data, \@xaxis, \@yaxis1, \@yaxis2, \@yaxis3, \@yaxis4) if ($outtype_graph and $xaxis[0]); test( $report_index, \%tcp_content, \%tcp_content_size, \%tcp_content_time, 'tcp') if $test; $max_value[$report_index] = 'most requested content-type ' . htmlescape($xaxis[0]) . ' ' . ($opt_O ? kilomegagigatera($yaxis2[0], 6) . ' Byte' : $yaxis1[0] . ' Requests'); } outstop($report_index); } # Requested extensions $report_index = 12; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 32, 9, '%', '%', 'off', 8, '%', '%', 'off', 'off', 'off' ); outstart($report_index); if ( $tcp == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); $max_x_data = ($opt_t < $x_scale and $opt_t != -1) ? $opt_t : $x_scale; $i = 0; outimg($report_index) if ($outtype_graph); @counter = keys %tcp_urlext; $other_urlext = $#counter + 1; $other = $tcp; $other_size = $tcp_size; $other_time = $tcp_time; $other_hit = $tcp_hit; $other_hit_size = $tcp_hit_size; $other_count = $opt_t; $sum_tcp_urlext_fresh = 0; $sum_tcp_urlext_stale = 0; $sum_tcp_urlext_refresh = 0; $sum_tcp_urlext_mod = 0; $sum_tcp_urlext_unmod = 0; foreach $urlext ( sort {${"tcp_urlext$sortorder"}{$b} <=> ${"tcp_urlext$sortorder"}{$a} } keys(%tcp_urlext) ) { $sum_tcp_urlext_fresh += $tcp_urlext_fresh{$urlext}; $sum_tcp_urlext_stale += $tcp_urlext_stale{$urlext}; $sum_tcp_urlext_refresh += $tcp_urlext_refresh{$urlext}; $sum_tcp_urlext_mod += $tcp_urlext_mod{$urlext}; $sum_tcp_urlext_unmod += $tcp_urlext_unmod{$urlext}; } $other_fresh = $sum_tcp_urlext_fresh; $other_stale = $sum_tcp_urlext_stale; $other_mod = $sum_tcp_urlext_mod; $other_unmod = $sum_tcp_urlext_unmod; $other_refresh = $sum_tcp_urlext_refresh; outheader( $report_index, 'extensions', ' request', '% ', 'hit-%', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '% ', 'hit-%', 'auto', 'fresh/stale', 'unmod/mod' ); outseperator($report_index); foreach $urlext ( sort {${"tcp_urlext$sortorder"}{$b} <=> ${"tcp_urlext$sortorder"}{$a} } keys(%tcp_urlext) ) { $sum_tcp_urlext_fresh += $tcp_urlext_fresh{$urlext}; $sum_tcp_urlext_stale += $tcp_urlext_stale{$urlext}; $sum_tcp_urlext_refresh += $tcp_urlext_refresh{$urlext}; $sum_tcp_urlext_mod += $tcp_urlext_mod{$urlext}; $sum_tcp_urlext_unmod += $tcp_urlext_unmod{$urlext}; } foreach $urlext ( sort {${"tcp_urlext$sortorder"}{$b} <=> ${"tcp_urlext$sortorder"}{$a} } keys(%tcp_urlext) ) { next if $urlext eq ''; $other_urlext--; $other -= $tcp_urlext{$urlext}; $other_size -= $tcp_urlext_size{$urlext}; $other_time -= $tcp_urlext_time{$urlext}; $other_hit -= $tcp_hit_urlext{$urlext}; $other_hit_size -= $tcp_hit_urlext_size{$urlext}; $other_fresh -= $tcp_urlext_fresh{$urlext}; $other_stale -= $tcp_urlext_stale{$urlext}; $other_mod -= $tcp_urlext_mod{$urlext}; $other_unmod -= $tcp_urlext_unmod{$urlext}; $other_refresh -= $tcp_urlext_refresh{$urlext}; $i++; push @xaxis, $urlext if ($i < $max_x_data); push @yaxis1, $tcp_urlext{$urlext} if ($i < $max_x_data); push @yaxis2, $tcp_urlext_size{$urlext} if ($i < $max_x_data); push @yaxis3, $tcp_urlext{$urlext} ? $tcp_hit_urlext{$urlext} / $tcp_urlext{$urlext} : 0 if ($i < $max_x_data); push @yaxis4, $tcp_urlext_size{$urlext} ? $tcp_hit_urlext_size{$urlext} / $tcp_urlext_size{$urlext} : 0 if ($i < $max_x_data); writecache( $report_index, $urlext, $tcp_urlext{$urlext}, $tcp_urlext_size{$urlext}, $tcp_hit_urlext{$urlext}, $tcp_hit_urlext_size{$urlext}, $tcp_urlext_time{$urlext}, $tcp_urlext_fresh{$urlext}, $tcp_urlext_stale{$urlext}, $tcp_urlext_refresh{$urlext}, $tcp_urlext_mod{$urlext}, $tcp_urlext_unmod{$urlext} ); outline( $report_index, 'toggle', $urlext, $tcp_urlext{$urlext}, 100 * $tcp_urlext{$urlext} / $tcp, 100 * $tcp_hit_urlext{$urlext} / $tcp_urlext{$urlext}, $tcp_urlext_time{$urlext} / ( 1000 * $tcp_urlext{$urlext} ), kilomegagigatera( $tcp_urlext_size{$urlext}, $format[5] ), $tcp_size ? 100 * $tcp_urlext_size{$urlext} / $tcp_size : 0, $tcp_urlext_size{$urlext} ? 100 * $tcp_hit_urlext_size{$urlext} / $tcp_urlext_size{$urlext} : 0, $tcp_urlext_time{$urlext} ? $tcp_urlext_size{$urlext} / ( 1.024 * $tcp_urlext_time{$urlext} ) : 0, join ('/', gcd($tcp_urlext_fresh{$urlext}, $tcp_urlext_stale{$urlext})), join ('/', gcd($tcp_urlext_unmod{$urlext}, $tcp_urlext_mod{$urlext})) ); last if ( --$other_count == 0 and $other != 1 ); } if ($other) { push @xaxis, ''; push @yaxis1, $other; push @yaxis2, $other_size; push @yaxis3, $other ? $other_hit / $other : 0; push @yaxis4, $other_size ? $other_hit_size / $other_size : 0; $max_x_data = ( $opt_t < $x_scale and $opt_t != -1 ) ? $opt_t + 1 : $x_scale + 1; writecache( $report_index, '', $other, $other_size, $other_hit, $other_hit_size, $other_time, $other_fresh, $other_stale, $other_refresh, $other_mod, $other_unmod ); $other_urlext = '' unless $show_other_tcp_urlext; outline( $report_index, '', 'other: ' . $other_urlext . ' extensions', $other, 100 * $other / $tcp, 100 * $other_hit / $other, $other_time / (1000 * $other), kilomegagigatera( $other_size, $format[5] ), $tcp_size ? 100 * $other_size / $tcp_size : 0, $other_size ? 100 * $other_hit_size / $other_size : 0, $other_size ? $other_size/ (1.024 * $other_time ) : 0, join ('/', gcd($other_fresh, $other_stale)), join ('/', gcd($other_unmod, $other_mod)) ); } outseperator($report_index); outline( $report_index, '2', 'Sum', $tcp, 100, 100 * $tcp_hit / $tcp, $tcp_time / (1000 * $tcp), kilomegagigatera( $tcp_size, $format[5] ), 100, $tcp_size ? 100 * $tcp_hit_size / $tcp_size : 0, $tcp_time ? $tcp_size / ( 1.024 * $tcp_time ) : 0, join ('/', gcd($sum_tcp_urlext_fresh, $sum_tcp_urlext_stale)), join ('/', gcd($sum_tcp_urlext_mod, $sum_tcp_urlext_unmod)) ); outgraph($report_index, \@graph_legend, $max_x_data, \@xaxis, \@yaxis1, \@yaxis2, \@yaxis3, \@yaxis4) if ($outtype_graph and $xaxis[0]); test( $report_index, \%tcp_urlext, \%tcp_urlext_size, \%tcp_urlext_time, 'tcp') if $test; $max_value[$report_index] = 'most requested extension ' . htmlescape($xaxis[0]) . ' ' . ($opt_O ? kilomegagigatera($yaxis2[0], 6) . ' Byte' : $yaxis1[0]. ' Requests'); } outstop($report_index); } if ($opt_r) { # Incoming UDP-requests by host $report_index = 13; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 38, 9, 'off', '%', 'off', 8, 'off', '%', 'kbps' ); outstart($report_index); if ( $udp == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); $max_x_data = ($opt_t < $x_scale and $opt_t != -1) ? $opt_t : $x_scale; $i = 0; outimg($report_index) if ($outtype_graph); if ($opt_R) { outheader( $report_index, 'host / target', ' request', '%', 'hit-%', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '%', 'hit-%', 'auto' ); } else { outheader( $report_index, 'host', ' request', '%', 'hit-%', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '%', 'hit-%', 'auto' ); } outseperator($report_index); @counter = keys %udp_requester; $other_requester = $#counter + 1; $other = $udp; $other_size = $udp_size; $other_time = $udp_time; $other_hit = $udp_hit; $other_hit_size = $udp_hit_size; $other_count = $opt_r; foreach $requester ( sort { ${"udp_requester$sortorder"}{$b} <=> ${"udp_requester$sortorder"}{$a} } keys(%udp_requester) ) { next if $requester eq ''; $other_requester--; $other -= $udp_requester{$requester}; $other_size -= $udp_requester_size{$requester}; $other_time -= $udp_requester_time{$requester}; $other_hit -= $udp_hit_requester{$requester}; $other_hit_size -= $udp_hit_requester_size{$requester}; $i++; push @xaxis, $requester if ($i < $max_x_data); push @yaxis1, $udp_requester{$requester} if ($i < $max_x_data); push @yaxis2, $udp_requester_size{$requester} if ($i < $max_x_data); push @yaxis3, $udp_requester{$requester} ? $udp_hit_requester{$requester} / $udp_requester{$requester} : 0 if ($i < $max_x_data); push @yaxis4, $udp_requester_size{$requester} ? $udp_hit_requester_size{$requester} / $udp_requester_size{$requester} : 0 if ($i < $max_x_data); writecache( "$report_index.1", $requester, $udp_requester{$requester}, $udp_requester_size{$requester}, $udp_requester_time{$requester}, $udp_hit_requester{$requester}, $udp_hit_requester_size{$requester} ); outline( $report_index, '', $requester, $udp_requester{$requester}, $udp ? 100 * $udp_requester{$requester} / $udp : 0, 100 * $udp_hit_requester{$requester} / $udp_requester{$requester}, $udp_requester{$requester} ? $udp_requester_time{$requester} / ( 1000 * $udp_requester{$requester} ) : 0, kilomegagigatera( $udp_requester_size{$requester}, $format[5] ), $udp_size ? 100 * $udp_requester_size{$requester} / $udp_size : 0, $udp_requester_size{$requester} ? 100 * $udp_hit_requester_size{$requester} / $udp_requester_size{$requester} : 0, $udp_requester_size{$requester} / ( 1.024 * $udp_requester_time{$requester} ) ); if ($opt_R) { @counter2 = keys( %{ $udp_requester_urlhost{$requester} } ); $other2_requester_urlhost = $#counter2 + 1; $other2 = $udp_requester{$requester}; $other2_size = $udp_requester_size{$requester}; $other2_time = $udp_requester_time{$requester}; $other2_hit = $udp_hit_requester{$requester}; $other2_hit_size = $udp_hit_requester_size{$requester}; $other2_count = $opt_R; foreach $urlhost ( sort { ${"udp_requester_urlhost$sortorder"}{$requester}{$b} <=> ${"udp_requester_urlhost$sortorder"}{$requester}{$a} } keys( %{ $udp_requester_urlhost{$requester} } ) ) { next if $urlhost eq ''; $other2_requester_urlhost--; $other2 -= $udp_requester_urlhost{$requester}{$urlhost}; $other2_size -= $udp_requester_urlhost_size{$requester}{$urlhost}; $other2_time -= $udp_requester_urlhost_time{$requester}{$urlhost}; $other2_hit -= $udp_hit_requester_urlhost{$requester}{$urlhost}; $other2_hit_size -= $udp_hit_requester_urlhost_size{$requester}{$urlhost}; writecache( "$report_index.2", $requester, $urlhost, $udp_requester_urlhost{$requester}{$urlhost}, $udp_requester_urlhost_size{$requester}{$urlhost}, $udp_requester_urlhost_time{$requester}{$urlhost}, $udp_hit_requester_urlhost{$requester}{$urlhost}, $udp_hit_requester_urlhost_size{$requester}{$urlhost} ); outline( $report_index, 'toggle', ' ' . $urlhost, $udp_requester_urlhost{$requester}{$urlhost}, '', 100 * $udp_hit_requester_urlhost{$requester}{$urlhost} / $udp_requester_urlhost{$requester}{$urlhost}, $udp_requester_urlhost_time{$requester}{$urlhost} / (1000 * $udp_requester_urlhost{$requester}{$urlhost}), kilomegagigatera( $udp_requester_urlhost_size{$requester}{$urlhost}, $format[5] ), '', $udp_requester_urlhost_size{$requester}{$urlhost} ? 100 * $udp_hit_requester_urlhost_size{$requester}{$urlhost} / $udp_requester_urlhost_size{$requester}{$urlhost} : 0, $udp_requester_urlhost_size{$requester}{$urlhost} / ( 1.024 * $udp_requester_urlhost_time{$requester}{$urlhost} ) ); last if ( --$other2_count == 0 and $other2 != 1 ); } if ($other2) { writecache( "$report_index.2", $requester, '', $other2, $other2_size, $other2_time, $other2_hit, $other2_hit_size ); outline( $report_index, '', ' other: ' . $other2_requester_urlhost . ' requested urlhosts', $other2, '', 100 * $other2_hit / $other2, $other2_time / ( 1000 * $other2_requester_urlhost ), kilomegagigatera( $other2_size, $format[5] ), '', $other2_size ? 100 * $other2_hit_size / $other2_size : 0, $other2_size / ( 1.024 * $other2_time ) ); } } last if ( --$other_count == 0 and $other != 1 ); } if ($other) { push @xaxis, ''; push @yaxis1, $other; push @yaxis2, $other_size; push @yaxis3, $other ? $other_hit / $other : 0; push @yaxis4, $other_size ? $other_hit_size / $other_size : 0; $max_x_data = ( $opt_r < $x_scale and $opt_r != -1 ) ? $opt_r + 1 : $x_scale + 1; writecache( "$report_index.1", '', $other, $other_size, $other_time, $other_hit, $other_hit_size ); $other_requester = '' unless $show_other_udp_requester; outline( $report_index, '', 'other: ' . $other_requester . ' requesting hosts', $other, '', 100 * $other_hit / $other, $other_time / ( 1000 * $udp ), kilomegagigatera( $other_size, $format[5] ), '', 100 * $other_hit_size / $other_size, $other_size / ( 1.024 * $udp_time ) ); } outseperator($report_index); outline( $report_index, '2', 'Sum', $udp, 100, 100 * $udp_hit / $udp, $udp_time / (1000 * $udp), kilomegagigatera( $udp_size, $format[5] ), 100, $udp_size ? 100 * $udp_hit_size / $udp_size : 0, $udp_time ? $udp_size / ( 1.024 * $udp_time ) : 0 ); outgraph( $report_index, \@graph_legend, $max_x_data, \@xaxis, \@yaxis1, \@yaxis2, \@yaxis3, \@yaxis4 ) if ($outtype_graph and $xaxis[0]); test( $report_index, \%udp_requester, \%udp_requester_size, \%udp_requester_time, 'udp') if $test; $max_value[$report_index] = 'most active host ' . htmlescape($xaxis[0]) . ' ' . ($opt_O ? kilomegagigatera($yaxis2[0], 6) . ' Byte' : $yaxis1[0] . ' Requests'); } outstop($report_index); # Incoming TCP-requests by host $report_index = 14; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 30, 9, 'off', '%', 'spr', 8, 'off', '%', 'kbps' ); outstart($report_index); if ( $tcp == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); $max_x_data = ($opt_r < $x_scale and $opt_r != -1) ? $opt_r : $x_scale; $i = 0; outimg($report_index) if ($outtype_graph); if ($opt_R) { outheader( $report_index, 'host / target', ' request', '%', 'hit-%', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '%', 'hit-%', 'auto' ); } else { outheader( $report_index, 'host', ' request', '%', 'hit-%', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '%', 'hit-%', 'auto' ); } outseperator($report_index); @counter = keys %tcp_requester; $other_requester = $#counter + 1; $other = $tcp; $other_size = $tcp_size; $other_time = $tcp_time; $other_hit = $tcp_hit; $other_hit_size = $tcp_hit_size; $other_count = $opt_r; foreach $requester ( sort { ${"tcp_requester$sortorder"}{$b} <=> ${"tcp_requester$sortorder"}{$a} } keys(%tcp_requester) ) { next if $requester eq ''; $other_requester--; $other -= $tcp_requester{$requester}; $other_size -= $tcp_requester_size{$requester}; $other_time -= $tcp_requester_time{$requester}; $other_hit -= $tcp_hit_requester{$requester}; $other_hit_size -= $tcp_hit_requester_size{$requester}; $i++; push @xaxis, $requester if ($i < $max_x_data); push @yaxis1, $tcp_requester{$requester} if ($i < $max_x_data); push @yaxis2, $tcp_requester_size{$requester} if ($i < $max_x_data); push @yaxis3, $tcp_requester{$requester} ? $tcp_hit_requester{$requester} / $tcp_requester{$requester} : 0 if ($i < $max_x_data); push @yaxis4, $tcp_requester_size{$requester} ? $tcp_hit_requester_size{$requester} / $tcp_requester_size{$requester} : 0 if ($i < $max_x_data); writecache( "$report_index.1", $requester, $tcp_requester{$requester}, $tcp_requester_size{$requester}, $tcp_requester_time{$requester}, $tcp_hit_requester{$requester}, $tcp_hit_requester_size{$requester} ); outline( $report_index, 'toggle', uri_unescape($requester), $tcp_requester{$requester}, $tcp ? 100 * $tcp_requester{$requester} / $tcp : 0, 100 * $tcp_hit_requester{$requester} / $tcp_requester{$requester}, $tcp_requester_time{$requester} / ( 1000 * $tcp_requester{$requester} ), kilomegagigatera( $tcp_requester_size{$requester}, $format[5] ), $tcp_size ? 100 * $tcp_requester_size{$requester} / $tcp_size : 0, $tcp_requester_size{$requester} ? 100 * $tcp_hit_requester_size{$requester} / $tcp_requester_size{$requester} : 0, $tcp_requester_size{$requester} / ( 1.024 * $tcp_requester_time{$requester} ) ); if ($opt_R) { @counter2 = keys( %{ $tcp_requester_urlhost{$requester} } ); $other2_requester_urlhost = $#counter2 + 1; $other2 = $tcp_requester{$requester}; $other2_size = $tcp_requester_size{$requester}; $other2_time = $tcp_requester_time{$requester}; $other2_hit = $tcp_hit_requester{$requester}; $other2_hit_size = $tcp_hit_requester_size{$requester}; $other2_count = $opt_R; foreach $urlhost ( sort { ${"tcp_requester_urlhost$sortorder"}{$requester}{$b} <=> ${"tcp_requester_urlhost$sortorder"}{$requester}{$a} } keys( %{ $tcp_requester_urlhost{$requester} } ) ) { next if $urlhost eq ''; $other2_requester_urlhost--; $other2 -= $tcp_requester_urlhost{$requester}{$urlhost}; $other2_size -= $tcp_requester_urlhost_size{$requester}{$urlhost}; $other2_time -= $tcp_requester_urlhost_time{$requester}{$urlhost}; $other2_hit -= $tcp_hit_requester_urlhost{$requester}{$urlhost}; $other2_hit_size -= $tcp_hit_requester_urlhost_size{$requester}{$urlhost}; writecache( "$report_index.2", $requester, $urlhost, $tcp_requester_urlhost{$requester}{$urlhost}, $tcp_requester_urlhost_size{$requester}{$urlhost}, $tcp_requester_urlhost_time{$requester}{$urlhost}, $tcp_hit_requester_urlhost{$requester}{$urlhost}, $tcp_hit_requester_urlhost_size{$requester}{$urlhost} ); outline( $report_index, 'toggle', ' ' . $urlhost, $tcp_requester_urlhost{$requester}{$urlhost}, '', 100 * $tcp_hit_requester_urlhost{$requester}{$urlhost} / $tcp_requester_urlhost{$requester}{$urlhost}, $tcp_requester_urlhost_time{$requester}{$urlhost} / ( 1000 * $tcp_requester_urlhost{$requester}{$urlhost} ), kilomegagigatera( $tcp_requester_urlhost_size{$requester}{$urlhost}, $format[5] ), '', $tcp_requester_urlhost_size{$requester}{$urlhost} ? 100 * $tcp_hit_requester_urlhost_size{$requester}{$urlhost} / $tcp_requester_urlhost_size{$requester}{$urlhost} : 0, $tcp_requester_urlhost_size{$requester}{$urlhost} / ( 1.024 * $tcp_requester_urlhost_time{$requester}{$urlhost} ) ); last if ( --$other2_count == 0 and $other2 != 1 ); } if ($other2) { writecache( "$report_index.2", $requester, '', $other2, $other2_size, $other2_time, $other2_hit, $other2_hit_size ); outline( $report_index, '', ' other: ' . $other2_requester_urlhost . ' requested urlhosts', $other2, '', 100 * $other2_hit / $other2, $other2_time / ( 1000 * $other2_requester_urlhost ), kilomegagigatera( $other2_size, $format[5] ), '', $other2_size ? 100 * $other2_hit_size / $other2_size : 0, $other2_size / ( 1.024 * $other2_time ) ); } } last if ( --$other_count == 0 and $other != 1 ); } if ($other) { push @xaxis, ''; push @yaxis1, $other; push @yaxis2, $other_size; push @yaxis3, $other ? $other_hit / $other : 0; push @yaxis4, $other_size ? $other_hit_size / $other_size : 0; $max_x_data = ( $opt_r < $x_scale and $opt_r != -1 ) ? $opt_r + 1 : $x_scale + 1; writecache( "$report_index.1", '', $other, $other_size, $other_time, $other_hit, $other_hit_size ); $other_requester = '' unless $show_other_tcp_requester; outline( $report_index, '', 'other: ' . $other_requester . ' requesting hosts', $other, '', 100 * $other_hit / $other, $other_time / ( 1000 * $tcp ), kilomegagigatera( $other_size, $format[5] ), '', $other_size ? 100 * $other_hit_size / $other_size : 0, $other_size / ( 1.024 * $tcp_time ) ); } outseperator($report_index); outline( $report_index, '2', 'Sum', $tcp, 100, 100 * $tcp_hit / $tcp, $tcp_time / (1000 * $tcp), kilomegagigatera( $tcp_size, $format[5] ), 100, $tcp_size ? 100 * $tcp_hit_size / $tcp_size : 0, $tcp_time ? $tcp_size / ( 1.024 * $tcp_time ) : 0 ); outgraph( $report_index, \@graph_legend, $max_x_data, \@xaxis, \@yaxis1, \@yaxis2, \@yaxis3, \@yaxis4 ) if ($outtype_graph and $xaxis[0]); test( $report_index, \%tcp_requester, \%tcp_requester_size, \%tcp_requester_time, 'tcp') if $test; $max_value[$report_index] = 'most active host ' . htmlescape($xaxis[0]) . ' ' . ($opt_O ? kilomegagigatera($yaxis2[0], 6) . ' Byte' : $yaxis1[0] . ' Requests'); } outstop($report_index); } # Size Distribution Diagram $report_index = 15; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 30, 9, 'off', '%', 'spr', 8, 'off', '%', 'kbps' ); if ($opt_D) { outstart($report_index); if ( $tcp == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); outimg($report_index) if ($outtype_graph); outheader( $report_index, 'object-size (bytes)', ' request', '%', 'hit-%', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '%', 'hit-%', 'auto' ); outseperator($report_index); foreach $distribution ( sort { $a <=> $b } keys(%tcp_distribution) ) { push @xaxis, int( $opt_D**$distribution ) . '-' . int( $opt_D**( $distribution + 1 ) - 1 ); push @yaxis1, $tcp_distribution{$distribution}; push @yaxis2, $tcp_distribution_size{$distribution}; push @yaxis3, $tcp_distribution{$distribution} ? $tcp_hit_distribution{$distribution} / $tcp_distribution{$distribution} : 0; push @yaxis4, $tcp_distribution_size{$distribution} ? $tcp_hit_distribution_size{$distribution} / $tcp_distribution_size{$distribution} : 0; writecache( $report_index, $distribution, $tcp_distribution{$distribution}, $tcp_distribution_size{$distribution}, $tcp_distribution_time{$distribution}, $tcp_hit_distribution{$distribution}, $tcp_hit_distribution_size{$distribution} ); outline( $report_index, '', int( $opt_D**$distribution ) . '-' . int( $opt_D**( $distribution + 1 ) - 1 ), $tcp_distribution{$distribution}, 100 * $tcp_distribution{$distribution} / $tcp, 100 * $tcp_hit_distribution{$distribution} / $tcp_distribution{$distribution}, $tcp_distribution_time{$distribution} / ( 1000 * $tcp_distribution{$distribution} ), kilomegagigatera( $tcp_distribution_size{$distribution}, $format[5] ), $tcp_size ? 100 * $tcp_distribution_size{$distribution} / $tcp_size : 0, $tcp_distribution_size{$distribution} ? 100 * $tcp_hit_distribution_size{$distribution} / $tcp_distribution_size{$distribution} : 0, $tcp_distribution_size{$distribution} / ( 1.024 * $tcp_distribution_time{$distribution} ) ); } outseperator($report_index); outline( $report_index, '2', 'Sum', $tcp, 100, 100 * $tcp_hit / $tcp, $tcp_time / (1000 * $tcp), kilomegagigatera( $tcp_size, $format[5] ), 100, $tcp_size ? 100 * $tcp_hit_size / $tcp_size : 0, $tcp_time ? $tcp_size / ( 1.024 * $tcp_time ) : 0 ); outgraph( $report_index, \@graph_legend, $x_scale, \@xaxis, \@yaxis1, \@yaxis2, \@yaxis3, \@yaxis4 ) if ($outtype_graph and $xaxis[0]); # find max value my ($max, $maxi) = ($opt_O) ? maxi(@yaxis2) : maxi(@yaxis1); if (defined($maxi) and defined($xaxis[$maxi])) { $max_value[$report_index] = 'most requested object_size ' . htmlescape($xaxis[$maxi]) . ' ' . ($opt_O ? kilomegagigatera($max, 6) . ' Byte' : $max . ' Requests'); } test( $report_index, \%tcp_distribution, \%tcp_distribution_size, \%tcp_distribution_time, 'tcp') if $test; } outstop($report_index); } # Performance in $P steps $report_index = 16; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 15, 9, 'off', 5, 'off', 'off', 'kbps', 'kbps', 'kbps', 'kbps', 'kbps', 'kbps' ); if ($opt_P) { outstart($report_index); if ( $tcp == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); outimg($report_index) if ($outtype_graph); outheader( $report_index, '', '', '', '', '', '', 'incomin', ' hit', ' miss', ' direct', 'sibling', ' fetch' ); outheader( $report_index, 'date', ' request', 'hit-%', ' Byte', 'hit-%', 'IPs', 'auto', 'auto', 'auto', 'auto', 'auto', 'auto'); outseperator($report_index); foreach $perf_date ( sort { $a <=> $b } keys(%perf_counter) ) { $perf_requester{$perf_date} = scalar keys %{$perf_ip{$perf_date}}; push @xaxis, substr( convertdate($perf_date), 0, 15 ); push @yaxis1, $perf_counter{$perf_date}; push @yaxis2, $perf_size{$perf_date}; push @yaxis3, $perf_counter{$perf_date} ? $perf_tcp_hit{$perf_date} / $perf_counter{$perf_date} : 0; push @yaxis4, $perf_size{$perf_date} ? $perf_tcp_hit_size{$perf_date} / $perf_size{$perf_date} : 0; writecache( $report_index, $perf_date, $perf_counter{$perf_date}, $perf_size{$perf_date}, $perf_time{$perf_date}, $perf_tcp_hit_size{$perf_date}, $perf_tcp_hit_time{$perf_date}, $perf_tcp_miss_size{$perf_date}, $perf_tcp_miss_time{$perf_date}, $perf_hier_direct_size{$perf_date}, $perf_hier_direct_time{$perf_date}, $perf_hier_sibling_size{$perf_date}, $perf_hier_sibling_time{$perf_date}, $perf_hier_parent_size{$perf_date}, $perf_hier_parent_time{$perf_date}, $perf_requester{$perf_date}, $perf_tcp_hit{$perf_date} ); outline( $report_index, 'toggle', substr( convertdate($perf_date), 0, 15 ), $perf_counter{$perf_date}, $perf_counter{$perf_date} ? 100 * $perf_tcp_hit{$perf_date} / $perf_counter{$perf_date} : 0, kilomegagigatera( $perf_size{$perf_date}, $format[3] ), $perf_size{$perf_date} ? 100 * $perf_tcp_hit_size{$perf_date} / $perf_size{$perf_date} : 0, $perf_requester{$perf_date}, removezerotimes( $perf_size{$perf_date}, $perf_time{$perf_date} ), removezerotimes( $perf_tcp_hit_size{$perf_date}, $perf_tcp_hit_time{$perf_date} ), removezerotimes( $perf_tcp_miss_size{$perf_date}, $perf_tcp_miss_time{$perf_date} ), removezerotimes( $perf_hier_direct_size{$perf_date}, $perf_hier_direct_time{$perf_date} ), removezerotimes( $perf_hier_sibling_size{$perf_date}, $perf_hier_sibling_time{$perf_date} ), removezerotimes( $perf_hier_parent_size{$perf_date}, $perf_hier_parent_time{$perf_date} ) ); } outseperator($report_index); outline( $report_index, '2', 'overall', $tcp, 100 * $tcp_hit / $tcp, kilomegagigatera( $tcp_size, $format[3] ), $tcp_size ? 100 * $tcp_hit_size / $tcp_size : 0, scalar keys %tcp_requester, removezerotimes( $tcp_size, $tcp_time ), removezerotimes( $tcp_hit_size, $tcp_hit_time ), removezerotimes( $tcp_miss_size, $tcp_miss_time ), removezerotimes( $hier_direct_size, $hier_direct_time ), removezerotimes( $hier_sibling_size, $hier_sibling_time ), removezerotimes( $hier_parent_size, $hier_parent_time ) ); outgraph( $report_index, \@graph_legend, 31, \@xaxis, \@yaxis1, \@yaxis2, \@yaxis3, \@yaxis4 ) if ($outtype_graph and $xaxis[0]); test( $report_index, \%perf_counter, \%perf_size, \%perf_time, 'tcp') if $test; my ($max, $maxi) = ($opt_O) ? maxi(@yaxis2) : maxi(@yaxis1); if (defined($maxi) and defined($xaxis[$maxi])) { $max_value[$report_index] = 'most active day ' . htmlescape($xaxis[$maxi]) . ' ' . ($opt_O ? kilomegagigatera($max, 6) . ' Byte' : $max . ' Requests'); } } outstop($report_index); } # UDP-Request duration distribution in msec $report_index = 17; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 16, 9, '%', '%', 'spr', 8, '%', '%', 'kbps' ); if ($opt_response_time) { outstart($report_index); if ( $udp == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { my $max = 0; my $max_interval = 0; foreach $reqtime ( keys %udp_reqtime ) { for ($i = 0; $i <= $#response_time_report_interval; $i++) { if ($reqtime <= $response_time_report_interval[$i]) { if (${"udp_reqtime$sortorder"}{$reqtime} > $max) { $max = ${"udp_reqtime$sortorder"}{$reqtime}; $max_interval = "<= $response_time_report_interval[$i]"; } $ordered_udp_req_time_time{"<= $response_time_report_interval[$i]"} += $reqtime * $udp_reqtime{$reqtime}; $ordered_udp_req_time{"<= $response_time_report_interval[$i]"} += $udp_reqtime{$reqtime}; $ordered_udp_req_time_size{"<= $response_time_report_interval[$i]"} += $udp_reqtime_size{$reqtime}; $ordered_udp_hit_req_time{"<= $response_time_report_interval[$i]"} += $udp_hit_reqtime{$reqtime}; $ordered_udp_hit_req_time_size{"<= $response_time_report_interval[$i]"} += $udp_hit_reqtime_size{$reqtime}; if ( ${"ordered_udp_req_time$sortorder"}{"<= $response_time_report_interval[$i]"} - (($i == 0 or !defined(${"ordered_udp_req_time$sortorder"}{"<= $response_time_report_interval[$i-1]"})) ? 0 : ${"ordered_udp_req_time$sortorder"}{"<= $response_time_report_interval[$i-1]"}) > $max) { $max = ${"ordered_udp_req_time$sortorder"}{"<= $response_time_report_interval[$i]"} - (($i == 0 or !defined(${"ordered_udp_req_time$sortorder"}{"<= $response_time_report_interval[$i-1]"})) ? 0 : ${"ordered_udp_req_time$sortorder"}{"<= $response_time_report_interval[$i-1]"}); $max_interval = "<= $response_time_report_interval[$i]"; } } } } my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); outimg($report_index) if ($outtype_graph); outheader( $report_index, 'time', ' request', '% ', 'hit-%', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '% ', 'hit-%', 'auto'); outseperator($report_index); writecache( $report_index, $ordered_udp_req_time_max_interval, $ordered_udp_req_time_max ); foreach $time_interval ( sort { $a =~ m/^(>|<=)\s*(\S+)$/; my $a1 = $2; $b =~ m/^(>|<=)\s*(\S+)$/; my $b1 = $2; return $a1 <=> $b1 } keys(%ordered_udp_req_time) ) { push @xaxis, $time_interval; push @yaxis1, $ordered_udp_req_time{$time_interval}; push @yaxis2, $ordered_udp_req_time_size{$time_interval}; push @yaxis3, $ordered_udp_req_time{$time_interval} ? $ordered_udp_hit_req_time{$time_interval} / $ordered_udp_req_time{$time_interval} : 0; push @yaxis4, $ordered_udp_req_time_size{$time_interval} ? $ordered_udp_hit_req_time_size{$time_interval} / $ordered_udp_req_time_size{$time_interval} : 0; writecache( $report_index, $time_interval, $ordered_udp_req_time{$time_interval}, $ordered_udp_req_time_size{$time_interval}, $ordered_udp_hit_req_time{$time_interval}, $ordered_udp_hit_req_time_size{$time_interval}, $ordered_udp_req_time_time{$time_interval}); outline( $report_index, 'toggle', $time_interval, $ordered_udp_req_time{$time_interval}, 100 * $ordered_udp_req_time{$time_interval} / $udp, 100 * $ordered_udp_hit_req_time{$time_interval} / $ordered_udp_req_time{$time_interval}, $ordered_udp_req_time{$time_interval} ? $ordered_udp_req_time_time{$time_interval} / (1000 * $ordered_udp_req_time{$time_interval}) : 0, kilomegagigatera( $ordered_udp_req_time_size{$time_interval}, $format[5] ), $udp_size ? 100 * $ordered_udp_req_time_size{$time_interval} / $udp_size : 0, $ordered_udp_req_time_size{$time_interval} ? 100 * $ordered_udp_hit_req_time_size{$time_interval} / $ordered_udp_req_time_size{$time_interval} : 0, $ordered_udp_req_time_time{$time_interval} ? $ordered_udp_req_time_size{$time_interval} / (1.024 * $ordered_udp_req_time_time{$time_interval}) : 0 ); } outseperator($report_index); outline( $report_index, '2', 'Sum', $udp, 100, 100 * $udp_hit / $udp, $udp_time / (1000 * $udp), kilomegagigatera( $udp_size, $format[5] ), 100, $udp_size ? 100 * $udp_hit_size / $udp_size : 0, $udp_time ? $udp_size / ( 1.024 * $udp_time ) : 0); outgraph( $report_index, \@graph_legend, scalar(@response_time_report_interval), \@xaxis, \@yaxis1, \@yaxis2, \@yaxis3, \@yaxis4 ) if ($outtype_graph and $xaxis[0]); test( $report_index, \%udp_reqtime, \%udp_reqtime_size, 0, 'udp') if $test; $max_value[$report_index] = 'most frequent response time ' . htmlescape($max_interval) . ' ' . ($opt_O ? kilomegagigatera($max, 6) . ' Byte' : $max . ' Requests'); } outstop($report_index); # TCP-Request duration distribution in msec $report_index = 18; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 16, 9, '%', '%', 'spr', 8, '%', '%', 'kbps' ); outstart($report_index); if ( $tcp == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { foreach $reqtime ( keys %tcp_reqtime ) { for ( $i = 0; $i <= $#response_time_report_interval; $i++ ) { if ($reqtime <= $response_time_report_interval[$i]) { $ordered_tcp_req_time_time{"<= $response_time_report_interval[$i]"} += $reqtime * $tcp_reqtime{$reqtime}; $ordered_tcp_req_time{"<= $response_time_report_interval[$i]"} += $tcp_reqtime{$reqtime}; $ordered_tcp_req_time_size{"<= $response_time_report_interval[$i]"} += $tcp_reqtime_size{$reqtime}; $ordered_tcp_hit_req_time{"<= $response_time_report_interval[$i]"} += $tcp_hit_reqtime{$reqtime}; $ordered_tcp_hit_req_time_size{"<= $response_time_report_interval[$i]"} += $tcp_hit_reqtime_size{$reqtime}; if ( ${"ordered_tcp_req_time$sortorder"}{"<= $response_time_report_interval[$i]"} - (( $i == 0 or !defined(${"ordered_tcp_req_time$sortorder"}{"<= $response_time_report_interval[$i-1]"})) ? 0 : ${"ordered_tcp_req_time$sortorder"}{"<= $response_time_report_interval[$i-1]"}) > $ordered_tcp_req_time_max) { $ordered_tcp_req_time_max = ${"ordered_tcp_req_time$sortorder"}{"<= $response_time_report_interval[$i]"} - (( $i == 0 or !defined(${"ordered_tcp_req_time$sortorder"}{"<= $response_time_report_interval[$i-1]"})) ? 0 : ${"ordered_tcp_req_time$sortorder"}{"<= $response_time_report_interval[$i-1]"}); $ordered_tcp_req_time_max_interval = "<= $response_time_report_interval[$i]"; } } } } my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); outimg($report_index) if ($outtype_graph); outheader( $report_index, 'time', ' request', '% ', 'hit-%', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '% ', 'hit-%', 'auto'); outseperator($report_index); writecache( $report_index, $ordered_tcp_req_time_max_interval, $ordered_tcp_req_time_max ); foreach $time_interval ( sort { $a =~ m/^(>|<=)\s*(\S+)$/; my $a1 = $2; $b =~ m/^(>|<=)\s*(\S+)$/; my $b1 = $2; return $a1 <=> $b1 } keys(%ordered_tcp_req_time) ) { push @xaxis, $time_interval; push @yaxis1, $ordered_tcp_req_time{$time_interval}; push @yaxis2, $ordered_tcp_req_time_size{$time_interval}; push @yaxis3, $ordered_tcp_req_time{$time_interval} ? $ordered_tcp_hit_req_time{$time_interval} / $ordered_tcp_req_time{$time_interval} : 0; push @yaxis4, $ordered_tcp_req_time_size{$time_interval} ? $ordered_tcp_hit_req_time_size{$time_interval} / $ordered_tcp_req_time_size{$time_interval} : 0; writecache( $report_index, $time_interval, $ordered_tcp_req_time{$time_interval}, $ordered_tcp_req_time_size{$time_interval}, $ordered_tcp_hit_req_time{$time_interval}, $ordered_tcp_hit_req_time_size{$time_interval}, $ordered_tcp_req_time_time{$time_interval}); outline( $report_index, 'toggle', $time_interval, $ordered_tcp_req_time{$time_interval}, 100 * $ordered_tcp_req_time{$time_interval} / $tcp, 100 * $ordered_tcp_hit_req_time{$time_interval} / $ordered_tcp_req_time{$time_interval}, $ordered_tcp_req_time{$time_interval} ? $ordered_tcp_req_time_time{$time_interval} / (1000 * $ordered_tcp_req_time{$time_interval}) : 0, kilomegagigatera( $ordered_tcp_req_time_size{$time_interval}, $format[5] ), $tcp_size ? 100 * $ordered_tcp_req_time_size{$time_interval} / $tcp_size : 0, $ordered_tcp_req_time_size{$time_interval} ? 100 * $ordered_tcp_hit_req_time_size{$time_interval} / $ordered_tcp_req_time_size{$time_interval} : 0, $ordered_tcp_req_time_time{$time_interval} ? $ordered_tcp_req_time_size{$time_interval} / (1.024 * $ordered_tcp_req_time_time{$time_interval}) : 0 ); } outseperator($report_index); outline( $report_index, '2', 'Sum', $tcp, 100, 100 * $tcp_hit / $tcp, $tcp_time / (1000 * $tcp), kilomegagigatera( $tcp_size, $format[5] ), 100, $tcp_size ? 100 * $tcp_hit_size / $tcp_size : 0, $tcp_time ? $tcp_size / ( 1.024 * $tcp_time ) : 0); outgraph( $report_index, \@graph_legend, scalar(@response_time_report_interval), \@xaxis, \@yaxis1, \@yaxis2, \@yaxis3, \@yaxis4 ) if ($outtype_graph and $xaxis[0]); test( $report_index, \%tcp_reqtime, \%tcp_reqtime_size, 0, 'tcp') if $test; $max_value[$report_index] = 'most frequent response time ' . htmlescape($ordered_tcp_req_time_max_interval) . ' ' . ($opt_O ? kilomegagigatera($ordered_tcp_req_time_max, 6) . ' Byte' : $ordered_tcp_req_time_max . ' Requests'); } outstop($report_index); } # UDP Response code distribution $report_index = 19; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 46, 9, '%', 'off', 'off', 8, '%', 'off', 'off' ); if ($opt_errorcode_distribution) { %err_code = geterrcode(); outstart($report_index); if ( $udp == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); outimg($report_index) if ($outtype_graph); outheader( $report_index, 'status-code', ' request', '% ', 'hit-%', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '% ', 'hit-%', 'auto' ); outseperator($report_index); foreach $code ( sort { $a cmp $b } keys %udp_code ) { push @xaxis, $code; push @yaxis1, $udp_code{$code}; push @yaxis2, $udp_code_size{$code}; push @yaxis3, $udp_code{$code} ? $udp_hit_code{$code} / $udp_code{$code} : 0; push @yaxis4, $udp_code_size{$code} ? $udp_hit_code_size{$code} / $udp_code_size{$code} : 0; writecache( $report_index, $code, $udp_code{$code}, $udp_code_size{$code}, $udp_hit_code{$code}, $udp_hit_code_size{$code}, $udp_code_time{$code}); outline( $report_index, 'toggle', defined($err_code{$code}) ? "$code ($err_code{$code})" : "$code (unknown)", $udp_code{$code}, $udp ? 100 * $udp_code{$code} / $udp : 0, $udp_code{$code} ? 100 * $udp_hit_code{$code} / $udp_code{$code} : 0, $udp_code{$code} ? $udp_code_time{$code} / (1000 * $udp_code{$code}) : 0, kilomegagigatera( $udp_code_size{$code}, $format[5] ), $udp_size ? 100 * $udp_code_size{$code} / $udp_size : 0, $udp_code_size{$code} ? 100 * $udp_hit_code_size{$code} / $udp_code_size{$code} : 0, $udp_code_time{$code} ? $udp_hit_code_size{$code} / (1.024 * $udp_code_time{$code}) : 0 ); } outseperator($report_index); outline( $report_index, '2', 'Sum', $udp, 100, 100 * $udp_hit / $udp, $udp_time / (1000 * $udp), kilomegagigatera( $udp_size, $format[5] ), 100, $udp_size ? 100 * $udp_hit_size / $udp_size : 0, $udp_time ? $udp_size / ( 1.024 * $udp_time ) : 0); outgraph( $report_index, \@graph_legend, $x_scale, \@xaxis, \@yaxis1, \@yaxis2, \@yaxis3, \@yaxis4 ) if ($outtype_graph and $xaxis[0]); test( $report_index, \%udp_code, \%udp_code_size, \%udp_code_time, 'udp') if $test; my ($max, $maxi) = ($opt_O) ? maxi(@yaxis2) : maxi(@yaxis1); if (defined($maxi) and defined($xaxis[$maxi])) { $max_value[$report_index] = 'most frequent response code ' . htmlescape($xaxis[$maxi]) . ' ' . ($opt_O ? kilomegagigatera($max, 6) . ' Byte' : $max . ' Requests' ); } } outstop($report_index); # TCP Response code distribution $report_index = 20; @format = ref($formats[$report_index]) ? @{$formats[$report_index]} : ( 46, 9, '%', 'off', 'off', 8, '%', 'off', 'off' ); outstart($report_index); if ( $tcp == 0 ) { outline( $report_index, '', 'no matching requests' ); } else { my (@xaxis, @yaxis1, @yaxis2, @yaxis3, @yaxis4); outimg($report_index) if ($outtype_graph); outheader( $report_index, 'status-code', ' request', '% ', 'hit-%', 'auto', $outtype_unformatted ? " ${opt_U}Byte" : ' Byte', '% ', 'hit-%', 'auto' ); outseperator($report_index); foreach $code ( sort { $a cmp $b } keys %tcp_code ) { push @xaxis, $code; push @yaxis1, $tcp_code{$code}; push @yaxis2, $tcp_code_size{$code}; push @yaxis3, $tcp_code{$code} ? $tcp_hit_code{$code} / $tcp_code{$code} : 0; push @yaxis4, $tcp_code_size{$code} ? $tcp_hit_code_size{$code} / $tcp_code_size{$code} : 0; writecache( $report_index, $code, $tcp_code{$code}, $tcp_code_size{$code}, $tcp_hit_code{$code}, $tcp_hit_code_size{$code}, $tcp_code_time{$code}); outline( $report_index, 'toggle', defined($err_code{$code}) ? "$code ($err_code{$code})" : "$code (unknown)", $tcp_code{$code}, $tcp ? 100 * $tcp_code{$code} / $tcp : 0, $tcp_code{$code} ? 100 * $tcp_hit_code{$code} / $tcp_code{$code} : 0, $tcp_code{$code} ? $tcp_code_time{$code} / (1000 * $tcp_code{$code}) : 0, kilomegagigatera( $tcp_code_size{$code}, $format[5] ), $tcp_size ? 100 * $tcp_code_size{$code} / $tcp_size : 0, $tcp_code_size{$code} ? 100 * $tcp_hit_code_size{$code} / $tcp_code_size{$code} : 0, $tcp_code_time{$code} ? $tcp_hit_code_size{$code} / (1.024 * $tcp_code_time{$code}) : 0 ); } outseperator($report_index); outline( $report_index, '2', 'Sum', $tcp, 100, 100 * $tcp_hit / $tcp, $tcp_time / (1000 * $tcp), kilomegagigatera( $tcp_size, $format[5] ), 100, $tcp_size ? 100 * $tcp_hit_size / $tcp_size : 0, $tcp_time ? $tcp_size / ( 1.024 * $tcp_time ) : 0); outgraph( $report_index, \@graph_legend, $x_scale, \@xaxis, \@yaxis1, \@yaxis2, \@yaxis3, \@yaxis4) if ($outtype_graph and $xaxis[0]); test( $report_index, \%tcp_code, \%tcp_code_size, \%tcp_code_time, 'tcp') if $test; my ($max, $maxi) = ($opt_O) ? maxi(@yaxis2) : maxi(@yaxis1); if (defined($maxi) and defined($xaxis[$maxi])) { $max_value[$report_index] = 'most frequent response code ' . htmlescape($xaxis[$maxi]) . ' ' . ($opt_O ? kilomegagigatera($max, 6) . ' Byte' : $max . ' Requests'); } } outstop($report_index); } close(CACHE); ################################################## # now print it out. $generated = convertdate(time); $out_head = ''; $out_head .= "MIME-Version: 1.0\nContent-Type: text/html; charset=us-ascii Content-Transfer-Encoding: 7bit\n" if ( $outtype_mail and $outtype_html ); $out_head .= 'Subject: ' . ( $host_name ? "$host_name " : '') . "Proxy Report ($loginterval)\n\n" if ($outtype_mail); if ( $outtype_html or $outtype_htmlembed or outtype_htmlframe ) { $out_head .= ' ' . ( $host_name ? "$host_name " : '') . 'Proxy Report (' . $loginterval . ') ' . ( $opt_M ? " $opt_M\n" : '' ) . ' ' if ($outtype_html or $outtype_htmlframe); $out_index_head .= ' ' if ($outtype_html or $outtype_htmlembed or $outtype_htmlframe); if ($opt_l) { $out_index_head .= ' '; } $out_index_head .= '
' . $opt_l . '

Proxy Report

' . $host_name . '
Report period: ' . $loginterval . '
Generated at: ' . $generated . '

' if ($outtype_html or $outtype_htmlembed or $outtype_htmlframe); } else { $out_index_head .= "\n${host_name} Proxy-Report\n Report period: $loginterval\nGenerated at: $generated\n"; } @format = (60); if ( ( $invalid / $counter ) > .05 and $counter > 1000 ) { outstart('E'); outline( 'E', '', '' ); outline( 'E', '', 'More than 5% discarded logfile-lines.' ); outline( 'E', '', 'Please check your logfile with calamaris -v' ) unless ($opt_v); outstop('E'); } if ( defined($peak_warn) ) { outstart('E'); outline( 'E', '', '' ); outline( 'E', '', "$peak_warn" ); outline( 'E', '', 'Please read the README on unsorted input' ); outline( 'E', '', 'To find out which line caused this, try calamaris -v' ) unless ($opt_v); outstop('E'); } if ( defined($cache_warn) ) { outstart('E'); outline( 'E', '', '' ); outline( 'E', '', 'with Calamaris V3.x the Cache-File-Format is completely' ); outline( 'E', '', 'changed.' ); outline( 'E', '', '' ); outline( 'E', '', 'To re-use your old Cachefiles you\'ll first have to' ); outline( 'E', '', 'convert them with' ); outline( 'E', '', 'calamaris-cache-convert old.cache new.cache' ); outstop('E'); } if ( $opt_I and $opt_i ) { outstart('E'); outline( 'E', '', '' ); outline( 'E', '', 'You have run Calamaris with the -I (Interval) and the -i' ); outline( 'E', '', '(input cache) option. This is normally not useful,' ); outline( 'E', '', 'because the time-interval cannot be applied to' ); outline( 'E', '', 'cache-files.' ); outstop('E'); } if ($opt_ipfilter_exclude) { outstart('E'); outline( 'E', '', '' ); outline( 'E', '', 'The following IP addresses have been ignored:' ); foreach ( split ( ':', $opt_ipfilter_exclude ) ) { outline( 'E', '', " $_" ); } outstop('E'); } if ($opt_ipfilter_include) { outstart('E'); outline( 'E', '', '' ); outline( 'E', '', 'Only the following IP addresses have been recognized:' ); foreach ( split ( ':', $opt_ipfilter_include ) ) { outline( 'E', '', " $_" ); } outstop('E'); } if ( $outtype_html or $outtype_htmlembed or $outtype_htmlframe ) { $out_index_body .= ' '; @reportlist = ($opt_S) ? ( split ( ",", $opt_S ) ) : (0 .. $#reports); foreach ( @reportlist ) { outref($_) if $outref{$_}; } $out_index_body .= '
Table of Content / Overview
'; } if ( $outtype_html or $outtype_htmlembed or $outtype_htmlframe ) { my $year = (localtime)[5] + 1900; $out_tail = "
$HTMLCOPYRIGHT"; $out_tail .= ' ' if ($outtype_html or $outtype_htmlframe); } else { $out_tail .= "\n\n"; $out_tail .= "-- \n" if ($outtype_mail); $out_tail .= "Calamaris $VERSION\n$COPYRIGHT\n$LICENSE\n$HOMEPAGE\n"; } my $fh = *STDOUT; if ($opt_output_path or $opt_output_file or $opt_output_file_prefix) { print STDERR "writing output to $path/$file_prefix$filename\n" if $opt_v; if ($outtype_htmlframe) { open( OUT, ">$path/${file_prefix}overview.html" ) or die ("$0: can't open $path/${file_prefix}overview.html for writing: $!\n"); } else { open( OUT, ">$path/$file_prefix$filename" ) or die ("$0: can't open $path/$file_prefix$filename for writing: $!\n"); } $fh = *OUT; } print $fh $out_head; print $fh $out_index_head if $out_index_head; print $fh $out_index_body if $out_index_body; print $fh $out_tail if $outtype_htmlframe; if ($opt_output_path and $outtype_htmlframe) { # print frameset open( FRAME, ">$path/${file_prefix}framehead.html" ) or die ("$0: can't open $path/${file_prefix}framehead.html for writing: $!\n"); $frame = *FRAME; print $frame $out_head; print $frame $out_index_head; print $frame ' '; close($frame); open( FRAME, ">$path/$file_prefix$filename" ) or die ("$0: can't open $path/$file_prefix$filename for writing: $!\n"); $frame = *FRAME; print $frame ' ' . ($host_name ? "$host_name " : '') . 'Proxy Report (' . $loginterval . ') ' . ( $opt_M ? " $opt_M\n" : '' ) . ' <body> <p> Your browser is not able to view frames! Please follow this <a href="' . $file_prefix . 'toc.html">link</a> to get noframes. </p> <hr /> ' . $HTMLCOPYRIGHT . ' </body> '; close($frame); # print table of content open( TOC, ">$path/${file_prefix}toc.html" ) or die ("$0: can't open $path/${file_prefix}toc.html for writing: $!\n"); my $toc = *TOC; print $toc $out_head; outtoc(); print $toc $out_toc; print $toc ' '; close($toc); } @reportlist = ($opt_S) ? ( split ( ",", $opt_S ) ) : (0 .. $#reports); foreach $index ( 'E', @reportlist ) { if ( $outtype_htmlframe ) { open( OUT, ">$path/${file_prefix}$index.html" ) or die ("$0: can't open $path/${file_prefix}$index.html for writing: $!\n"); $fh = *OUT; print $fh $out_head; } if ($outref{$index}) { if ( not defined( $out_body{$index} ) and $index ne 'E' ) { outstart($index); outline( $index, 'no matching requests' ); outstop($index); } print $fh $out_body{$index} if defined( $out_body{$index} ); } if ($outtype_htmlframe) { print $fh $out_tail; close($fh); } } print $fh $out_tail unless $outtype_htmlframe; close($fh); print "$test_string\n" if $test; if ( $opt_generate_index and $opt_output_path and $opt_output_file_prefix) { opendir DIR, $opt_output_path or die("$0: can't opendir $opt_output_path: $!\n"); $pattern = $opt_output_file_prefix . $filename; $pattern =~ s#%h#(\\S+)#; $pattern =~ s#%t#(\\d{14}-\\d{14})#; $pattern =~ s#%%#%#; @files = grep { m#^$pattern# && -f "$opt_output_path/$_" } readdir(DIR); closedir DIR; $filename = 'index.html' unless $opt_output_file; open (INDEX, ">$opt_output_path/$filename") or die ("$0: can't open $opt_output_path/$filename for writing: $!\n"); print INDEX ' Proxy Report Index ' . ( $opt_M ? " $opt_M\n" : '' ) . '

Proxy Report Index

'; foreach (@files) { m#^$pattern#; if ($1 =~ m#\d{14}-\d{14}#) { $timestamp = $1; $host = $2; } else { $host = $1; $timestamp = $2; } ($startdate, $enddate) = split ('-', $timestamp) if $timestamp; print INDEX " \n"; } print INDEX '
Hostname Startdate Enddate
$host $startdate $enddate

' . $HTMLCOPYRIGHT . ' '; close(INDEX); } sub kilomegagigatera { my ($value) = shift (@_); my ($length) = $outtype_unformatted ? 999 : shift (@_); if ( $value > 10**( $length + 8 ) or $opt_U eq 'T' ) { return sprintf( '%d%s', int( ( $value / 1024**4 ) + .5 ), $outtype_unformatted ? '' : 'T' ); } elsif ( $value > 10**( $length + 5 ) or $opt_U eq 'G' ) { return sprintf( '%d%s', int( ( $value / 1024**3 ) + .5 ), $outtype_unformatted ? '' : 'G' ); } elsif ( $value > 10**( $length + 2 ) or $opt_U eq 'M' ) { return sprintf( '%d%s', int( ( $value / 1024**2 ) + .5 ), $outtype_unformatted ? '' : 'M' ); } elsif ( $value > 10**($length) or $opt_U eq 'K' ) { return sprintf( '%d%s', int( ( $value / 1024 ) + .5 ), $outtype_unformatted ? '' : 'K' ); } else { return $value; } } sub removezerotimes { my ($size) = shift (@_); my ($time) = shift (@_); if ( $size == 0 or $time == 0 ) { return '-'; } else { return $size / ( 1.024 * $time ); } } sub getfqdn { my ($host) = @_; if ( $host =~ m#^([^@]+@)?(::ffff:)?(([0-9][0-9]{0,2}\.){3}[0-9][0-9]{0,2}$)#o ) { $hostcache{$3} = addtonam($3) unless defined $hostcache{$3}; return $1 . $hostcache{$3} if defined $1; return $hostcache{$3}; } else { return $host; } } sub addtonam { my ($address) = shift (@_); my (@octets); my ( $host_name, $aliases, $type, $len, $addr ); my ($ip_number); @octets = split '\.', $address; if ( $#octets != 3 ) { undef; } $ip = pack( "CCCC", @octets[ 0 .. 3 ] ); ( $host_name, $aliases, $type, $len, $addr ) = gethostbyaddr( $ip, 2 ); if ($host_name) { $host_name; } else { $address; } } sub convertdate { my $date = shift (@_); my $type = shift (@_); if ($date) { my ( $sec, $min, $hour, $mday, $mon, $year ) = ( localtime($date) )[ 0, 1, 2, 3, 4, 5, 6 ]; my $month = $months[$mon]; $year += 1900; my $retdate = $type ? sprintf( "%04d%02d%02d%02d%02d%02d\n", $year, $mon+1, $mday, $hour, $min, $sec ) : sprintf( "%02d.%s %02d %02d:%02d:%02d\n", $mday, $month, substr( $year, -2 ), $hour, $min, $sec ); chomp($retdate); return $retdate; } else { return ' '; } } sub outtoc { $out_toc .= " "; @reportlist = ($opt_S) ? ( split ( ",", $opt_S ) ) : (0 .. $#reports); foreach ( @reportlist ) { $out_toc .= " "; } $out_toc .= '

Table of Content

Overview
Warnings
$reports[$_]
'; } sub outref { my $name = shift (@_); $link = ( $outtype_htmlframe ) ? "${file_prefix}${name}.html" : "#${name}"; if (defined($max_value[$name])) { $out_index_body .= " $reports[$name] $max_value[$name] "; } else { $out_index_body .= " $reports[$name] - - no requests found "; } } sub outstart { my $index = shift (@_); if ( $outtype_html or $outtype_htmlembed or $outtype_htmlframe ) { $out_body{$index} .= '
'; if ( $index eq 'E' ) { $out_body{$index} .= ' '; } else { $out_body{$index} .= '
'; } } else { $out_body{$index} .= "\n# $reports[$index]\n" unless ( $index eq 'E' ); } } sub outheader { my $index = shift (@_); my $print; my $no = 0; $out_body{$index} .= "\n " if ( $outtype_html or $outtype_htmlembed or $outtype_htmlframe ); foreach (@_) { $p = $_; $p = 'kB/sec' if ($format[$no] eq 'kbps' and $p eq 'auto'); $p = 'sec/kB' if ($format[$no] eq 'spkb' and $p eq 'auto'); $p = 'req/sec' if ($format[$no] eq 'rps' and $p eq 'auto'); $p = 'sec/req' if ($format[$no] eq 'spr' and $p eq 'auto'); $p = 'Byte/sec' if ($format[$no] eq 'bps' and $p eq 'auto'); $p = 'sec/Byte' if ($format[$no] eq 'spb' and $p eq 'auto'); $p = 'req/msec' if ($format[$no] eq 'rpms' and $p eq 'auto'); $p = 'msec/req' if ($format[$no] eq 'mspr' and $p eq 'auto'); if ($format[$no] eq 'off') { # do nothing } elsif ($outtype_unformatted) { $out_body{$index} .= "$p "; } elsif ( $outtype_html or $outtype_htmlembed or $outtype_htmlframe ) { $p =~ s# +# #go; $p =~ s#(^ | $)##go; $p = ' ' if ( $p eq '' ); $out_body{$index} .= " "; } elsif ( $format[$no] eq '%' ) { $out_body{$index} .= sprintf( ' ' x ( 6 - length($p) ) ) . substr( $p, 0, 6 ) . ' '; } elsif ( $format[$no] =~ m/[bps|spb|spkb|rps|rpms|spr]$/ ) { $out_body{$index} .= sprintf( substr( $p, 0, 7 ) . ' ' x ( 7 - length($p) ) . ' ' ); } else { $out_body{$index} .= sprintf( substr( $p, 0, $format[$no] ) . ' ' x ( $format[$no] - length($p) ) . ' ' ); } $no++; } $out_body{$index} .= "\n"; $out_body{$index} .= ' ' if ( $outtype_html or $outtype_htmlembed or $outtype_htmlframe ); } sub outimg { my $index = shift; $out_body{$index} .= " "; } sub outgraph { my $index = shift; my $legend_ref = shift; my $max_x_data = shift; my $xaxis_ref = shift; my $yaxis1_ref = shift; my $yaxis2_ref = shift; my $yaxis3_ref = shift; my $yaxis4_ref = shift; my ($factor0, $factor1, $unit0, $unit1, $min_x, $max_x); if ($max_x_data < 0) { # show last $max_x_data Values $min_x = ($#{$xaxis_ref} + $max_x_data < 0) ? 0 : $#{$xaxis_ref} + $max_x_data + 1; $max_x = $#{$xaxis_ref}; } else { # show first $max_x_data Values $min_x = 0; $max_x = ($#{$xaxis_ref} > $max_x_data) ? $max_x_data : $#{$xaxis_ref}; } my $graph = calamaris::calBars3d->new($width, int($width/3*2)); # check image-type if (! $verified) { @img_format = $graph->export_format; foreach ( @img_format ) { $format{$_} = 1; } if ( ! defined($format{$opt_image_type}) ) { # Image type not supported print STDERR "$0: $opt_image_type is not supported by GD::Graph!\n Please use one of the supported image types: @img_format \n\n"; exit(1); } $verified = 1; # don't do it on every 'sub outgraph' call } # 1 axis graph my @data = ([@$xaxis_ref[$min_x..$max_x]], [@$yaxis1_ref[$min_x..$max_x]]); ($factor0, $unit0) = getfactor(max(@$yaxis1_ref[$min_x..$max_x]),9); $yaxis1_ref = reformatarray($factor0, $yaxis1_ref) if ($factor0 > 1); my %graph_label = (x_label => '', y_label => "$unit0 ${$legend_ref}[0]", title => '', two_axes => '0', x_labels_vertical => '1', y_long_ticks => '1', y_tick_number => '5', x_ticks => '0', box_axis => '0', show_values => '0', values_vertical => '0', bar_spacing => '6', set_spacing => '0', shadowclr => 'lgray', shadow_depth => '0', boxclr => "$bg_color", fgclr => "$text_color", labelclr => "$text_color", axislabelclr => "$text_color", legendclr => "$text_color", valuesclr => "$text_color", textclr => "$text_color" ); $graph->set(%graph_label) or die $graph->error; # 2 axis graph if (scalar(@$legend_ref) > 1) { ($factor1, $unit1) = getfactor(max(@$yaxis2_ref[$min_x..$max_x]),5); $yaxis2_ref = reformatarray($factor1, $yaxis2_ref) if ($factor1 > 1); push @data, [@$yaxis2_ref[$min_x..$max_x]]; push @data, [@$yaxis3_ref[$min_x..$max_x]] if ref($yaxis3_ref); push @data, [@$yaxis4_ref[$min_x..$max_x]] if ref($yaxis4_ref); %graph_label = ( y1_label => "$unit0 ${$legend_ref}[0]", y2_label => "$unit1 ${$legend_ref}[1]", two_axes => '1', bar_spacing => '0', set_spacing => '6', ); } $graph->set(%graph_label) or die $graph->error; $graph->set_text_clr("$text_color"); $graph->set_legend(@$legend_ref); $graph->set( dclrs => [$column2_color, $column1_color] ); open(IMG, ">$path/${file_prefix}${index}.${opt_image_type}") or die ("$0: can't open $path/${file_prefix}${index}.${opt_image_type} for writing: $!\n"); binmode IMG; print IMG $graph->plot(\@data)->$opt_image_type; close(IMG); } sub maxi { my $max = -10e10; # an absolute small number my @array = @_; for ( $i = 0; $i <= $#array; $i++ ) { if ($array[$i] > $max ) { $max = $array[$i]; $maxi = $i; } } return $max, $maxi; } sub max { my $max = -10e10; # an absolute small number foreach (@_) { $max = $_ if $_ > $max } return $max; } sub reformatarray { my $factor = shift; my $array_ref = shift; my @array; foreach ( @$array_ref ) { push @array, $_/$factor } return \@array; } sub getfactor { my ($value) = shift (@_); my ($length) = $outtype_unformatted ? 999 : shift (@_); my ($factor, $unit); if ( $value > 10**( $length + 8 ) or $opt_U eq 'T' ) { $factor = 1024**4; $unit = 'Tera'; } elsif ( $value > 10**( $length + 5 ) or $opt_U eq 'G' ) { $factor = 1024**3; $unit = 'Giga'; } elsif ( $value > 10**( $length + 2 ) or $opt_U eq 'M' ) { $factor = 1024**2; $unit = 'Mega'; } elsif ( $value > 10**($length) or $opt_U eq 'K' ) { $factor = 1024; $unit = 'Kilo'; } else { $factor = 1; $unit = ''; } return $factor, $unit; } sub outline { my $index = shift (@_); my $linecolor = shift (@_); my $print; my $no = 0; $out_body{$index} .= "\n " if ( $outtype_html or $outtype_htmlembed or $outtype_htmlframe ); $color = 0 unless $linecolor; if ($linecolor eq 'toggle') { $color = $color ? 0 : 1; } elsif ($linecolor) { $color = $linecolor; } foreach (@_) { $print = $_; if ($format[$no] eq 'off') { # do nothing } elsif ($outtype_unformatted) { $out_body{$index} .= "$print "; } elsif ( $outtype_html or $outtype_htmlembed or $outtype_htmlframe ) { $print =~ s# +# #go; $print =~ s# $##go; $print =~ s#<#\<\;#go; $print =~ s#>#\>\;#go; if ( $no == 0 ) { unless ( $print =~ s#^ ##go ) { $out_body{$index} .= " "; } else { $out_body{$index} .= " "; } } elsif ( $format[$no] eq '%' ) { if ( $print eq '' or $print eq '-' ) { $out_body{$index} .= " "; } else { $out_body{$index} .= sprintf( ' ', $color, $print ); } } elsif ( $format[$no] =~ m/[bps|spb|spkb|rps|rpms|spr]$/ ) { my $factor = 1; $factor = 1000 if ($format[$no] =~ m#^rpms$# or $format[$no] =~ m#^mspr$#); $factor = 1024 if ($format[$no] =~ m#^bps$# or $format[$no] =~ m#^spb$#); if ( $print eq '' or $print eq '-' ) { $out_body{$index} .= " "; # kByte/sec } elsif ($format[$no] =~ m/bps/) { $out_body{$index} .= sprintf( ' ', $color, $print * $factor ); # sec/kByte } elsif ($format[$no] =~ m/spkb/ or $format[$no] =~ m/spb/) { $out_body{$index} .= sprintf( ' ', $color, 1 / ($factor * $print) ); # req/[m]sec } elsif ($format[$no] =~ m/rps/ or $format[$no] =~ m/rpms/) { $out_body{$index} .= sprintf( ' ', $color, 1 / ($print * $factor) ); # [m]sec/req } elsif ($format[$no] =~ m/spr/) { $out_body{$index} .= sprintf( ' ', $color, $print * $factor ); # % } else { $out_body{$index} .= sprintf( ' ', $color, $print ); } } elsif ( $no == 1 and $print !~ m#^[\d\.e\-\+]+$#o ) { $out_body{$index} .= sprintf( ' ', $color, $print ); } elsif ( $no == 1 or $print =~ m#^[\d\.e\-\+]+$#o ) { $out_body{$index} .= sprintf( ' ', $color, $print ); } else { if ($print) { $out_body{$index} .= " "; } else { $out_body{$index} .= " "; } } } else { if ( $no == 0 ) { if ( length($print) > $format[$no] ) { $out_body{$index} .= $print . sprintf( "\n" . ' ' x $format[$no] . ' ' ); } else { $out_body{$index} .= $print . sprintf( ' ' x ( $format[$no] - length($print) ) . ' ' ); } } elsif ( $format[$no] eq '10%' ) { if ( $print eq '' or $print eq '-' ) { $out_body{$index} .= ' ' x 11; } else { $out_body{$index} .= sprintf( '%10.2f ', $print ); } } elsif ( $format[$no] eq '%' ) { if ( $print eq '' or $print eq '-' ) { $out_body{$index} .= ' ' x 7; } else { $out_body{$index} .= sprintf( '%6.2f ', $print ); } } elsif ( $format[$no] =~ m/[bps|spb|spkb|rps|rpms|spr]$/ ) { my $factor = 1; $factor = 1000 if ($format[$no] =~ m#^rpms$# or $format[$no] =~ m#^mspr$#); $factor = 1024 if ($format[$no] =~ m#^bps$# or $format[$no] =~ m#^spb$#); if ( $print eq '-' ) { $out_body{$index} .= ' - '; # [k]Byte/sec } elsif ($format[$no] =~ m/bps/) { if ( $print >= 10000 ) { $out_body{$index} .= sprintf( '%7.0f ', $factor * $print ); } else { $out_body{$index} .= sprintf( '%7.2f ', $factor * $print ); } # sec/[k]Byte } elsif ($format[$no] =~ m/spkb/ or $format[$no] =~ m/spb/) { if ( $print >= 1000 ) { $out_body{$index} .= sprintf( '%7.0f ', 1 / ($factor * $print) ); } else { $out_body{$index} .= sprintf( '%7.3f ', 1 / ($factor * $print) ); } # req/[m]sec } elsif ($format[$no] =~ m/rps/ or $format[$no] =~ m/rpms/) { if ( $print >= 10000 ) { $out_body{$index} .= sprintf( '%7.0f ', 1 / ($factor * $print) ); } else { $out_body{$index} .= sprintf( '%7.2f ', 1 / ($factor * $print) ); } # [m]sec/req } elsif ($format[$no] =~ m/spr/) { if ( $print >= 10000 ) { $out_body{$index} .= sprintf( '%7.0f ', $factor * $print ); } else { $out_body{$index} .= sprintf( '%7.2f ', $factor * $print ); } } } else { $print = sprintf( '%d', $print + .5 ) if $print =~ m#^[\d\.e\-\+]+$#o; $out_body{$index} .= sprintf( ' ' x ( $format[$no] - length($print) ) ) . substr( $print, 0, $format[$no] ) . ' '; } } $no++; } $out_body{$index} .= "\n"; $out_body{$index} .= ' ' if ( $outtype_html or $outtype_htmlembed or $outtype_htmlframe); } sub outseperator { my $index = shift (@_); my $print; $out_body{$index} .= "\n " if ( $outtype_html or $outtype_htmlembed or $outtype_htmlframe ); foreach $print (@format) { next if $print eq 'off'; if ($outtype_unformatted) { $out_body{$index} .= "--- "; } elsif ( $outtype_html or $outtype_htmlembed or $outtype_htmlframe ) { $out_body{$index} .= ' '; } elsif ( $print eq '10%' ) { $out_body{$index} .= sprintf( '-' x 10 . ' ' ); } elsif ( $print eq '%' ) { $out_body{$index} .= sprintf( '-' x 6 . ' ' ); } elsif ( $print =~ m/[bps|spb|spkb|rps|rpms|spr]$/ ) { $out_body{$index} .= sprintf( '-' x 7 . ' ' ); } else { $out_body{$index} .= sprintf( '-' x $print . ' ' ); } } $out_body{$index} .= "\n"; $out_body{$index} .= ' ' if ( $outtype_html or $outtype_htmlembed or $outtype_htmlframe ); } sub outstop { my $index = shift (@_); my $link = ($outtype_htmlframe) ? "$file_prefix$filename" : '#top'; if ( $outtype_html or $outtype_htmlembed or $outtype_htmlframe ) { $out_body{$index} .= '
' . $reports[$index] . '
$p
\"Graphic:
$print   $print   %.2f   %.2f %.2f %.2f %.2f %.2f %s %d $print  
'; $out_body{$index} .= '

Back to Top

' unless $outtype_htmlframe; } else { $out_body{$index} .= "\n"; } } sub writecache { print CACHE join ( 'µ', @_ ) . "\n" if $opt_o; } sub geterrcode { my %err_code; $err_code{'000'} = 'Used mostly with UDP traffic'; $err_code{'100'} = 'Continue'; $err_code{'101'} = 'Switching Protocols'; $err_code{'102'} = 'Processing'; $err_code{'200'} = 'OK'; $err_code{'201'} = 'Created'; $err_code{'202'} = 'Accepted'; $err_code{'203'} = 'Non-Authoritative Information'; $err_code{'204'} = 'No Content'; $err_code{'205'} = 'Reset Content'; $err_code{'206'} = 'Partial Content'; $err_code{'207'} = 'Multi Status'; $err_code{'300'} = 'Multiple Choices'; $err_code{'301'} = 'Moved Permanently'; $err_code{'302'} = 'Moved Temporarily'; $err_code{'303'} = 'See Other'; $err_code{'304'} = 'Not Modified'; $err_code{'305'} = 'Use Proxy'; $err_code{'307'} = 'Temporary Redirect'; $err_code{'400'} = 'Bad Request'; $err_code{'401'} = 'Unauthorized'; $err_code{'402'} = 'Payment Required'; $err_code{'403'} = 'Forbidden'; $err_code{'404'} = 'Not Found'; $err_code{'405'} = 'Method Not Allowed'; $err_code{'406'} = 'Not Acceptable'; $err_code{'407'} = 'Proxy Authentication Required'; $err_code{'408'} = 'Request Timeout'; $err_code{'409'} = 'Conflict'; $err_code{'410'} = 'Gone'; $err_code{'411'} = 'Length Required'; $err_code{'412'} = 'Precondition Failed'; $err_code{'413'} = 'Request Entity Too Large'; $err_code{'414'} = 'Request URI Too Large'; $err_code{'415'} = 'Unsupported Media '; $err_code{'416'} = 'Request Range Not Satisfiable'; $err_code{'417'} = 'Expectation Failed'; $err_code{'424'} = 'Locked'; $err_code{'424'} = 'Failed Dependency'; $err_code{'433'} = 'Unprocessable Entity'; $err_code{'500'} = 'Internal Server Error'; $err_code{'501'} = 'Not Implemented'; $err_code{'502'} = 'Bad Gateway'; $err_code{'503'} = 'Service Unavailable'; $err_code{'504'} = 'Gateway Timeout'; $err_code{'505'} = 'HTTP Version Not Supported'; $err_code{'507'} = 'Insufficient Storage'; $err_code{'600'} = 'Squid header parsing error'; return %err_code; } sub readconfig { # Default values undef($benchmark); undef($cache_input_file); undef($cache_output_file); undef($domain_report); undef($domain_report_limit); undef($domain_report_n_level); undef($errorcode_distribution_report); undef($generate_index); undef($hostname); undef($input_format); undef($ipfilter_exclude); undef($ipfilter_include); undef($logo); undef($meta); undef($no_input); undef($object_freshness_report); undef($output_file); undef($output_file_prefix); undef($output_format); undef($output_path); undef($peak_report); undef($performance_report); undef($performance_report_adjust); undef($requester_report); undef($requester_report_no_dns_lookup); undef($requester_report_use_user_info); undef($requester_report_with_targets); undef($response_time_report); undef($show_reports); undef($size_distribution_report); undef($sort_order); undef($status_report); undef($time_interval); undef($type_report); undef($type_report_ignore_case); undef($unit); undef($verbose); @response_time_report_interval = qw( 0.001 0.01 0.02 0.05 0.1 0.2 0.5 1 2 5 10 20 50 100 200 500 1000 2000 5000 10000 20000 50000 100000 200000 500000 1000000 1e10 ); $response_time_limit = $response_time_report_interval[$#response_time_report_interval]; # show $show_other_tcp_urlhost = 1; $show_other_tcp_urltld = 1; $show_other_tcp_content = 1; $show_other_tcp_urlext = 1; $show_other_udp_requester = 1; $show_other_tcp_requester = 1; # GRAPH SECTION $column1_color = '#6699cc'; $column2_color = '#ff9900'; $text_color = '#222266'; $bg_color = '#ffffcc'; $x_scale = 30; $image_type = 'png'; $width = 600; $test = 0; $verified = 0; @graph_legend = ('Requests', 'Byte', 'Request Hit Rate', 'Byte Hit Rate'); # HTML SECTION if ($opt_config_file) { my $file = $opt_config_file; my $return; unless ($return = do $file) { warn "$0: Parsing of $file failed: $@" if $@; warn "$0: do on $file failed: $!" unless defined $return; warn "$0: couldn't execute $file" unless $return; } } $opt_b = $benchmark unless $opt_b; $opt_i = $cache_input_file unless $opt_i; $opt_o = $cache_output_file unless $opt_o; $opt_d = $domain_report unless $opt_d; $opt_domain_report_limit = $domain_report_limit unless $opt_domain_report_limit; $opt_N = $domain_report_n_level unless $opt_N; $opt_errorcode_distribution = $errorcode_distribution_report unless $opt_errorcode_distribution; $opt_H = $hostname unless $opt_H; $opt_c = $type_report_ignore_case unless $opt_c; $opt_f = $input_format unless $opt_f; $opt_image_type = $image_type unless $opt_image_type; $opt_generate_index = $generate_index unless $opt_generate_index; $opt_ipfilter_exclude = $ipfilter_exclude unless $opt_ipfilter_exclude; $opt_ipfilter_include = $ipfilter_include unless $opt_ipfilter_include; $opt_l = $logo unless $opt_l; $opt_M = $meta unless $opt_M; $opt_z = $no_input unless $opt_z; $opt_output_file = $output_file unless $opt_output_file; $opt_output_file_prefix = $output_file_prefix unless $opt_output_file_prefix; $opt_F = $output_format unless $opt_F; $opt_output_path = $output_path unless $opt_output_path; $opt_p = $peak_report unless $opt_p; $opt_P = $performance_report unless $opt_P; $opt_T = $performance_report_adjust unless $opt_T; $opt_r = $requester_report unless $opt_r; $opt_n = $requester_report_no_dns_lookup unless $opt_n; $opt_u = $requester_report_use_user_info unless $opt_u; $opt_R = $requester_report_with_targets unless $opt_R; $opt_response_time = $response_time_report unless $opt_response_time; undef($opt_response_time) unless scalar(@response_time_report_interval); $opt_S = $show_reports unless $opt_S; $opt_D = $size_distribution_report unless $opt_D; $opt_O = $sort_order unless $opt_O; $opt_s = $status_report unless $opt_s; $opt_I = $time_interval unless $opt_I; $opt_t = $type_report unless $opt_t; $opt_U = $unit unless $opt_U; $opt_v = $verbose unless $opt_v; # -M: if it's a file, read it and store it in $opt_M if ( defined($opt_M) and $opt_M !~ /\n/ and -e $opt_M ) { open(IN, "<$opt_M") or die "$0: Couldn't open file $opt_M for reading: $!\n"; $opt_M = ''; while () { $opt_M .= $_ } } # -l: if it's a file, read it and store it in $opt_l if ( defined($opt_l) and $opt_l !~ /\n/ and -e $opt_l ) { open(IN, "<$opt_l") or die "$0: Couldn't open file $opt_l for reading: $!\n"; $opt_l = ''; while () { $opt_l .= $_ } } if ( $opt_b and $opt_b < 1 ) { print STDERR "$0: wrong value at -b -option: \"$opt_b\"\n\n"; $usage_err = 1; } else { $| = 1; } if ($opt_U) { unless ( $opt_U =~ m#^[KMGT]$# ) { print STDERR "$0: wrong value at -U -option: \"$opt_U\"\n\n"; $usage_err = 1; } } else { $opt_U = ''; } if ($opt_D) { if ( $opt_D <= 1 ) { print STDERR "$0: wrong value at -D -option: \"$opt_D\"\n\n"; $usage_err = 1; } } if ($opt_H) { if ( $opt_H eq '1' or $opt_H eq 'lookup' ) { $host_name = hostname(); } else { $host_name = $opt_H; } } else { $host_name = ''; } if ($opt_ipfilter_exclude or $opt_ipfilter_include) { unless (eval "require NetAddr::IP") { print STDERR "$0: You need package NetAddr::IP for ipfilter-*-Option, I searched it in @INC: $!\n\n"; $usage_err = 1; } } if ( $opt_N and $opt_N != -1 and $opt_N < 2 ) { print STDERR "$0: wrong value at -N -option: \"$opt_N\"\n\n"; $usage_err = 1; } if ($opt_I) { use Time::Local; ( $interval_begin, $interval_end ) = split ( '-', $opt_I ); if ( $interval_begin =~ m#^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$# ) { $interval_begin = timelocal( $6, $5, $4, $3, $2 - 1, $1 - 1900 ); } elsif ( $interval_begin eq '' ) { $interval_begin = 0; } else { print STDERR "$0: wrong value at -I -option: \"$opt_I\"\n\n"; $usage_err = 1; } if ( $interval_end =~ m#^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$# ) { $interval_end = timelocal( $6, $5, $4, $3, $2 - 1, $1 - 1900 ); } elsif ( $interval_end eq '' ) { $interval_end = 9999999999; } else { print STDERR "$0: wrong value at -I -option: \"$opt_I\"\n\n"; $usage_err = 1; } if ($interval_begin > $interval_end) { print STDERR "$0: wrong value at -I -option: \"$opt_I\". Interval begin newer than interval end!\n\n"; $usage_err = 1; } } $path = $opt_output_path ? $opt_output_path : '.'; if (-d "$path") { unless (-w "$path") { print STDERR "$0: directory $path not writable: $!\n\n"; $usage_err = 1; } } else { use File::Path qw(make_path); make_path( "$path", {error => \my $err} ); if (@err) { print STDERR "$0: can't create directory $path: @err\n\n"; $usage_err = 1; } } $filename = $opt_output_file ? $opt_output_file : 'calamaris.txt'; $file_prefix = $opt_output_file_prefix ? $opt_output_file_prefix : ''; if ($opt_F) { $outtype_htmlembed = $outtype_htmlframe = $outtype_html = 0; foreach $output ( split ( /\s*,\s*/, $opt_F ) ) { if ($output eq 'mail') { $outtype_mail = 1; } elsif ($output eq 'html') { $outtype_html = 1; } elsif ($output eq 'html-embed') { $outtype_htmlembed = 1; } elsif ($output eq 'html-frame') { $outtype_htmlframe = 1; } elsif ( $output eq 'graph' ) { unless (eval "require GD::Graph") { print STDERR "$0: You need package GD::Graph for -F 'graph'-Option, I searched it in @INC: $!\n\n"; $usage_err = 1; } use lib "$ENV{PWD}/../"; unless (eval "require calamaris::calBars3d") { print STDERR "$0: You need package calamaris::calBars3d for -F 'graph'-Option, I searched it in @INC: $!\n\n"; $usage_err = 1; } $outtype_graph = 1; } elsif ( $output eq 'unformatted' ) { $outtype_unformatted = 1; } else { print STDERR "$0: unknown output-format: $output\n\n"; $usage_err = 1; } } if ( ( $outtype_htmlembed + $outtype_htmlframe + $outtype_html ) > 1 ) { print STDERR "$0: only one of 'html', 'html-embed' or 'html-frame' can be used: $opt_F\n\n"; $usage_err = 1; } if ( $outtype_mail and ($outtype_htmlembed or $outtype_htmlframe or $outtype_graph) ) { print STDERR "$0: 'mail' together with 'html-embed', 'html-frame' or 'graph' won't work: $opt_F\n\n"; $usage_err = 1; } print STDERR "$0: please use --output-path /path, when using -F 'graph'\n\n" if ( $outtype_graph and not $opt_output_path ); if ($outtype_graph and not ($outtype_html or $outtype_htmlembed or $outtype_htmlframe) ) { print STDERR "$0: -F 'graph' is kinda useless without 'html', 'html-embed' or 'html-frame'.\n\n"; } } if ( $opt_generate_index and not $opt_output_path and not $opt_output_file_prefix) { print STDERR "$0: --generate-index needs --output-path and --output-file-prefix\n"; } if ($outtype_htmlembed or $outtype_html or $outtype_htmlframe) { $filename = $opt_output_file ? $opt_output_file : 'index.html'; } $sortorder = $opt_O ? '_size' : ''; if ($opt_a) { $opt_response_time = 1; $opt_errorcode_distribution = 1; $opt_D = 10 unless $opt_D; $opt_P = 60 unless $opt_P; $opt_d = 20 unless $opt_d; $opt_r = 20 unless $opt_r; $opt_s = 1; $opt_t = 20 unless $opt_t; } $opt_domain_report_limit = 0 unless $opt_domain_report_limit; $opt_N = 2 unless $opt_N; $opt_T = 0 unless $opt_T; $opt_r = $opt_R unless $opt_r; if ($object_freshness_report) { $opt_t = 20 unless $opt_t; } $P = $opt_P ? "$opt_P minute" : '60 minute'; $P = $opt_P/60 . ' hour' if ( defined($opt_P) and ($opt_P % 60) == 0 and $opt_P >= 60 ); $P = $opt_P/1440 . ' day' if ( defined($opt_P) and ($opt_P % 1440) == 0 and $opt_P >= 1440 ); if ( $opt_N == -1 or $opt_N > 2 ) { if ( $opt_N == 3 ) { $N = '3rd'; } elsif ( $opt_N == -1 ) { $N = 'all'; } else { $N = $opt_N . 'th'; } } else { $N = '2nd'; } $outref{E} = 1; $outref{0} = 1; $outref{1} = ($opt_p) ? 1 : 0; $outref{2} = ($opt_p and $opt_p eq 'new') ? 1 : 0; $outref{3} = 1; $outref{4} = 1; $outref{5} = 1; $outref{6} = 1; $outref{7} = 1; $outref{8} = ($opt_d) ? 1 : 0; $outref{9} = ($opt_d) ? 1 : 0; $outref{10} = ($opt_t) ? 1 : 0; $outref{11} = ($opt_t) ? 1 : 0; $outref{12} = ($opt_t) ? 1 : 0; $outref{13} = ($opt_r) ? 1 : 0; $outref{14} = ($opt_r) ? 1 : 0; $outref{15} = ($opt_D) ? 1 : 0; $outref{16} = ($opt_P) ? 1 : 0; $outref{17} = ($opt_response_time) ? 1 : 0; $outref{18} = ($opt_response_time) ? 1 : 0; $outref{19} = ($opt_errorcode_distribution) ? 1 : 0; $outref{20} = ($opt_errorcode_distribution) ? 1 : 0; @reports = ( 'Summary', 'Incoming request peak per protocol', 'Incoming transfer volume peak per protocol', 'Incoming requests by method', 'Incoming UDP-requests by status', 'Incoming TCP-requests by status', 'Outgoing requests by status', 'Outgoing requests by destination', "Request-destinations by ${N}-level-domain", 'Request-destinations by toplevel-domain', 'TCP-Request-protocol', 'Requested content-type', 'Requested extensions', 'Incoming UDP-requests by host', 'Incoming TCP-requests by host', 'Size Distribution Diagram', "Performance in $P steps", 'UDP-Request duration distribution in msec', 'TCP-Request duration distribution in msec', 'UDP Response code distribution', 'TCP Response code distribution' ); $LICENSE = 'Calamaris comes with ABSOLUTELY NO WARRANTY. It is free software, and you are welcome to redistribute it under certain conditions. See source for details.'; $COPYRIGHT = 'Copyright (C) 1997-2006, 2013, 2015 Cord Beermann. Authors: Cord Beermann and Michael Pophal.'; $HOMEPAGE = 'http://Calamaris.Cord.de/'; $HTMLCOPYRIGHT = '
Calamaris ' . $VERSION . ', Copyright © 1997-2006, 2013, 2015 Cord Beermann. Authors: Cord Beermann and Michael Pophal.

' . $LICENSE . '

'; $USAGE = ' Usage: cat log | ' . $0 . ' --config-file /path/to/calamaris.conf [switches] or cat log | ' . $0 . ' [switches] --config-file file Not all reports and modification can be made through command-line-switches. To use all options of Calamaris you\'ll have to use the configuration file. see the manpage for the configuration-file syntax. Reports: --all-useful-reports|-a extracts all useful reports available, --all-useful-reports equals --size-distribution-report 10 \ --domain-report 20 \ --performance-report 60 \ --requester-report 20 \ --status-report \ --type-report 20 \ --response-time-report \ --errorcode-distribution-report --domain-report|-d n show n Top-level and n second-level destinations, -1 = unlimited --domain-report-limit n limit display of domains to those with n requests or more. --domain-report-n-level|-N n change all 2nd-level-reports to n-level-reports. n can be any number from 2 up. -1 means full report. --errorcode-distribution-report shows the Response code distribution over all objects --peak-report|-p type measure peak requests old = make old request-peak mesurement new = make new request&byte-peak measurement (both slow Calamaris significantly down.) --performance-report|-P n show throughput data for every n minutes --performance-report-adjust|-T n adjust the Performance-Report in minutes --requester-report|-r n show n Requesters, -1 = unlimited --requester-report-no-dns-lookup|-n don\'t look IP-Numbers up --requester-report-use-user-info|-u use ident information if available (*) --requester-report-with-targets|-R n show n targets for every Requester, -1 = unlimited), implies --requester-report (*) --response-time-report shows the time distribution over all objects --size-distribution-report|-D n shows size-based distribution of requested objects, smaller numbers result in more verbose reports. choose 2, 10 or 100 for useful output. (You can also play with this ;-)) --status-report|-s show verbose status reports --type-report|-t n show n content-type, n extensions and requested protocols, -1 = unlimited --type-report-ignore-case|-c switch to case-insensitive (useful for extensions-report) More reports and report-modifications are available via the configuration-file. see manpage. Input: --input-format|-f type sets the type of input logfiles auto = tries to guess the input format (This is the Default) squid = Native-Logfile derived from Squid V1.1.beta26-V2.x squid-extended = Native-Logfile with log_mime_hdrs enabled derived from Squid V1.1.beta26-V2.x (*) or Cisco Content Engines (*) or Squid with SmartFilter-patch (*) squid-old = Native-Logfile derived from Squid V1.1.alpha1-V1.1.beta25 nc = Squid-style Logfiles derived from NetCache V?? (<5.x) its = Logfiles derived from Inktomi Traffic Server elff = Extended Logfile Format (i.e Compaq Tasksmart, Novell Internet Caching System, NetCache 5.x, BlueCoat) nse = Netscape Extended-1/2 Logfile Format --ipfilter-exclude IP/range all IPs are analyzed, except IP/range. (*) Format: 1.1.1.1/32:1.1.2.0/24 1.1.1.1/255.255.255.255:1.1.2.0/255.255.255.0 IP list separated by \':\' This switch needs the perl Module NetAddr::IP. --ipfilter-include IP/range no IPs are analyzed, except IP/range. (*) Format: see --ipfilter-exclude --no-input|-z no input via stdin --time-interval|-I t-t defines which time-interval should be parsed. t has to be the format yyyymmddhhmmss (localtime). omitting the beginning or ending is allowed. Output: (Default is plain formatted text) --hostname|-H name a name for the Output, -H \'lookup\' issues a lookup for the current host --image-type Sets the image type to gif, png, jpeg, gd or gd2. Only usefull when --output-format graph is set. The supported images types are dependend on your GD::Graph installation. --logo|-l string add this string to the head of the report. works only in combination with --output-format html or html-frame --meta|-M string/file includes the given strings in html-. If a file is given, the file is included in html-. works only in combination with --output-format html or html-frame --output-format|-F type output format (comma-seperated list) mail = mail format, disables graph output. html = HTML format html-frame = HTML frames, disables mail output. html-embed = HTML format without HTML-headers. graph = enable graphics, needs GD::Graph, only useful with html or html-embed, see --output-path. Disables mail output. This switch needs the perl Module GD::Graph. unformatted = plain unformatted output --output-path /path --output-file-prefix string --output-file filename output calamaris statistics to /path. In case of graph output, the graphics destination is /path and the filename is index.html, else it is calamaris.txt. If --output-path is not given, all graphics are written to the working directory. %h will be expanded to the hostname, %t to a timerange, %% to a single %. --generate-index Generates an index-file of all matching reports if output-path and output-file-prefix is set --show-reports|-S list Shows only the defined reports (comma-seperated list) in the specified order. The following numbers are defined: '; foreach ( 0 .. $#reports ) { $USAGE .= "\t $_\t$reports[$_]\n"; } $USAGE .= ' Note: only putting out one report does not speed up Calamaris as the internal operations were done based on the report-switches. Default: Reports are displayed based on activated reports. --sort-order|-O changes the sort order in the reports to request size, default is sorting by number of requests --unit|-U string define the Unit for the Byte-values, else it will be auto. K(ilo), M(ega), G(iga), T(era) There are more options to modify the output of Calamaris. Please see the man-page. Caching: --cache-input-file|-i file input-datafile for caching, to add many files separate them with a \':\') --cache-output-file|-o file output-datafile for caching, can be the same as --cache-input-file Misc: --benchmark|-b n prints a hash-sign (#) to stderr for each n lines processed --copyright|-C prints the copyright --help|-h prints out this message --version|-V prints version-info Debug: --verbose|-v print information what Calamaris is doing. Useful for debugging. --dump-loop|-L dumps the generated internal loop to STDERR for debugging. (*) These options break the privacy of your users. Please read the README on this.'; } sub readcache { ### Read Cache. foreach $file ( split ':', $opt_i ) { open( CACHE, "$file" ) or die ("$0: can't open $file for reading: $!\n"); while () { chomp; next if m#^$#; @cache = split 'µ'; $x = shift (@cache); next unless ($x ne ''); if ( $x eq '0' and $#cache == 39 ) { $time_begin = $cache[0] if $cache[0] < $time_begin; $time_end = $cache[1] if $cache[1] > $time_end; $counter += $cache[2]; $size += $cache[3]; $time += $cache[4]; $invalid += $cache[5]; $time_run += $cache[6]; $udp += $cache[7]; $udp_size += $cache[8]; $udp_time += $cache[9]; $udp_hit += $cache[10]; $udp_hit_size += $cache[11]; $udp_hit_time += $cache[12]; $udp_miss += $cache[13]; $udp_miss_size += $cache[14]; $udp_miss_time += $cache[15]; $tcp += $cache[16]; $tcp_size += $cache[17]; $tcp_time += $cache[18]; $tcp_hit += $cache[19]; $tcp_hit_size += $cache[20]; $tcp_hit_time += $cache[21]; $tcp_miss += $cache[22]; $tcp_miss_size += $cache[23]; $tcp_miss_time += $cache[24]; $tcp_miss_none += $cache[25]; $tcp_miss_none_size += $cache[26]; $tcp_miss_none_time += $cache[27]; $hier += $cache[28]; $hier_size += $cache[29]; $hier_time += $cache[30]; $hier_direct += $cache[31]; $hier_direct_size += $cache[32]; $hier_direct_time += $cache[33]; $hier_sibling += $cache[34]; $hier_sibling_size += $cache[35]; $hier_sibling_time += $cache[36]; $hier_parent += $cache[37]; $hier_parent_size += $cache[38]; $hier_parent_time += $cache[39]; } elsif ( $x eq '1' and $#cache == 17 ) { unless ( $peak_udp_sec == 0 ) { warn("multiple cache files.\n") if $opt_v; $peak_warn = 'Peak values are possibly wrong!'; } if ( $peak_udp_sec < $cache[0] ) { $peak_udp_sec = $cache[0]; $peak_udp_sec_time = $cache[1]; } if ( $peak_udp_min < $cache[2] ) { $peak_udp_min = $cache[2]; $peak_udp_min_time = $cache[3]; } $peak_udp_hour{ $cache[5] } = 0 unless defined $peak_udp_hour{ $cache[5] }; $peak_udp_hour{ $cache[5] } += $cache[4]; if ( $peak_tcp_sec < $cache[6] ) { $peak_tcp_sec = $cache[6]; $peak_tcp_sec_time = $cache[7]; } if ( $peak_tcp_min < $cache[8] ) { $peak_tcp_min = $cache[8]; $peak_tcp_min_time = $cache[9]; } $peak_tcp_hour{ $cache[11] } = 0 unless defined $peak_tcp_hour{ $cache[11] }; $peak_tcp_hour{ $cache[11] } += $cache[10]; if ( $peak_all_sec < $cache[12] ) { $peak_all_sec = $cache[12]; $peak_all_sec_time = $cache[13]; } if ( $peak_all_min < $cache[14] ) { $peak_all_min = $cache[14]; $peak_all_min_time = $cache[15]; } $peak_all_hour{ $cache[17] } = 0 unless defined $peak_all_hour{ $cache[17] }; $peak_all_hour{ $cache[17] } += $cache[16]; } elsif ( $x eq '1' and $#cache == 23 ) { unless ( $peak_udp_sec == 0 ) { warn("multiple cache files.\n") if $opt_v; $peak_warn = 'Peak values are possibly wrong!'; } if ( $peak_udp_sec < $cache[0] ) { $peak_udp_sec = $cache[0]; $peak_udp_sec_time = $cache[1]; } if ( $peak_udp_min < $cache[2] ) { $peak_udp_min = $cache[2]; $peak_udp_min_time = $cache[3]; } $peak_udp_hour{ $cache[5] } = 0 unless defined $peak_udp_hour{ $cache[5] }; $peak_udp_hour{ $cache[5] } += $cache[4]; $peak_udp_hour_size{ $cache[7] } = 0 unless defined $peak_udp_hour_size{ $cache[7] }; $peak_udp_hour_size{ $cache[7] } += $cache[6]; if ( $peak_tcp_sec < $cache[8] ) { $peak_tcp_sec = $cache[8]; $peak_tcp_sec_time = $cache[9]; } if ( $peak_tcp_min < $cache[10] ) { $peak_tcp_min = $cache[10]; $peak_tcp_min_time = $cache[11]; } $peak_tcp_hour{ $cache[13] } = 0 unless defined $peak_tcp_hour{ $cache[13] }; $peak_tcp_hour{ $cache[13] } += $cache[12]; $peak_tcp_hour_size{ $cache[15] } = 0 unless defined $peak_tcp_hour_size{ $cache[15] }; $peak_tcp_hour_size{ $cache[15] } += $cache[14]; if ( $peak_all_sec < $cache[16] ) { $peak_all_sec = $cache[16]; $peak_all_sec_time = $cache[17]; } if ( $peak_all_min < $cache[18] ) { $peak_all_min = $cache[18]; $peak_all_min_time = $cache[19]; } $peak_all_hour{ $cache[21] } = 0 unless defined $peak_all_hour{ $cache[21] }; $peak_all_hour{ $cache[21] } += $cache[20]; $peak_all_hour_size{ $cache[23] } = 0 unless defined $peak_all_hour_size{ $cache[23] }; $peak_all_hour_size{ $cache[23] } += $cache[22]; } elsif ( $x eq '3' and $#cache == 3 ) { $y = shift (@cache); $method{$y} = $method_size{$y} = $method_time{$y} = 0 unless defined $method{$y}; $method{$y} += $cache[0]; $method_size{$y} += $cache[1]; $method_time{$y} += $cache[2]; } elsif ( $x eq '4.1' and $#cache == 3 ) { $y = shift (@cache); $udp_hit{$y} = $udp_hit_size{$y} = $udp_hit_time{$y} = 0 unless defined $udp_hit{$y}; $udp_hit{$y} += $cache[0]; $udp_hit_size{$y} += $cache[1]; $udp_hit_time{$y} += $cache[2]; } elsif ( $x eq '4.2' and $#cache == 3 ) { $y = shift (@cache); $udp_miss{$y} = $udp_miss_size{$y} = $udp_miss_time{$y} = 0 unless defined $udp_miss{$y}; $udp_miss{$y} += $cache[0]; $udp_miss_size{$y} += $cache[1]; $udp_miss_time{$y} += $cache[2]; } elsif ( $x eq '5.1' and $#cache == 3 ) { $y = shift (@cache); $tcp_hit{$y} = $tcp_hit_size{$y} = $tcp_hit_time{$y} = 0 unless defined $tcp_hit{$y}; $tcp_hit{$y} += $cache[0]; $tcp_hit_size{$y} += $cache[1]; $tcp_hit_time{$y} += $cache[2]; } elsif ( $x eq '5.2' and $#cache == 3 ) { $y = shift (@cache); $tcp_miss{$y} = $tcp_miss_size{$y} = $tcp_miss_time{$y} = 0 unless defined $tcp_miss{$y}; $tcp_miss{$y} += $cache[0]; $tcp_miss_size{$y} += $cache[1]; $tcp_miss_time{$y} += $cache[2]; } elsif ( $x eq '5.3' and $#cache == 3 ) { $y = shift (@cache); $tcp_miss_none{$y} = $tcp_miss_none_size{$y} = $tcp_miss_none_time{$y} = 0 unless defined $tcp_miss_none{$y}; $tcp_miss_none{$y} += $cache[0]; $tcp_miss_none_size{$y} += $cache[1]; $tcp_miss_none_time{$y} += $cache[2]; } elsif ( $x eq '6.1' and $#cache == 3 ) { $y = shift (@cache); $hier_direct{$y} = $hier_direct_size{$y} = $hier_direct_time{$y} = 0 unless defined $hier_direct{$y}; $hier_direct{$y} += $cache[0]; $hier_direct_size{$y} += $cache[1]; $hier_direct_time{$y} += $cache[2]; } elsif ( $x eq '6.2' and $#cache == 3 ) { $y = shift (@cache); $hier_sibling{$y} = $hier_sibling_size{$y} = $hier_sibling_time{$y} = 0 unless defined $hier_sibling{$y}; $hier_sibling{$y} += $cache[0]; $hier_sibling_size{$y} += $cache[1]; $hier_sibling_time{$y} += $cache[2]; } elsif ( $x eq '6.3' and $#cache == 3 ) { $y = shift (@cache); $hier_parent{$y} = $hier_parent_size{$y} = $hier_parent_time{$y} = 0 unless defined $hier_parent{$y}; $hier_parent{$y} += $cache[0]; $hier_parent_size{$y} += $cache[1]; $hier_parent_time{$y} += $cache[2]; } elsif ( $x eq '7.1' and $#cache == 3 ) { $y = shift (@cache); $hier_neighbor{$y} = $hier_neighbor_size{$y} = $hier_neighbor_time{$y} = 0 unless defined $hier_neighbor{$y}; $hier_neighbor{$y} += $cache[0]; $hier_neighbor_size{$y} += $cache[1]; $hier_neighbor_time{$y} += $cache[2]; } elsif ( $x eq '7.2' and $#cache == 4 ) { $y = shift (@cache); $z = shift (@cache); $hier_neighbor_status{$y}{$z} = $hier_neighbor_status_size{$y}{$z} = $hier_neighbor_status_time{$y}{$z} = 0 unless defined $hier_neighbor_status{$y}{$z}; $hier_neighbor_status{$y}{$z} += $cache[0]; $hier_neighbor_status_size{$y}{$z} += $cache[1]; $hier_neighbor_status_time{$y}{$z} += $cache[2]; } elsif ( $x eq '8' and $#cache == 5 ) { $y = shift (@cache); $tcp_urlhost{$y} = $tcp_urlhost_size{$y} = $tcp_urlhost_time{$y} = $tcp_hit_urlhost{$y} = $tcp_hit_urlhost_size{$y} = 0 unless defined $tcp_urlhost{$y}; $show_other_tcp_urlhost = 0 if defined($tcp_urlhost{''}); $tcp_urlhost{$y} += $cache[0]; $tcp_urlhost_size{$y} += $cache[1]; $tcp_hit_urlhost{$y} += $cache[2]; $tcp_hit_urlhost_size{$y} += $cache[3]; $tcp_urlhost_time{$y} += $cache[4]; } elsif ( $x eq '9' and $#cache == 5 ) { $y = shift (@cache); $tcp_urltld{$y} = $tcp_urltld_size{$y} = $tcp_urltld_time{$y} = $tcp_hit_urltld{$y} = $tcp_hit_urltld_size{$y} = 0 unless defined $tcp_urltld{$y}; $show_other_tcp_urltld = 0 if defined($tcp_urltld{''}); $tcp_urltld{$y} += $cache[0]; $tcp_urltld_size{$y} += $cache[1]; $tcp_hit_urltld{$y} += $cache[2]; $tcp_hit_urltld_size{$y} += $cache[3]; $tcp_urltld_time{$y} += $cache[4]; } elsif ( $x eq '10' and $#cache == 5 ) { $y = shift (@cache); $tcp_urlprot{$y} = $tcp_urlprot_size{$y} = $tcp_urlprot_time{$y} = $tcp_hit_urlprot{$y} = $tcp_hit_urlprot_size{$y} = 0 unless defined $tcp_urlprot{$y}; $tcp_urlprot{$y} += $cache[0]; $tcp_urlprot_size{$y} += $cache[1]; $tcp_hit_urlprot{$y} += $cache[2]; $tcp_hit_urlprot_size{$y} += $cache[3]; $tcp_urlprot_time{$y} += $cache[4]; } elsif ( $x eq '11' and $#cache == 5 ) { $y = shift (@cache); $tcp_content{$y} = $tcp_content_size{$y} = $tcp_content_time{$y} = $tcp_hit_content{$y} = $tcp_hit_content_size{$y} = 0 unless defined $tcp_content{$y}; $show_other_tcp_content = 0 if defined($tcp_content{''}); $tcp_content{$y} += $cache[0]; $tcp_content_size{$y} += $cache[1]; $tcp_hit_content{$y} += $cache[2]; $tcp_hit_content_size{$y} += $cache[3]; $tcp_content_time{$y} += $cache[4]; } elsif ( $x eq '12' and $#cache == 10 ) { $y = shift (@cache); $tcp_urlext{$y} = $tcp_urlext_size{$y} = $tcp_urlext_time{$y} = $tcp_hit_urlext{$y} = $tcp_hit_urlext_size{$y} = 0 unless defined $tcp_urlext{$y}; $show_other_tcp_urlext = 0 if defined($tcp_urlext{''}); $tcp_urlext{$y} += $cache[0]; $tcp_urlext_size{$y} += $cache[1]; $tcp_hit_urlext{$y} += $cache[2]; $tcp_hit_urlext_size{$y} += $cache[3]; $tcp_urlext_time{$y} += $cache[4]; $tcp_urlext_fresh{$y} += $cache[5]; $tcp_urlext_stale{$y} += $cache[6]; $tcp_urlext_refresh{$y} += $cache[7]; $tcp_urlext_mod{$y} += $cache[8]; $tcp_urlext_unmod{$y} += $cache[9]; } elsif ( $x eq '13.1' and $#cache == 5 ) { $y = shift (@cache); $udp_requester{$y} = $udp_requester_size{$y} = $udp_requester_time{$y} = $udp_hit_requester{$y} = $udp_hit_requester_size{$y} = 0 unless defined $udp_requester{$y}; $show_other_udp_requester = 0 if defined($udp_requester{''}); $udp_requester{$y} += $cache[0]; $udp_requester_size{$y} += $cache[1]; $udp_requester_time{$y} += $cache[2]; $udp_hit_requester{$y} += $cache[3]; $udp_hit_requester_size{$y} += $cache[4]; } elsif ( $x eq '14.1' and $#cache == 5 ) { $y = shift (@cache); $tcp_requester{$y} = $tcp_requester_size{$y} = $tcp_requester_time{$y} = $tcp_hit_requester{$y} = $tcp_hit_requester_size{$y} = 0 unless defined $tcp_requester{$y}; $show_other_tcp_requester = 0 if defined($tcp_requester{''}); $tcp_requester{$y} += $cache[0]; $tcp_requester_size{$y} += $cache[1]; $tcp_requester_time{$y} += $cache[2]; $tcp_hit_requester{$y} += $cache[3]; $tcp_hit_requester_size{$y} += $cache[4]; } elsif ( $x eq '16' and $#cache == 15 ) { $y = shift (@cache); $perf_counter{$y} += $cache[0]; $perf_size{$y} += $cache[1]; $perf_time{$y} += $cache[2]; $perf_tcp_hit_size{$y} += $cache[3]; $perf_tcp_hit_time{$y} += $cache[4]; $perf_tcp_miss_size{$y} += $cache[5]; $perf_tcp_miss_time{$y} += $cache[6]; $perf_hier_direct_size{$y} += $cache[7]; $perf_hier_direct_time{$y} += $cache[8]; $perf_hier_sibling_size{$y} += $cache[9]; $perf_hier_sibling_time{$y} += $cache[10]; $perf_hier_parent_size{$y} += $cache[11]; $perf_hier_parent_time{$y} += $cache[12]; $perf_requester{$y} += $cache[13]; $perf_tcp_hit{$y} += $cache[14]; } elsif ( $x eq '13.2' and $#cache == 6 ) { $y = shift (@cache); $z = shift (@cache); $udp_requester_urlhost{$y}{$z} = $udp_requester_urlhost_size{$y}{$z} = $udp_requester_urlhost_time{$y}{$z} = $udp_hit_requester_urlhost{$y}{$z} = $udp_hit_requester_urlhost_size{$y}{$z} = 0 unless defined $udp_requester_urlhost{$y}{$z}; $udp_requester_urlhost{$y}{$z} += $cache[0]; $udp_requester_urlhost_size{$y}{$z} += $cache[1]; $udp_requester_urlhost_time{$y}{$z} += $cache[2]; $udp_hit_requester_urlhost{$y}{$z} += $cache[3]; $udp_hit_requester_urlhost_size{$y}{$z} += $cache[4]; } elsif ( $x eq '14.2' and $#cache == 6 ) { $y = shift (@cache); $z = shift (@cache); $tcp_requester_urlhost{$y}{$z} = $tcp_requester_urlhost_size{$y}{$z} = $tcp_requester_urlhost_time{$y}{$z} = $tcp_hit_requester_urlhost{$y}{$z} = $tcp_hit_requester_urlhost_size{$y}{$z} = 0 unless defined $tcp_requester_urlhost{$y}{$z}; $tcp_requester_urlhost{$y}{$z} += $cache[0]; $tcp_requester_urlhost_size{$y}{$z} += $cache[1]; $tcp_requester_urlhost_time{$y}{$z} += $cache[2]; $tcp_hit_requester_urlhost{$y}{$z} += $cache[3]; $tcp_hit_requester_urlhost_size{$y}{$z} += $cache[4]; } elsif ( $x eq '15' and $#cache == 5 ) { $y = shift (@cache); $tcp_distribution{$y} = $tcp_distribution_size{$y} = $tcp_distribution_time{$y} = $tcp_hit_distribution{$y} = $tcp_hit_distribution_size{$y} = 0 unless defined $tcp_distribution{$y}; $tcp_distribution{$y} += $cache[0]; $tcp_distribution_size{$y} += $cache[1]; $tcp_distribution_time{$y} += $cache[2]; $tcp_hit_distribution{$y} += $cache[3]; $tcp_hit_distribution_size{$y} += $cache[4]; # read max values } elsif ( $x eq '18' and $#cache == 1 ) { $ordered_tcp_req_time_max_interval = $cache[0]; $ordered_tcp_req_time_max = $cache[1]; } elsif ( $x eq '18' and $#cache == 5 ) { $y = shift (@cache); $ordered_tcp_req_time{$y} = $ordered_tcp_req_time_size{$y} = $ordered_tcp_hit_req_time{$y} = $ordered_tcp_hit_req_time_size{$y} = $ordered_tcp_req_time_time{$y} = 0 unless defined $ordered_tcp_req_time{$y}; $ordered_tcp_req_time{$y} += $cache[0]; $ordered_tcp_req_time_size{$y} += $cache[1]; $ordered_tcp_hit_req_time{$y} += $cache[2]; $ordered_tcp_hit_req_time_size{$y} += $cache[3]; $ordered_tcp_req_time_time{$y} += $cache[4]; # read max values } elsif ( $x eq '17' and $#cache == 1 ) { $ordered_udp_req_time_max_interval = $cache[0]; $ordered_udp_req_time_max = $cache[1]; } elsif ( $x eq '17' and $#cache == 5 ) { $y = shift (@cache); $ordered_udp_req_time{$y} = $ordered_udp_req_time_size{$y} = $ordered_udp_hit_req_time{$y} = $ordered_udp_hit_req_time_size{$y} = $ordered_udp_req_time_time{$y} = 0 unless defined $ordered_udp_req_time{$y}; $ordered_udp_req_time{$y} += $cache[0]; $ordered_udp_req_time_size{$y} += $cache[1]; $ordered_udp_hit_req_time{$y} += $cache[2]; $ordered_udp_hit_req_time_size{$y} += $cache[3]; $ordered_udp_req_time_time{$y} += $cache[4]; } elsif ( $x eq '19' and $#cache == 5 ) { $y = shift (@cache); $udp_code{$y} = $udp_code_size{$y} = 0 unless defined $udp_code{$y}; $udp_code{$y} += $cache[0]; $udp_code_size{$y} += $cache[1]; $udp_hit_code{$y} += $cache[2]; $udp_hit_code_size{$y} += $cache[3]; $udp_code_time{$y} += $cache[4]; } elsif ( $x eq '20' and $#cache == 5 ) { $y = shift (@cache); $tcp_code{$y} = $tcp_code_size{$y} = 0 unless defined $tcp_code{$y}; $tcp_code{$y} += $cache[0]; $tcp_code_size{$y} += $cache[1]; $tcp_hit_code{$y} += $cache[2]; $tcp_hit_code_size{$y} += $cache[3]; $tcp_code_time{$y} += $cache[4]; } else { print STDERR "can't parse cache-line: \"$x @cache\"\n"; $cache_warn = 1 if ( $x =~ m#^[A-Z]$# ); } } close(CACHE); } } sub htmlescape { my $toencode = shift; return undef unless defined($toencode); $toencode=~s/&/&/gso; $toencode=~s/\"/"/gso; $toencode=~s/>/>/gso; $toencode=~s/= $b) ? $a : $b; my $next = ($a >= $b) ? $b : $a; return $a, $b if !$gcd; if ($next) { foreach (1..3) { # reduces accuracy, but increases readability :-) my $r = $gcd % $next; $r += $next if $r < 0; # fix for % in integer mode $gcd = $next; $next = $r; last if ($next == 0); } } return $a/$gcd, $b/$gcd; } sub uri_unescape { # Note from RFC1630: "Sequences which start with a percent sign # but are not followed by two hexadecimal characters are reserved # for future extension" my $str = shift; if (@_ && wantarray) { # not executed for the common case of a single argument my @str = ($str, @_); # need to copy foreach (@str) { s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg } return @str; } $str =~ s/%([0-9A-Fa-f]{2})/chr(hex($1))/eg; $str; }