Commit | Line | Data |
---|---|---|
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 |
12 | use 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 | ||
41 | open(LOG, $usage_file) || die "Error opening usage log file: $usage_file\n"; | |
42 | ||
43 | if ($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 |
48 | if ($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 | |
53 | line: 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 | } | |
115 | close LOG; | |
116 | ||
c78779cc WD |
117 | #@syslist = keys %systemfiles; |
118 | @dates = sort datecompare keys %xferbytes; | |
2c51d5de AT |
119 | |
120 | if ($xferfiles == 0) {die "There was no data to process.\n";} | |
121 | ||
122 | ||
123 | print "TOTALS FOR SUMMARY PERIOD ", $dates[0], " TO ", $dates[$#dates], "\n\n"; | |
c78779cc WD |
124 | printf("Files Transmitted During Summary Period %12.0f\n", $xferfiles); |
125 | printf("Bytes Transmitted During Summary Period %12.0f\n", $xferbytes); | |
126 | #printf("Systems Using Archives %12.0f\n\n", $#syslist+1); | |
2c51d5de | 127 | |
c78779cc | 128 | printf("Average Files Transmitted Daily %12.0f\n", |
2c51d5de | 129 | $xferfiles / ($#dates + 1)); |
c78779cc | 130 | printf("Average Bytes Transmitted Daily %12.0f\n", |
2c51d5de AT |
131 | $xferbytes / ($#dates + 1)); |
132 | ||
133 | format top1 = | |
134 | ||
135 | Daily 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 | ||
142 | format line1 = | |
143 | @<<<<<<<<<<<<<< @>>>>>>>>> @>>>>>>>>>> @>>>>>>> @>>>>>>> | |
144 | $date, $nfiles, $nbytes/(1024*1024), $pctfiles, $pctbytes | |
145 | . | |
146 | ||
147 | $^ = top1; | |
148 | $~ = line1; | |
149 | ||
c78779cc | 150 | foreach $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 | 159 | if ($total_report) { |
2c51d5de AT |
160 | format top2 = |
161 | ||
162 | Total Transfers from each Archive Section (By bytes) | |
163 | ||
164 | - Percent - | |
165 | Archive Section NFiles MB Files Bytes | |
166 | ------------------------------------- ------- ----------- ----- ------- | |
167 | . | |
168 | ||
169 | format line2 = | |
170 | @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>> @>>>>>>>>>> @>>>> @>>>> | |
171 | $section, $files, $bytes/(1024*1024), $pctfiles, $pctbytes | |
172 | . | |
173 | ||
174 | $| = 1; | |
175 | $- = 0; | |
176 | $^ = top2; | |
177 | $~ = line2; | |
178 | ||
c78779cc | 179 | foreach $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 | ||
189 | if ( $xferfiles < 1 ) { $xferfiles = 1; } | |
190 | if ( $xferbytes < 1 ) { $xferbytes = 1; } | |
191 | } | |
192 | ||
c78779cc | 193 | if ($domain_report) { |
2c51d5de AT |
194 | format top3 = |
195 | ||
196 | Total Transfer Amount By Domain | |
197 | ||
198 | Number Of Number of Percent Of Percent Of | |
199 | Domain Name Files Sent MB Sent Files Sent Bytes Sent | |
200 | ----------- ---------- ------------ ---------- ---------- | |
201 | . | |
202 | ||
203 | format line3 = | |
204 | @<<<<<<<<<< @>>>>>>>>> @>>>>>>>>>>> @>>>>>>> @>>>>>>> | |
205 | $domain, $files, $bytes/(1024*1024), $pctfiles, $pctbytes | |
206 | . | |
207 | ||
208 | $- = 0; | |
209 | $^ = top3; | |
210 | $~ = line3; | |
211 | ||
c78779cc | 212 | foreach $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 | 226 | if ($hourly_report) { |
2c51d5de AT |
227 | |
228 | format top8 = | |
229 | ||
230 | Hourly 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 | ||
237 | format line8 = | |
238 | @<<<<<<<<<<<<<< @>>>>>>>>> @>>>>>>>>>> @>>>>>>> @>>>>>>> | |
239 | $hour, $nfiles, $nbytes/(1024*1024), $pctfiles, $pctbytes | |
240 | . | |
241 | ||
242 | ||
243 | $| = 1; | |
244 | $- = 0; | |
245 | $^ = top8; | |
246 | $~ = line8; | |
247 | ||
c78779cc | 248 | foreach $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 | } | |
257 | exit(0); | |
258 | ||
259 | sub datecompare { | |
c7c05641 | 260 | $a gt $b; |
2c51d5de AT |
261 | } |
262 | ||
263 | sub 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 | ||
270 | sub 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 | ||
277 | sub 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 |
284 | sub usage |
285 | { | |
286 | die <<EOT; | |
287 | USAGE: rsyncstats [options] | |
288 | ||
289 | OPTIONS: | |
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". | |
298 | EOT | |
299 | } |