cups/PrintAnalyzer

500 lines
13 KiB
Perl

#!/usr/bin/perl -w
#***************************************************************************
# PrintAnalyzer
# Generate some stats from cups page_log file
# copyright : (C) 1999 - 2002 by Thies Moeller
# email : moeller@tu-harburg.de
#***************************************************************************
#***************************************************************************
#* *
#* 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. *
#* *
#***************************************************************************
use strict;
use warnings;
use POSIX qw(strftime);
use Time::Local;
##############
# edit place of your page_log file
##############
my $PAGE_LOG_FILE = "/var/log/cups/page_log";
##############
# edit start and end of normal work time
# activity outside this interval will be marked with an "!"
# to disable set WorkStart to 0 and WorkEnd to 23
##############
my $WorkStart = 8;
my $WorkEnd = 21;
############################ nothing to modify below this line ##############
my %userRequests = ();
my %userPages = ();
my %hourRequests = ();
my %dateRequests = ();
my %datePages = ();
my %pageRequests = ();
my %queueRequests = ();
my %queuePages = ();
my %pageHeu = ();
my %copyRequests = ();
my %logline = ();
my %lastlogline = ();
my %billingStats = ();
my $totalReq = 0;
my $totalPages = 0;
sub DateCompare
{
my $date1 = substr($a, 6, 2) * 1024; # Years
my $date2 = substr($b, 6, 2) * 1024;
$date1 += substr($a,3,2) * 64; # Months
$date2 += substr($b,3,2) * 64;
$date1 += substr($a, 0, 2); # Days
$date2 += substr($b, 0, 2);
return ($date1 <=> $date2);
}
sub tzdiff2sec
{
## this method is copied from LogReport Time.pm
## Copyright (C) 2000-2002 Stichting LogReport Foundation LogReport@LogReport.org
die "tzdiff2sec needs 1 arg\n"
unless @_ == 1;
# e.g. +0100 or -0900 ; +hh:mm, +hhmm, or +hh
my ( $sign, $hour, $min ) = $_[0] =~ /^([+-])?(\d\d):?(\d\d)?$/
or die "invalid tzdiff format: $_[0]. It must looks like +0100 or -01:00\n";
$sign ||= "+";
$hour ||= 0;
$min ||= 0;
my $sec = $hour * 60 * 60 + $min * 60;
$sec *= -1 if $sign eq '-';
return $sec;
}
sub getMonth
{
my $AllMonths= 'JanFebMarAprMayJunJulAugSepOctNovDec';
my $month = shift(@_);
return index($AllMonths, $month)/3;
}
sub DateTime2Epoch
{
my ($day,$month,$year,$hour,$min,$sec,$tz)=
unpack'@1 A2 @4 A3 @8 A4 @13 A2 @16 A2 @19 A2 @22 A5', shift();
my $epoch=timegm $sec ,
$min ,
$hour,
$day,
getMonth($month),
$year;
return $epoch - tzdiff2sec($tz);
}
sub PrintDayLog
{
my $dateReq;
############# Output Form ################
format DAYLOG_TOP =
Daily Usage
Date %Requests Pages
-----------------------------------------
.
format DAYLOG =
@<<<<<<<<<<<<< @>>>>>>> @>>>>>>>
$dateReq,$dateRequests{$dateReq},$datePages{$dateReq}
.
############# Output Form ################
$-=0;
$~="DAYLOG";
$^="DAYLOG_TOP";
foreach $dateReq (sort DateCompare keys %dateRequests)
{
#printf("Monat %d\n",getMonth($dateReq));
write;
}
}
sub PrintUserLog
{
my $userReq;
my $pageperjob;
############# Output Form ################
format USERLOG_TOP =
PrinterAccounting
Username Requests Pages Pages/Request
--------------------------------------------------------
.
format USERLOG =
@<<<<<<<<<<<<<<<<<< @>>>>>>> @>>>>>>> @>>>>>>>>
$userReq, $userRequests{$userReq}, $userPages{$userReq}, $pageperjob
.
############# Output Form ################
$-=0;
$~="USERLOG";
$^="USERLOG_TOP";
foreach $userReq (sort { $userPages{$b} <=> $userPages{$a}} keys %userRequests)
{
$pageperjob = sprintf("%5d", POSIX::ceil($userPages{$userReq} / $userRequests{$userReq}));
write ;
}
}
sub PrintHourLog
{
my $hourReq;
my $outOfWorkingTime;
############# Output Form ################
format HOURLOG_TOP =
Hour Usage
Hour Requests
---------------------
.
format HOURLOG =
@<@<<<<< @>>>>>>>
$outOfWorkingTime,$hourReq,$hourRequests{$hourReq}
.
############# Output Form ################
$-=0;
$~="HOURLOG";
$^="HOURLOG_TOP";
foreach $hourReq (sort {$a <=> $b} keys %hourRequests)
{
if($hourReq <$WorkStart || $hourReq > $WorkEnd)
{
if($hourRequests{$hourReq} == 0)
{
next;
}
else
{
$outOfWorkingTime = "!";
}
}
else
{
$outOfWorkingTime = " ";
}
write;
}
}
sub PrintRequestSize
{
my $pageReq;
my %pageHeu;
my $pageHeuK;
my $pageperHeu;
############# Output Form ################
format REQUESTLOG_TOP =
Heuristic
JobSize %Requests
---------------------------
.
format REQUESTLOG =
@||||||||||| @>>>>>>>>
$pageHeuK,$pageperHeu
.
############# Output Form ################
# sammeln der Daten
foreach $pageReq (sort {$a <=> $b} keys %pageRequests)
{
if($pageReq >0 && $pageReq <=10)
{$pageHeu{"1. 0-10"}+=$pageRequests{$pageReq}};
if ($pageReq >10 && $pageReq <=20)
{$pageHeu{ "2. 20-30"}+=$pageRequests{$pageReq}};
if ($pageReq >20 && $pageReq <=30)
{$pageHeu{ "3. 30-40"}+=$pageRequests{$pageReq}};
if ($pageReq >40 && $pageReq <=50)
{$pageHeu{ "4. 40-50"}+=$pageRequests{$pageReq}};
if ($pageReq >50 && $pageReq <=100)
{$pageHeu{ "5. 50-100"}+=$pageRequests{$pageReq}};
if ($pageReq >100 && $pageReq <=200)
{$pageHeu{ "6. 100-200"}+=$pageRequests{$pageReq}};
if ($pageReq >200 )
{$pageHeu{ "7. 200- "}+=$pageRequests{$pageReq}};
}
$-=0;
$~="REQUESTLOG";
$^="REQUESTLOG_TOP";
foreach $pageHeuK (sort keys %pageHeu)
{
$pageperHeu = sprintf("%5.2f", 100*$pageHeu{$pageHeuK}/$totalReq);
write;
}
}
sub PrintCopySize
{
my $copyReq;
my %copyHeu;
my $copyHeuK;
my $copyperheu;
############# Output Form ################
format COPY_TOP =
Heuristic
Copies %Requests
---------------------------
.
format COPYLOG =
@||||||||||||| @>>>>>>>>
$copyHeuK,$copyperheu
.
############# Output Form ################
foreach $copyReq (sort {$a <=> $b} keys %copyRequests)
{
if($copyReq == 1 )
{$copyHeu{" 1. single"}+=$copyRequests{$copyReq}};
if($copyReq == 2)
{$copyHeu{" 2. 2 "}+=$copyRequests{$copyReq}};
if($copyReq == 3)
{$copyHeu{" 3. 3 "}+=$copyRequests{$copyReq}};
if($copyReq == 4)
{$copyHeu{" 4. 4 "}+=$copyRequests{$copyReq}};
if($copyReq >=5 && $copyReq <=10)
{$copyHeu{" 5. 5-10 "}+=$copyRequests{$copyReq}};
if ($copyReq >10 && $copyReq <=20)
{$copyHeu{ " 6. 20-30 "}+=$copyRequests{$copyReq}};
if ($copyReq >20 && $copyReq <=30)
{$copyHeu{ " 7. 30-40 "}+=$copyRequests{$copyReq}};
if ($copyReq >40 && $copyReq <=50)
{$copyHeu{ " 8. 40-50 "}+=$copyRequests{$copyReq}};
if ($copyReq >50 && $copyReq <=100)
{$copyHeu{ " 9. 50-100 "}+=$copyRequests{$copyReq}};
if ($copyReq >100 && $copyReq <=200)
{$copyHeu{ "10. 100-200 "}+=$copyRequests{$copyReq}};
if ($copyReq >200 )
{$copyHeu{ "11. 200- "}+=$copyRequests{$copyReq}};
}
$-=0;
$~="COPYLOG";
$^="COPY_TOP";
foreach $copyHeuK (sort keys %copyHeu)
{
$copyperheu = sprintf("%5.2f", 100*$copyHeu{$copyHeuK}/$totalReq);
write;
}
}
sub PrintQueueLog
{
my $queueReq;
my $reqperqueue;
my $pagepermin;
my $pageperqueue ;
############# Output Form ################
format QUEUELOG_TOP =
Queue Heuristic
Queue %Requests %Pages Pages
--------------------------------------------------------------
.
format QUEUELOG =
@>>>>>>>>>>>>>>>>>>>>> @>>>>>>> @>>>>>>> @>>>>>>>>
$queueReq,$reqperqueue,$pageperqueue,$queuePages{$queueReq}
.
############# Output Form ################
$-=0;
$~="QUEUELOG";
$^="QUEUELOG_TOP";
foreach $queueReq (sort { $queuePages{$b} <=> $queuePages{$a} } keys %queuePages)
{
$reqperqueue = sprintf("%5.2f", 100*$queueRequests{$queueReq}/$totalReq);
$pageperqueue = sprintf("%5.2f", 100*$queuePages{$queueReq}/$totalPages);
write;
}
}
sub PrintBillingLog
{
my $billing;
my $pageperbilling ;
my $billinguser;
############# Output Form ################
format BILLINGLOG_TOP =
Billing Heuristic
Billing Pages
--------------------------------------------------------------
.
format BILLINGLOG =
@<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>
$billing,$pageperbilling
.
format BILLINGUSERLOG =
|- @>>>>>>>>>>>>>>>>>>>>> @>>>>>>>>
$billinguser,$pageperbilling
.
############# Output Form ################
$-=0;
$~="BILLINGLOG";
$^="BILLINGLOG_TOP";
foreach $billing (sort keys %billingStats)
{
$pageperbilling = $billingStats{$billing}{"total_pages"};
$~="BILLINGLOG";
write;
$~="BILLINGUSERLOG";
foreach $billinguser ( sort {$billingStats{$billing}{"user"}{$b} <=> $billingStats{$billing}{"user"}{$a}} keys %{$billingStats{$billing}{"user"}})
{
$pageperbilling = $billingStats{$billing}{"user"}{$billinguser};
write;
}
}
}
sub HandleNewJob
{
my $realpages = $lastlogline{num_pages}*$lastlogline{copies};
my $hourstring = POSIX::strftime "%H", localtime($lastlogline{time}) ;
my $daystring = POSIX::strftime "%d/%m/%y", localtime($lastlogline{time}) ;
$userRequests{$lastlogline{user}}++;
$userPages{$lastlogline{user}}+=$realpages;
$dateRequests{$daystring}++;
$datePages{$daystring}+=$realpages;
$pageRequests{$realpages}++;
$queueRequests{$lastlogline{printer}}++;
$queuePages{$lastlogline{printer}}+=$realpages;
$hourRequests{$hourstring}++;
$copyRequests{$lastlogline{copies}}++;
$billingStats{$lastlogline{billing}}{"user"}{$lastlogline{user}} += $realpages;
$billingStats{$lastlogline{billing}}{"printer"}{$lastlogline{printer}} += $realpages;
$billingStats{$lastlogline{billing}}{"total_pages"} += $realpages;
$totalReq++;
$totalPages+=$realpages;
}
sub InitHourHistogram
{
my $i;
for ($i = 0 ; $i <=24 ; $i++)
{
my $hourstring = sprintf("%02d", $i);
$hourRequests{$hourstring}=0;
}
}
# main
open(PAGELOG,"$PAGE_LOG_FILE") || die "Can't open pagelog file $PAGE_LOG_FILE";
#initialize the hourhistogram
InitHourHistogram;
while(<PAGELOG>)
{
my $time;
my $pagenum;
%logline = ();
chomp();
($logline{printer},
$logline{user},
$logline{jobid},
$time,
$pagenum,
$logline{copies},
$logline{billing}) =
($_ =~ /^(.*)\s(.*)\s(\d+)\s(\[.*\])\s(\d+)\s(\d+)\s(.*)$/)
or do {
print STDERR "Cannot convert $_ \n";
next;
};
# downcase username because of samba
$logline{user}=~ tr/A-Z/a-z/;
# handle empty user
if ($logline{user} eq "") {
$logline{user}="TestPages";
}
# handle empty billing code
if ($logline{billing} eq "") {
$logline{billing}="-none-";
}
my $endtime = DateTime2Epoch( $time );
if ( ! defined $lastlogline{jobid} || $lastlogline{jobid} ne $logline{jobid} )
{
# new job;
$logline{num_pages} = 1;
$logline{time} = $endtime;
if ( defined $lastlogline{jobid} ) {
HandleNewJob;
};
} else {
# same job; update info
$logline{num_pages} = $lastlogline{num_pages} + 1;
$logline{time} = $lastlogline{time};
}
%lastlogline= %logline;
}
close(PAGELOG);
# handle last job
if ( defined $lastlogline{jobid} ) {
HandleNewJob;
}
PrintQueueLog;
PrintRequestSize;
PrintCopySize;
PrintBillingLog;
PrintUserLog;
PrintHourLog;
PrintDayLog;