2 #***************************************************************************
4 # Generate some stats from cups page_log file
5 # copyright : (C) 1999 - 2003 by Thies Moeller
6 # email : moeller@tu-harburg.de
7 #***************************************************************************
9 #***************************************************************************
11 #* This program is free software; you can redistribute it and/or modify *
12 #* it under the terms of the GNU General Public License as published by *
13 #* the Free Software Foundation; either version 2 of the License, or *
14 #* (at your option) any later version. *
16 #***************************************************************************
19 use POSIX qw(strftime);
26 # edit place of your page_log file or give it as option "-f filename"
33 if (exists $opt{"f"}) { $PAGE_LOG_FILE = $opt{f};}
34 else {$PAGE_LOG_FILE = "/var/log/cups/page_log";}
37 # edit start and end of normal work time
38 # activity outside this interval will be marked with an "!"
39 # to disable set WorkStart to 0 and WorkEnd to 24
45 ############################ nothing to modify below this line ##############
47 my %userRequests = ();
49 my %hourRequests = ();
50 my %dateRequests = ();
52 my %pageRequests = ();
53 my %queueRequests = ();
56 my %copyRequests = ();
59 my %billingStats = ();
60 my %queueUserStats = ();
66 my $date1 = substr($a, 6, 2) * 1024; # Years
67 my $date2 = substr($b, 6, 2) * 1024;
69 $date1 += substr($a,3,2) * 64; # Months
70 $date2 += substr($b,3,2) * 64;
72 $date1 += substr($a, 0, 2); # Days
73 $date2 += substr($b, 0, 2);
74 return ($date1 <=> $date2);
80 ## this method is copied from LogReport Time.pm
81 ## Copyright (C) 2000-2002 Stichting LogReport Foundation LogReport@LogReport.org
83 die "tzdiff2sec needs 1 arg\n"
86 # e.g. +0100 or -0900 ; +hh:mm, +hhmm, or +hh
87 my ( $sign, $hour, $min ) = $_[0] =~ /^([+-])?(\d\d):?(\d\d)?$/
88 or die "invalid tzdiff format: $_[0]. It must looks like +0100 or -01:00\n";
92 my $sec = $hour * 60 * 60 + $min * 60;
93 $sec *= -1 if $sign eq '-';
99 my $AllMonths= 'JanFebMarAprMayJunJulAugSepOctNovDec';
100 my $month = shift(@_);
101 return index($AllMonths, $month)/3;
108 my ($day,$month,$year,$hour,$min,$sec,$tz)=
109 unpack'@1 A2 @4 A3 @8 A4 @13 A2 @16 A2 @19 A2 @22 A5', shift();
111 my $epoch=timegm $sec ,
117 return $epoch - tzdiff2sec($tz);
124 ############# Output Form ################
129 -----------------------------------------
133 @<<<<<<<<<<<<< @>>>>>>> @>>>>>>>
134 $dateReq,$dateRequests{$dateReq},$datePages{$dateReq}
136 ############# Output Form ################
142 foreach $dateReq (sort DateCompare keys %dateRequests)
144 #printf("Monat %d\n",getMonth($dateReq));
154 ############# Output Form ################
157 Username Requests Pages Pages/Request
158 --------------------------------------------------------
162 @<<<<<<<<<<<<<<<<<< @>>>>>>> @>>>>>>> @>>>>>>>>
163 $userReq, $userRequests{$userReq}, $userPages{$userReq}, $pageperjob
165 ############# Output Form ################
170 foreach $userReq (sort { $userPages{$b} <=> $userPages{$a}} keys %userRequests)
172 $pageperjob = sprintf("%5d", POSIX::ceil($userPages{$userReq} / $userRequests{$userReq}));
180 my $outOfWorkingTime;
182 ############# Output Form ################
186 ---------------------
191 $outOfWorkingTime,$hourReq,$hourRequests{$hourReq}
193 ############# Output Form ################
200 foreach $hourReq (sort {$a <=> $b} keys %hourRequests)
202 if($hourReq <$WorkStart || $hourReq > $WorkEnd)
204 if($hourRequests{$hourReq} == 0)
210 $outOfWorkingTime = "!";
215 $outOfWorkingTime = " ";
228 ############# Output Form ################
230 format REQUESTLOG_TOP =
233 ---------------------------
237 @||||||||||| @>>>>>>>>
238 $pageHeuK,$pageperHeu
240 ############# Output Form ################
243 foreach $pageReq (sort {$a <=> $b} keys %pageRequests)
245 if($pageReq >0 && $pageReq <=10)
246 {$pageHeu{"1. 0-10"}+=$pageRequests{$pageReq}};
247 if ($pageReq >10 && $pageReq <=20)
248 {$pageHeu{ "2. 20-30"}+=$pageRequests{$pageReq}};
249 if ($pageReq >20 && $pageReq <=30)
250 {$pageHeu{ "3. 30-40"}+=$pageRequests{$pageReq}};
251 if ($pageReq >40 && $pageReq <=50)
252 {$pageHeu{ "4. 40-50"}+=$pageRequests{$pageReq}};
253 if ($pageReq >50 && $pageReq <=100)
254 {$pageHeu{ "5. 50-100"}+=$pageRequests{$pageReq}};
255 if ($pageReq >100 && $pageReq <=200)
256 {$pageHeu{ "6. 100-200"}+=$pageRequests{$pageReq}};
258 {$pageHeu{ "7. 200- "}+=$pageRequests{$pageReq}};
264 foreach $pageHeuK (sort keys %pageHeu)
266 $pageperHeu = sprintf("%5.2f", 100*$pageHeu{$pageHeuK}/$totalReq);
277 ############# Output Form ################
281 ---------------------------
284 @||||||||||||| @>>>>>>>>
285 $copyHeuK,$copyperheu
287 ############# Output Form ################
290 foreach $copyReq (sort {$a <=> $b} keys %copyRequests)
293 {$copyHeu{" 1. single"}+=$copyRequests{$copyReq}};
295 {$copyHeu{" 2. 2 "}+=$copyRequests{$copyReq}};
297 {$copyHeu{" 3. 3 "}+=$copyRequests{$copyReq}};
299 {$copyHeu{" 4. 4 "}+=$copyRequests{$copyReq}};
300 if($copyReq >=5 && $copyReq <=10)
301 {$copyHeu{" 5. 5-10 "}+=$copyRequests{$copyReq}};
302 if ($copyReq >10 && $copyReq <=20)
303 {$copyHeu{ " 6. 20-30 "}+=$copyRequests{$copyReq}};
304 if ($copyReq >20 && $copyReq <=30)
305 {$copyHeu{ " 7. 30-40 "}+=$copyRequests{$copyReq}};
306 if ($copyReq >40 && $copyReq <=50)
307 {$copyHeu{ " 8. 40-50 "}+=$copyRequests{$copyReq}};
308 if ($copyReq >50 && $copyReq <=100)
309 {$copyHeu{ " 9. 50-100 "}+=$copyRequests{$copyReq}};
310 if ($copyReq >100 && $copyReq <=200)
311 {$copyHeu{ "10. 100-200 "}+=$copyRequests{$copyReq}};
313 {$copyHeu{ "11. 200- "}+=$copyRequests{$copyReq}};
318 foreach $copyHeuK (sort keys %copyHeu)
320 $copyperheu = sprintf("%5.2f", 100*$copyHeu{$copyHeuK}/$totalReq);
331 ############# Output Form ################
332 format QUEUELOG_TOP =
334 Queue %Requests %Pages Pages
335 --------------------------------------------------------------
339 @>>>>>>>>>>>>>>>>>>>>> @>>>>>>> @>>>>>>> @>>>>>>>>
340 $queueReq,$reqperqueue,$pageperqueue,$queuePages{$queueReq}
342 ############# Output Form ################
348 foreach $queueReq (sort { $queuePages{$b} <=> $queuePages{$a} } keys %queuePages)
350 $reqperqueue = sprintf("%5.2f", 100*$queueRequests{$queueReq}/$totalReq);
351 $pageperqueue = sprintf("%5.2f", 100*$queuePages{$queueReq}/$totalPages);
363 ############# Output Form ################
364 format BILLINGLOG_TOP =
367 --------------------------------------------------------------
371 @<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>
372 $billing,$pageperbilling
375 format BILLINGUSERLOG =
376 |- @>>>>>>>>>>>>>>>>>>>>> @>>>>>>>>
377 $billinguser,$pageperbilling
379 ############# Output Form ################
385 foreach $billing (sort keys %billingStats)
387 $pageperbilling = $billingStats{$billing}{"total_pages"};
391 foreach $billinguser ( sort {$billingStats{$billing}{"user"}{$b} <=> $billingStats{$billing}{"user"}{$a}} keys %{$billingStats{$billing}{"user"}})
393 $pageperbilling = $billingStats{$billing}{"user"}{$billinguser};
400 sub PrintQueueUserLog
406 ############# Output Form ################
407 format QUEUEUSER_TOP =
410 --------------------------------------------------------------
414 @<<<<<<<<<<<<<<<<<<<<<<<<
418 format QUEUEUSERLOG =
419 |- @>>>>>>>>>>>>>>>>>>>>> @>>>>>>>>
420 $queueuser,$pageperqueue
422 ############# Output Form ################
428 foreach $queue (sort keys %queueUserStats)
433 foreach $queueuser ( sort {$queueUserStats{$queue}{$b} <=> $queueUserStats{$queue}{$a}} keys %{$queueUserStats{$queue}})
435 $pageperqueue = $queueUserStats{$queue}{$queueuser};
444 my $realpages = $lastlogline{num_pages}*$lastlogline{copies};
445 my $hourstring = POSIX::strftime "%H", localtime($lastlogline{time}) ;
446 my $daystring = POSIX::strftime "%d/%m/%y", localtime($lastlogline{time}) ;
448 $userRequests{$lastlogline{user}}++;
449 $userPages{$lastlogline{user}}+=$realpages;
450 $dateRequests{$daystring}++;
451 $datePages{$daystring}+=$realpages;
452 $pageRequests{$realpages}++;
453 $queueRequests{$lastlogline{printer}}++;
454 $queuePages{$lastlogline{printer}}+=$realpages;
455 $hourRequests{$hourstring}++;
456 $copyRequests{$lastlogline{copies}}++;
457 $billingStats{$lastlogline{billing}}{"user"}{$lastlogline{user}} += $realpages;
458 $billingStats{$lastlogline{billing}}{"printer"}{$lastlogline{printer}} += $realpages;
459 $billingStats{$lastlogline{billing}}{"total_pages"} += $realpages;
460 $queueUserStats{$lastlogline{printer}}{$lastlogline{user}} += $realpages;
463 $totalPages+=$realpages;
466 sub InitHourHistogram
469 for ($i = 0 ; $i <=24 ; $i++)
471 my $hourstring = sprintf("%02d", $i);
472 $hourRequests{$hourstring}=0;
477 open(PAGELOG,"$PAGE_LOG_FILE") || die "Can't open pagelog file $PAGE_LOG_FILE";
480 #initialize the hourhistogram
496 ($_ =~ /^(.*)\s(.*)\s(\d+)\s(\[.*\])\s(\d+)\s(\d+)\s(.*)$/)
498 if(! exists $opt{"q"}) {print STDERR "Cannot convert $_ \n";}
501 # downcase username because of samba
502 $logline{user}=~ tr/A-Z/a-z/;
504 if ($logline{user} eq "") {
505 $logline{user}="TestPages";
507 # handle empty billing code
508 if ($logline{billing} eq "") {
509 $logline{billing}="-none-";
511 my $endtime = DateTime2Epoch( $time );
513 if ( ! defined $lastlogline{jobid} || $lastlogline{jobid} ne $logline{jobid} )
516 $logline{num_pages} = 1;
517 $logline{time} = $endtime;
518 if ( defined $lastlogline{jobid} ) {
522 # same job; update info
523 $logline{num_pages} = $lastlogline{num_pages} + 1;
524 $logline{time} = $lastlogline{time};
526 %lastlogline= %logline;
532 if ( defined $lastlogline{jobid} ) {
551 PrintAnalyzer - create statistics from CUPS page_log file
555 PrintAnalyzer [-f filename][-q]
559 This Tool generates statistics from the CUPS page_log file.
567 =item Pages per user per queue (Accounting)
569 =item Jobsize histogram (all queues in one)
571 =item Number of copies histogram (all queues in one)
573 =item Jobs/Pages per hour (all queues in one)
575 =item Jobs/Pages per day (all queues in one)
577 =item Jobs/Pages per user (all queues in one)
579 =item Pages per Billingcode (all queues in one)
581 =item Pages per User per Billingcode (all queues in one)
585 =head1 OPTIONS AND ARGUMENTS
591 Location of the page_log file