Changed sig_int() to use a standard signal-handler prototype.
[rsync/rsync.git] / support / rsyncstats
CommitLineData
c78779cc 1#!/usr/bin/perl
2c51d5de
AT
2#
3# This script parses the default logfile format produced by rsync when running
aa57d14a
WD
4# as a daemon with transfer logging enabled. It also parses a slightly tweaked
5# version of the default format where %o has been replaced with %i.
6#
7# This script is derived from the xferstats script that comes with wuftpd. See
8# the usage message at the bottom for the options it takes.
2c51d5de
AT
9#
10# Andrew Tridgell, October 1998
2c51d5de 11
c78779cc
WD
12use Getopt::Long;
13
14# You may wish to edit the next line to customize for your default log file.
2c51d5de
AT
15$usage_file = "/var/adm/rsyncd.log";
16
17# Edit the following lines for default report settings.
18# Entries defined here will be over-ridden by the command line.
19
c78779cc
WD
20$hourly_report = 0;
21$domain_report = 0;
22$total_report = 0;
23$depth_limit = 9999;
24$only_section = '';
25
26&Getopt::Long::Configure('bundling');
27&usage if !&GetOptions(
28 'hourly-report|h' => \$hourly_report,
29 'domain-report|d' => \$domain_report,
30 'domain|D:s' => \$only_domain,
31 'total-report|t' => \$total_report,
32 'depth-limit|l:i' => \$depth_limit,
33 'real|r' => \$real,
34 'anon|a' => \$anon,
35 'section|s:s' => \$only_section,
36 'file|f:s' => \$usage_file,
37);
38
39$anon = 1 if !$real && !$anon;
40
41open(LOG, $usage_file) || die "Error opening usage log file: $usage_file\n";
42
43if ($only_domain) {
44 print "Transfer Totals include the '$only_domain' domain only.\n";
45 print "All other domains are filtered out for this report.\n\n";
46}
2c51d5de 47
c78779cc
WD
48if ($only_section) {
49 print "Transfer Totals include the '$only_section' section only.\n";
50 print "All other sections are filtered out for this report.\n\n";
51}
2c51d5de
AT
52
53line: while (<LOG>) {
54
aa57d14a
WD
55 next unless ($day,$time,$op,$host,$module,$file,$bytes)
56 = m#^ (\d+/\d\d/\d\d)\s+(\d\d:\d\d:\d\d)\s+\[\d+\]\s+(send|recv|[<>]f\S+)\s+
57 (\S+)\s+\[\d+\.\d+\.\d+\.\d+\]\s+(\S+)\s+\(\S*\)\s+(.*)\s+(\d+) $ #x;
2c51d5de 58
aa57d14a
WD
59 # TODO actually divide the data by into send/recv categories
60 if ($op =~ /^>/) {
61 $op = 'send';
62 } elsif ($op =~ /^</) {
63 $op = 'recv';
64 }
2c51d5de
AT
65
66 $daytime = $day;
67 $hour = substr($time,0,2);
68
69 $file = $module . "/" . $file;
70
263cf2ed
AT
71 $file =~ s|//|/|mg;
72
2c51d5de
AT
73 @path = split(/\//, $file);
74
75 $pathkey = "";
c78779cc 76 for ($i=0; $i <= $#path && $i <= $depth_limit; $i++) {
2c51d5de
AT
77 $pathkey = $pathkey . "/" . $path[$i];
78 }
79
c78779cc
WD
80 if ($only_section ne '') {
81 next unless (substr($pathkey,0,length($only_section)) eq $only_section);
82 }
2c51d5de
AT
83
84 $host =~ tr/A-Z/a-z/;
85
86 @address = split(/\./, $host);
87
88 $domain = $address[$#address];
89 if ( int($address[0]) > 0 || $#address < 2 )
90 { $domain = "unresolved"; }
91
c78779cc
WD
92 if ($only_domain ne '') {
93 next unless (substr($domain,0,length($only_domain)) eq $only_domain);
2c51d5de
AT
94 }
95
96
c78779cc 97# printf("c=%d day=%s bytes=%d file=%s path=%s\n",
2c51d5de
AT
98# $#line, $daytime, $bytes, $file, $pathkey);
99
100 $xferfiles++; # total files sent
101 $xfertfiles++; # total files sent
102 $xferfiles{$daytime}++; # files per day
103 $groupfiles{$pathkey}++; # per-group accesses
104 $domainfiles{$domain}++;
105
106 $xferbytes{$daytime} += $bytes; # bytes per day
107 $domainbytes{$domain} += $bytes; # xmit bytes to domain
108 $xferbytes += $bytes; # total bytes sent
109 $groupbytes{$pathkey} += $bytes; # per-group bytes sent
110
111 $xfertfiles{$hour}++; # files per hour
112 $xfertbytes{$hour} += $bytes; # bytes per hour
113 $xfertbytes += $bytes; # total bytes sent
114}
115close LOG;
116
c78779cc
WD
117#@syslist = keys %systemfiles;
118@dates = sort datecompare keys %xferbytes;
2c51d5de
AT
119
120if ($xferfiles == 0) {die "There was no data to process.\n";}
121
122
123print "TOTALS FOR SUMMARY PERIOD ", $dates[0], " TO ", $dates[$#dates], "\n\n";
c78779cc
WD
124printf("Files Transmitted During Summary Period %12.0f\n", $xferfiles);
125printf("Bytes Transmitted During Summary Period %12.0f\n", $xferbytes);
126#printf("Systems Using Archives %12.0f\n\n", $#syslist+1);
2c51d5de 127
c78779cc 128printf("Average Files Transmitted Daily %12.0f\n",
2c51d5de 129 $xferfiles / ($#dates + 1));
c78779cc 130printf("Average Bytes Transmitted Daily %12.0f\n",
2c51d5de
AT
131 $xferbytes / ($#dates + 1));
132
133format top1 =
134
135Daily Transmission Statistics
136
137 Number Of Number of Percent Of Percent Of
138 Date Files Sent MB Sent Files Sent Bytes Sent
139--------------- ---------- ----------- ---------- ----------
140.
141
142format line1 =
143@<<<<<<<<<<<<<< @>>>>>>>>> @>>>>>>>>>> @>>>>>>> @>>>>>>>
144$date, $nfiles, $nbytes/(1024*1024), $pctfiles, $pctbytes
145.
146
147$^ = top1;
148$~ = line1;
149
c78779cc 150foreach $date (sort datecompare keys %xferbytes) {
2c51d5de
AT
151
152 $nfiles = $xferfiles{$date};
153 $nbytes = $xferbytes{$date};
154 $pctfiles = sprintf("%8.2f", 100*$xferfiles{$date} / $xferfiles);
155 $pctbytes = sprintf("%8.2f", 100*$xferbytes{$date} / $xferbytes);
156 write;
157}
158
c78779cc 159if ($total_report) {
2c51d5de
AT
160format top2 =
161
162Total Transfers from each Archive Section (By bytes)
163
164 - Percent -
165 Archive Section NFiles MB Files Bytes
166------------------------------------- ------- ----------- ----- -------
167.
168
169format line2 =
170@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>> @>>>>>>>>>> @>>>> @>>>>
171$section, $files, $bytes/(1024*1024), $pctfiles, $pctbytes
172.
173
174$| = 1;
175$- = 0;
176$^ = top2;
177$~ = line2;
178
c78779cc 179foreach $section (sort bytecompare keys %groupfiles) {
2c51d5de
AT
180
181 $files = $groupfiles{$section};
182 $bytes = $groupbytes{$section};
183 $pctbytes = sprintf("%8.2f", 100 * $groupbytes{$section} / $xferbytes);
184 $pctfiles = sprintf("%8.2f", 100 * $groupfiles{$section} / $xferfiles);
185 write;
186
187}
188
189if ( $xferfiles < 1 ) { $xferfiles = 1; }
190if ( $xferbytes < 1 ) { $xferbytes = 1; }
191}
192
c78779cc 193if ($domain_report) {
2c51d5de
AT
194format top3 =
195
196Total Transfer Amount By Domain
197
198 Number Of Number of Percent Of Percent Of
199Domain Name Files Sent MB Sent Files Sent Bytes Sent
200----------- ---------- ------------ ---------- ----------
201.
202
203format line3 =
204@<<<<<<<<<< @>>>>>>>>> @>>>>>>>>>>> @>>>>>>> @>>>>>>>
205$domain, $files, $bytes/(1024*1024), $pctfiles, $pctbytes
206.
207
208$- = 0;
209$^ = top3;
210$~ = line3;
211
c78779cc 212foreach $domain (sort domnamcompare keys %domainfiles) {
2c51d5de
AT
213
214 if ( $domainsecs{$domain} < 1 ) { $domainsecs{$domain} = 1; }
215
216 $files = $domainfiles{$domain};
217 $bytes = $domainbytes{$domain};
218 $pctfiles = sprintf("%8.2f", 100 * $domainfiles{$domain} / $xferfiles);
219 $pctbytes = sprintf("%8.2f", 100 * $domainbytes{$domain} / $xferbytes);
220 write;
221
222}
223
224}
225
c78779cc 226if ($hourly_report) {
2c51d5de
AT
227
228format top8 =
229
230Hourly Transmission Statistics
231
232 Number Of Number of Percent Of Percent Of
233 Time Files Sent MB Sent Files Sent Bytes Sent
234--------------- ---------- ----------- ---------- ----------
235.
236
237format line8 =
238@<<<<<<<<<<<<<< @>>>>>>>>> @>>>>>>>>>> @>>>>>>> @>>>>>>>
239$hour, $nfiles, $nbytes/(1024*1024), $pctfiles, $pctbytes
240.
241
242
243$| = 1;
244$- = 0;
245$^ = top8;
246$~ = line8;
247
c78779cc 248foreach $hour (sort keys %xfertbytes) {
2c51d5de
AT
249
250 $nfiles = $xfertfiles{$hour};
251 $nbytes = $xfertbytes{$hour};
252 $pctfiles = sprintf("%8.2f", 100*$xfertfiles{$hour} / $xferfiles);
253 $pctbytes = sprintf("%8.2f", 100*$xfertbytes{$hour} / $xferbytes);
254 write;
255}
256}
257exit(0);
258
259sub datecompare {
c7c05641 260 $a gt $b;
2c51d5de
AT
261}
262
263sub domnamcompare {
264
265 $sdiff = length($a) - length($b);
266 ($sdiff < 0) ? -1 : ($sdiff > 0) ? 1 : ($a lt $b) ? -1 : ($a gt $b) ? 1 : 0;
267
268}
269
270sub bytecompare {
271
272 $bdiff = $groupbytes{$b} - $groupbytes{$a};
273 ($bdiff < 0) ? -1 : ($bdiff > 0) ? 1 : ($a lt $b) ? -1 : ($a gt $b) ? 1 : 0;
274
275}
276
277sub faccompare {
278
279 $fdiff = $fac{$b} - $fac{$a};
280 ($fdiff < 0) ? -1 : ($fdiff > 0) ? 1 : ($a lt $b) ? -1 : ($a gt $b) ? 1 : 0;
281
282}
283
c78779cc
WD
284sub usage
285{
286 die <<EOT;
287USAGE: rsyncstats [options]
288
289OPTIONS:
290 -f FILENAME Use FILENAME for the log file.
291 -h Include report on hourly traffic.
292 -d Include report on domain traffic.
293 -t Report on total traffic by section.
294 -D DOMAIN Report only on traffic from DOMAIN.
295 -l DEPTH Set DEPTH of path detail for sections.
296 -s SECTION Set SECTION to report on. For example, "-s /pub"
297 will report only on paths under "/pub".
298EOT
299}