3 # Copyright (c) 2002-2003
\r
4 # The President and Fellows of Harvard College.
\r
6 # Redistribution and use in source and binary forms, with or without
\r
7 # modification, are permitted provided that the following conditions
\r
9 # 1. Redistributions of source code must retain the above copyright
\r
10 # notice, this list of conditions and the following disclaimer.
\r
11 # 2. Redistributions in binary form must reproduce the above copyright
\r
12 # notice, this list of conditions and the following disclaimer in the
\r
13 # documentation and/or other materials provided with the distribution.
\r
14 # 3. Neither the name of the University nor the names of its contributors
\r
15 # may be used to endorse or promote products derived from this software
\r
16 # without specific prior written permission.
\r
18 # THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
\r
19 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
\r
20 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
\r
21 # ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
\r
22 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
\r
23 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
\r
24 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
\r
25 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
\r
26 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
\r
27 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
\r
30 # $Id: ns_timeagg,v 1.7 2003/07/28 14:27:17 ellard Exp $
\r
35 $ProgDir =~ /(^.*)\//;
\r
41 require "$ProgDir/common.pl";
\r
47 $NEW_INTERVAL = 300;
\r
52 Usage: $0 [options] [table1.ns [table2.ns ... ]]
\r
54 If no table files are specified, then the input is read from stdin.
\r
56 Command line options:
\r
58 -h Print usage message and exit.
\r
60 -B flags Choose fields to NOT aggregate. The fields are:
\r
62 U - Effective user ID
\r
63 G - Effective group ID
\r
66 -R secs Round the start time to the closest multiple of
\r
67 the given number of seconds. This is useful for
\r
68 dealing with small amounts of clock drift. For example,
\r
69 if the trace starts at 12:00:01 instead of 12:00:00,
\r
70 it is probably convenient to pretend that it started
\r
73 -t secs Aggregate over the given number of seconds. The default
\r
74 is $NEW_INTERVAL. If the current interval does not
\r
75 divide the new interval, warning messages are printed
\r
76 and the output might not be meaningful.
\r
78 If secs is 0, then the total for the entire table is
\r
81 -Z Omit count lines that have a zero total operation count.
\r
84 $cmdline = "$0 " . join (' ', @ARGV);
\r
85 $Options = "B:hR:t:Z";
\r
86 if (! getopts ($Options)) {
\r
87 print STDERR "$0: Incorrect usage.\n";
\r
88 print STDERR $Usage;
\r
91 if (defined $opt_h) {
\r
96 if (defined $opt_t) {
\r
100 $NEW_INTERVAL = $opt_t;
\r
103 $TIME_ROUNDING = defined $opt_R ? $opt_R : 0;
\r
105 if (defined $opt_B) {
\r
106 $UseClient = ($opt_B =~ /C/);
\r
107 $UseUID = ($opt_B =~ /U/);
\r
108 $UseGID = ($opt_B =~ /G/);
\r
109 $UseFH = ($opt_B =~ /F/);
\r
112 # We need to let the measurement of time be a little bit inexact, so
\r
113 # that a small rounding error or truncation doesn't throw everything
\r
116 $TimerInacc = 0.05;
\r
118 # Print out the commandline as a comment in the output.
\r
120 print "#cmdline $cmdline\n";
\r
122 # It would be nice to make this do the right thing with Latency lines,
\r
123 # and perhaps file op counts.
\r
131 next if ($l =~ /^#/);
\r
133 my ($type, $time, $client, $fh, $euid, $egid, @vals) = split (' ', $l);
\r
135 next unless ($type eq 'C');
\r
137 # Something wrong with the input?
\r
139 next if (@vals == 0);
\r
141 if (!defined $StartTime) {
\r
142 $StartTime = findStartTime ($time, $TIME_ROUNDING);
\r
143 if ($NEW_INTERVAL > 0) {
\r
144 $EndTime = $StartTime + $NEW_INTERVAL - $TimerInacc;
\r
148 if ($EndTime > 0 && $time >= $EndTime) {
\r
149 my $diff = int ($time - $StartTime);
\r
151 if ($NEW_INTERVAL % $diff != 0) {
\r
152 print STDERR "$0: time interval mismatch ";
\r
153 print STDERR "(from $diff to $NEW_INTERVAL)\n";
\r
157 dumpKeys ($StartTime);
\r
159 $StartTime += $NEW_INTERVAL;
\r
160 $EndTime = $StartTime + $NEW_INTERVAL - $TimerInacc;
\r
164 # Aggregate across clients, files, users, and groups unless
\r
165 # specifically asked NOT to.
\r
167 $client = $UseClient ? $client : 'u';
\r
168 $fh = $UseFH ? $fh : 'u';
\r
169 $euid = $UseUID ? $euid : 'u';
\r
170 $egid = $UseGID ? $egid : 'u';
\r
172 $key = "$client,$fh,$euid,$egid";
\r
174 if (exists $Totals{$key}) {
\r
175 my (@tots) = split (' ', $Totals{$key});
\r
176 for (my $i = 0; $i < @vals; $i++) {
\r
177 $tots[$i] += $vals[$i];
\r
179 $Totals{$key} = join (' ', @tots);
\r
182 $Totals{$key} = join (' ', @vals);
\r
186 if ($EndTime <= 0) {
\r
187 dumpKeys ($StartTime);
\r
194 foreach $k ( keys %Totals ) {
\r
195 my (@v) = split (' ', $Totals{$k});
\r
197 if ($OMIT_ZEROS && $v[0] == 0) {
\r
204 print "C $start $ks";
\r
206 for ($i = 0; $i < @v; $i++) {
\r
211 for ($i = 0; $i < @v; $i++) {
\r
214 $Totals{$k} = join (' ', @v);
\r