For any custom written user services and processes, you should maintain a log file to view the status of the service, or to troubleshoot any issues with the services/processes.
Perl CPAN offers few modules which provides the automated object interface for handling logging for services.
In this article, let us write our own Perl logger module which internally uses Perl CPAN modules: Log::Agent, Log::Agent::Driver::File and Log::Rotate.
This custom perl logger module will perform the following operations.
- Define the Log rotation policy
- Define list of log files to be used by the services
- Define the permission for each log file
The CPAN modules listed above needs to be installed using one of the perl module installation methods.
In our custom Logger module perl code, the log rotation policy is used for each log file with the following parameters.
- Number of old log files that need to be kept
- Type of compression technique to be used for old log files
- Number of recent old files to be kept in uncompressed state
- Log file rotation size: i.e Maximum file size after which log file needs to be rotated.
- Rotation frequency – daily/weekly/monthly. This option takes higher priority if we also enable size based rotation.
Next, define the number of log files with following attributes.
- String to be prefixed for logging of messages.
- Timestamp format
- Define the logfile names.
- Permission for each of the file.
- Enable or Disable the replication of error message ( in error log file ) into output log file.
You can have separate policy or same policy for all the log files.
Custom Perl Logger Module Source Code
Logger.pm module code given below with explanation as perl comments.
package Logger; #This Logger module helps the other modules to log useful messages. use Exporter; # for exporting some methods from this class. @ISA = qw(Exporter ); #The "Log::Agent" module provides an abstract layer for logging and tracing. use Log::Agent qw(logwrite logerr logdie); #The file logging driver redirects logxxx() operations to specified files, one per #channel usually (but channels may go to the same file). use Log::Agent::Driver::File; #The "Log::Agent::Rotate" class holds the parameters describing the logfile rotation policy, #and is meant to be supplied to instances of "Log::Agent::Driver::File" via arguments in the #creation routine, such as "-rotate", or by using array references as values #in the "-channels" hashref use Log::Agent::Rotate; # exporting two necessary methods for writing some useful logs, to trace the error # in the program execution if any. @EXPORT = qw(logwrite logerr logdie); ################################################################################ # logging priorities ################################################################################ #Name Level Traditional Export #--------- ----- -------------- ------ #none -1 NONE (special, see text) #emergency 0 (emerg, panic) EMERG #alert 1 ALERT #critical 2 (crit) CRIT #error 3 (err) ERROR #warning 4 WARN #notice 6 NOTICE #info 8 INFO #debug 10 DEBUG ################################################################################ #=============================================================================== # NAME: Initialize # PURPOSE: to prepare the log file rotation policy and configure the logging channels # RETURNS: object of the current module. #=============================================================================== sub Initialize { my($Self) = shift; my($driver,$policy); # create the logfile rotation policy $RotatePolicy = Log::Agent::Rotate->make( #The total amount of old logfiles to keep, besides the current logfile. -backlog => 7, # The amount of old logfiles, amongst the most recent ones, that should not be com- # pressed but be kept as plain files. -unzipped => 2, # The maximum logfile size. This is a threshold, which will cause a logfile rotation # cycle to be performed, when crossed after a write to the file. If set # to 0, this threshold is not checked. -max_size => 100*1024*1024, # 100M # The maximum time in seconds between the moment we opened the file and the next rota- # tion cycle occurs. This threshold is only checked after a write to the file. -max_time => "1d", # 1 day ); # make the file driver ready for logging on files $driver = Log::Agent::Driver::File->make( # string to be prefixed on all messages -prefix => "LogDemo", # timestamp format 'yy/mm/dd hh:mm:ss' -stampfmt => "own", # to duplicate the error channel into the output channel messages with a prefixing made to clearly mark them as such: "FATAL: " for logdie(), logcroak() and logconfess(), "ERROR: " for logerr() and "WARNING: " for logwarn(). -duperr => 1, # Specifies where channels go -channels => { debug => [ "/tmp/debug.log", $RotatePolicy ], output => [ "/tmp/output.log", $RotatePolicy ], error => [ "/tmp/error.log", $RotatePolicy ], }, # Specifies the file permissions for the channels specified by "-channels". -chanperm => { debug => 0644, output => 0644, error => 0644, } ); # specfiy the logging to the file via the Driver::File Log::Agent::logconfig(-confess => 1, -driver => $driver, -debug => 1); $Self; } #=============================================================================== # NAME: new # PURPOSE: to create object for class # RETURNS: object of the called class #=============================================================================== sub new { my($Class) = shift; # getting the class name my $Self = bless {}, ref($Class) || $Class; my $ObjectName = ref($Self); $Self->Initialize(); $Self; } 1;
You can customize the above module based on any special needs by your custom services or processes.
Perl Main Program calling our Custom Logger
The following perl main program code uses our custom Logger modue.
#!/usr/bin/perl -I./ # update @INC array with the current directory. # include the Logger module here. use Logger; # create the object for the Logger module. $obj = new Logger(); # To log the messages into the debug channel(/tmp/debug.log) logwrite ( "debug","INFO","DEBUG - Debug message 1.\n"); # To log the messages into the output channel(/tmp/output.log) logwrite ( "output","NOTICE","OUTPUT - Output message 1\n"); # To log the messages into the error channel(/tmp/error.log) logerr(" Error message1 \n");
After some certain number of log rotations, you might see following files under /tmp directory.
$ ls -1 *log* debug.log debug.log.0 debug.log.1 debug.log.2.gz error.log error.log.0 error.log.1 error.log.2.gz output.log output.log.0 output.log.1 output.log.2.gz
Comments on this entry are closed.
Hi,
thanks for yor post, but want to let know that the 3rd CPAN perl module you mentioned as needed is called “Log::Agent::Rotate” instead of “Log::Rotate”.
Thumbs up for your blog,
Torsten