perl logging - ghdrako/doc_snipets GitHub Wiki

log4perl

By default Log::Log4perl will print to the STDERR (Standard error) channel which is by default connected to the screen.

use Log::Log4perl qw(:easy);     #load the module importing the :easy key that will import 6 functions for the 6 logging levels provided by Log::Log4perl and 6 variables with corresponding names
Log::Log4perl->easy_init($WARN); #set the minimal log-level to be WARN
 
FATAL "This is", " fatal";
ERROR "This is error";
WARN  "This is warn";
INFO  "This is info";   # not show
DEBUG "This is debug";
TRACE "This is trace";  # not show
use Log::Log4perl qw(:easy);


DEBUG("message");
INFO("message");
WARN("message");
ERROR("message");
FATAL("message");

Turn off logging

Log::Log4perl->easy_init($OFF);

Using methods

use Log::Log4perl qw(:easy);
Log::Log4perl->easy_init($WARN);
 
my $logger = Log::Log4perl->get_logger();
$logger->fatal( "This is", " fatal");
$logger->error( "This is error");
$logger->warn(  "This is warn");
$logger->info(  "This is info");
$logger->debug( "This is debug");
$logger->trace( "This is trace");
use Log::Log4perl ();
use Log::Log4perl::Level ();
 
Log::Log4perl->easy_init(Log::Log4perl::Level::to_priority( 'WARN' ));
 
my $logger = Log::Log4perl->get_logger();
$logger->fatal( "This is", " fatal");
$logger->error( "This is error");
$logger->warn(  "This is warn");
$logger->info(  "This is info");
$logger->debug( "This is debug");
$logger->trace( "This is trace");
open FILE, "<blah" or die "Can't open blah -- bailing out!";  <--->  open FILE, "<blah" or $log->logdie("Can't open blah -- bailing out!");
                                                                     open FILE, "<blah" or LOGDIE "Can't open blah -- bailing out!";

Initializing Log4perl with a configuration file

###############################################################################
#                              Log::Log4perl Conf                             #
###############################################################################
log4perl.rootLogger              = DEBUG, LOG1
log4perl.appender.LOG1           = Log::Log4perl::Appender::File
log4perl.appender.LOG1.filename  = /var/log/mylog.log
log4perl.appender.LOG1.mode      = append
log4perl.appender.LOG1.layout    = Log::Log4perl::Layout::PatternLayout
log4perl.appender.LOG1.layout.ConversionPattern = %d %p %m %n
#!/usr/bin/perl

use Log::Log4perl;

# Initialize Logger
my $log_conf = "/etc/log4perl.conf";
Log::Log4perl::init($log_conf);
my $logger = Log::Log4perl->get_logger();

# sample logging statement
$logger->info("this is an info log message");

initialize Log4perl without using a config file

#!/usr/bin/perl
use Log::Log4perl;

# Initialize Logger
my $log_conf = q(
   log4perl.rootLogger              = DEBUG, LOG1
   log4perl.appender.LOG1           = Log::Log4perl::Appender::File
   log4perl.appender.LOG1.filename  = /var/log/mylog.log
   log4perl.appender.LOG1.mode      = append
   log4perl.appender.LOG1.layout    = Log::Log4perl::Layout::PatternLayout
   log4perl.appender.LOG1.layout.ConversionPattern = %d %p %m %n
);
Log::Log4perl::init(\$log_conf);
my $logger = Log::Log4perl->get_logger();

# sample logging statement
$logger->info("this is an info log message");

Output messages to file and screen using appenders

###############################################################################
#                              Log::Log4perl Conf                             #
###############################################################################
log4perl.rootLogger              = DEBUG, LOG1, SCREEN
log4perl.appender.SCREEN         = Log::Log4perl::Appender::Screen
log4perl.appender.SCREEN.stderr  = 0
log4perl.appender.SCREEN.layout  = Log::Log4perl::Layout::PatternLayout
log4perl.appender.SCREEN.layout.ConversionPattern = %m %n
log4perl.appender.LOG1           = Log::Log4perl::Appender::File
log4perl.appender.LOG1.filename  = /var/log/mylog.log
log4perl.appender.LOG1.mode      = append
log4perl.appender.LOG1.layout    = Log::Log4perl::Layout::PatternLayout
log4perl.appender.LOG1.layout.ConversionPattern = %d %p %m %n

It should be noted, that the output to STDOUT is buffered and there is apparently no way of enabling autoflush so that it doesn't buffer the output.

Log events and messages to a database

############################################################
# A simple root logger with a Log::Log4perl::Appender::DBI #
############################################################
log4perl.rootLogger   = INFO, DBI
log4perl.appender.DBI = Log::Log4perl::Appender::DBI
log4perl.appender.DBI.datasource=DBI:mysql:database=test;host=localhost;port=3306
log4perl.appender.DBI.username=guest
log4perl.appender.DBI.password=12345
log4perl.appender.DBI.sql=INSERT INTO log VALUES (0,?,?,?,?)
log4perl.appender.DBI.params.1=%F{1}
log4perl.appender.DBI.params.2=%d{yyyy-MM-dd HH:mm:ss}
log4perl.appender.DBI.params.3=%p
log4perl.appender.DBI.usePreparedStmt=1
log4perl.appender.DBI.layout=Log::Log4perl::Layout::NoopLayout
log4perl.appender.DBI.warp_message=0
--
-- Definition of table `log`
--
DROP TABLE IF EXISTS `log`;
CREATE TABLE `log` (
  `log_id` int(11) NOT NULL auto_increment,
  `log_source` varchar(100) NOT NULL default '',
  `log_date` datetime NOT NULL default '0000-00-00 00:00:00',
  `log_level` varchar(10) NOT NULL default '',
  `log_mesg` varchar(200) NOT NULL default '',
  PRIMARY KEY  (`log_id`),
  KEY `log_date_idx` (`log_date`),
  KEY `log_source_idx` (`log_source`),
  KEY `log_mesg_idx` (`log_mesg`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
SELECT * FROM mydb.log

Logging messages to Syslog

Log::Log4perl can be used by Perl scripts or tools that need to write log messages to Syslog through the use of a special appender. This facility is provided in Log::Log4perl via the JavaMap::SyslogAppender which is a wrapper for the Log::Dispatch::Syslog module. To get this to work, you will need to install both Log::Log4perl, as well as, Log::Dispatch::Syslog. Our solution calls for a log4perl.conf file that would look like this:

############################################################
# A simple root logger using Log::Log4perl::JavaMap        #
############################################################
log4j.appender.SyslogAppender            = org.apache.log4j.SyslogAppender
log4j.appender.SyslogAppender.SyslogHost = localhost
log4j.appender.SyslogAppender.Facility   = daemon
log4j.appender.SyslogAppender.layout     = org.apache.log4j.PatternLayout
log4j.appender.SyslogAppender.ConversionPattern = %p: %m%n

Alternatively, you can always call the Log::Dispatch::Syslog code directly as follows:

############################################################
#  Log::Log4perl conf - Syslog                             #
############################################################
log4perl.rootLogger                = DEBUG, SYSLOG
log4perl.appender.SYSLOG           = Log::Dispatch::Syslog
log4perl.appender.SYSLOG.min_level = debug
log4perl.appender.SYSLOG.ident     = myprocess
log4perl.appender.SYSLOG.facility  = daemon
log4perl.appender.SYSLOG.layout    = Log::Log4perl::Layout::SimpleLayout

Have different applications or scripts write to the same log file

###############################################################################
#                              Log::Log4perl Conf                             #
###############################################################################
log4perl.logger.my_app           = DEBUG, LOG1
log4perl.appender.LOG1           = Log::Log4perl::Appender::File
log4perl.appender.LOG1.filename  = /var/log/mylog.log
log4perl.appender.LOG1.mode      = append
log4perl.appender.LOG1.layout    = Log::Log4perl::Layout::PatternLayout
log4perl.appender.LOG1.layout.ConversionPattern = %d %p %m %n

# second logger points to the same file but with different level
log4perl.logger.my_other_app     = INFO, LOG2
log4perl.appender.LOG2           = Log::Log4perl::Appender::File
log4perl.appender.LOG2.filename  = /var/log/mylog.log
log4perl.appender.LOG2.mode      = append
log4perl.appender.LOG2.layout    = Log::Log4perl::Layout::PatternLayout
log4perl.appender.LOG2.layout.ConversionPattern = %d %p %m %n

To utilize this configuration, suppose we have to separate Perl scripts named my_app.pl and my_other_app.pl. They would both initialize the Log::Log4perl using the same conf file. Immediately after instantiating the $logger object, the get_logger() method would be called by each script, passing in the value of the logger to get, as follows:

#!/usr/bin/perl

use Log::Log4perl;

# Initialize Logger
my $log_conf = "/etc/log4perl.conf";
Log::Log4perl::init($log_conf);
my $logger = Log::Log4perl->get_logger('my_app');

# sample logging statement
$logger->info("this is an info log message");

Oter aplication differ in:

$logger->get_logger('my_other_app');

Log::Any

Log::Any allows CPAN modules to safely and efficiently log messages, while letting the application choose (or decline to choose) a logging mechanism such as Log::Dispatch or Log::Log4perl.

log.pm

$cat log.pm
#!perl -w

# Log.pm -- a simple logger which uses DBI and DBD::CSV to
# handle all the file locking. All log entries are kept in
# a text file, to make reading it much easier than if they
# had been put into a real database.
# copyright September 23, 2001 by Michael S. Joyce
# [email protected]
# This code may be used and distributed under the same terms
# as Perl.
# TODO:
# add an option to make database connections
# happen with each call to logger(), instead of
# maintaining the connection for the lifetime of
# the program

use DBI;
use strict;

package Logger;

use vars qw($tbldefault $dbdefault);

# default name for the log file
$tbldefault="errlog";

# default directory for the log files
$dbdefault='E:\\\\log';

# check to see if a log file exists,
# and create it if it doesn't.
sub tblexists {
  my $dbh = shift;
  my $tblname = shift;

# $dbh->tables() is a new method in DBI version 1.09
  unless (scalar grep {$_ eq $tblname} $dbh->tables())
  {
    my $crtstr=<<ENDQ;
      CREATE TABLE $tblname(
        date      CHAR(24),
        filename  CHAR(24),
        lineno    CHAR(8),
        message   VARCHAR(256)
       )
ENDQ
    $dbh->do($crtstr) or die "creating table: $!\n$dbh->errstr";
  }
}

# initialize the logger
# put a statement handle and database handle
# into self, as well as other potentially useful information
sub initialize {
  my $self = shift;
  
  $self->{'tblname'}=shift || $tbldefault;
  $self->{'dbname'}=shift || $dbdefault;
  $self->{'constr'}="DBI:CSV:f_dir=$self->{'dbname'}";

  my $dbh = DBI->connect($self->{'constr'})
    or die "No Database Connection Made: $!\n $DBI::errstr\n";
  $self->{'dbhandle'}=$dbh;

  tblexists($dbh, $self->{'tblname'});

  my $instr="INSERT INTO $self->{'tblname'} VALUES (?,?,?,?)";
  my $sth=$dbh->prepare($instr);
  $self->{'sthandle'}=$sth;
}

# simple constructor
# most of the work is done in initialize()
sub new {
  my $class = shift;
  my $self = {};
  bless $self, $class;
  $self->initialize(@_);
  return $self;
}

# member function to log a message
sub logger {
  my $self = shift;
  my $sth = $self->{'sthandle'};
  my $time=localtime();
  my $message = shift;

  my ($package, $filename, $line) = caller;
  
  $sth->execute($time, $filename, "line $line", $message);
}

# Destructor to cleanup database connections
sub DESTROY {
  my $self = shift;
  my $dbh = $self->{'dbhandle'};
  $dbh->disconnect();
}

1;

⚠️ **GitHub.com Fallback** ⚠️