File PrintAnalyzer of Package cups

#!/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;






openSUSE Build Service is sponsored by