The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Package::Base::Devel - Perl extension for blah blah blah

SYNOPSIS

#don't use this module directly, but rather inherit from it.
package My::Package;
use base qw(Package::Base::Devel);

#... see Package::Base for details on the new() and init() methods
#that are inherited by Package::Base::Devel.

#it isn't necessary to use new() or init() in your class hierarchy,
#Package::Base::Devel is smart enough to initialize itself the first
#time you call an inherited method.

DESCRIPTION

Provides the the same base functionality as Package::Base, but additionally provides automatic setup of Log::Log4perl loggging.

TRAPPED SIGNALS: warn() AND die().

Package::Base::Devel traps $SIG{__WARN__} and $SIG{__DIE__}. This is so we can log warn() and die() calls and what package they come from. After trapping the signal the default warn() and die() methods (CORE::warn() and CORE::die(), respectively) are called.

This signal trapping may not play nicely with other modules that also alter Perl's default exception handling behaviour. If you find this to be the case, please let me know, I do not use and have not tested against these other modules. If there is a way to detect signal handling clashes, please also let me know and I will modify this module appropriately.

CUSTOMIZED LOGGING

When the first instance of a class inheriting from Package::Base::Devel is instantiated, a Log::Log4perl::Logger is created. This uses a call to Log::Log4perl->init() for initialization of the logging object. The default Log::Log4perl configuration template used for this by Package::Base::Devel is:

log4perl.logger.%s   = DEBUG, %s
log4perl.appender.%s = Log::Log4perl::Appender::Screen
log4perl.appender.%s.stdout = 0
log4perl.appender.%s.stderr = 1
log4perl.appender.%s.layout = Log::Log4perl::Layout::PatternLayout
log4perl.appender.%s.layout.ConversionPattern =[%%d{HH:mm:ss}] %%-5p - %%-30c %%40M() in file .../%%F{2} (%%4L): %%m%%n

A few comments on the above configuration stanza:

* Notice there are several (seven) %s strings. If you guessed that this stanza is interpreted using an sprintf() call, you are right. The %s are replaced by a mangled version of the namespace of the package for which logging is being set up.

* Notice the word DEBUG. This is the default logging level for any class set up with this template. See "loglevel()" for a listing of valid strings here.

* This string can have as many %s slots as you like, so you have great flexibility as to how you want to set up your configuration stanza. This string must contain at at least two %s, as it is the minimum necessary for a valid configuration stanza.

To customize the default configuration stanza, just update $Package::Base::Devel::log4perl_template to something else recognizable by Log::Log4perl.

Caveat: Any time this string is changed before the first instantiation of a class inheriting from Package::Base::Devel, the instantiation event will cause a full reinitialization of Log::Log4perl using this template for all classes. Therefore it is recommended you set this template once in package main, startup.pl if you're using mod_perl, or in some other high-level package. This will prevent multiple reinitializations of the loggers, and potentially unintended results. Consider the following code:

package main;
use My::Class::A; #which inherits from Package::Base::Devel
use My::Class::B; #also inherits...

my $a = My::Class::A->new(some => 'args');

$Package::Base::Devel::log4perl_template = "this is an invalid log4perl stanza";

$a->log->info('this info STILL goes to the logger with the default config, no problem');

my $b = My::Class::B->new(some => 'args');
#the loggers were reinitialized with the updated template.
$b->log->info('this message fails');
$a->log->info('this message also fails');

The main thing you're likely to want to change at runtime is the log level. See "loglevel()" or Log::Log4perl to learn about log levels. To accomodate this, Package::Base::Devel provides the "loglevel()" shortcut function that allows calls like:

my $a1 = My::Class::A->new();
my $a2 = My::Class::A->new();

$a1->log->debug('debugging message'); #goes to log, DEBUG is the default log level, remember?
$a2->log->debug('this goes through to the logger also');

$a1->loglevel('FATAL'); #only show fatal messages
$a1->log->debug('this does not go through, log level too high');
$a2->log->debug('calls from $a2 are now also blocked, '.
                'as the logger is effectively a class instance');

AUTHOR

Allen Day, <allenday@ucla.edu>

SEE ALSO

Package::Base.

METHODS

new()

Identical functionality to Package::Base::new().

is_initialized()

Usage   : $boolean = $object->is_initialized();
Returns : true or false
Args    : none
Function: check to see if init() has been called or not.

init()

Usage   : $object->init(key1 => 'value1', key2 => 'value2');
Returns : a reference to the calling object
Args    : an anonymous hash of object attribute/value pairs.
Function: uses anonymous hash parameters to initialize object just as
          Package::Base.  See Package::Base::init() for details.

          Additionally sets up a Log::Log4perl configuration and logger
          instance for the object's class (ref($object)) if a Log::Log4perl
          configuration does not already exist.  The Log::Log4perl
          configuration template is customizable by setting
          $Package::Base::Devel::log4perl_template, See L</CUSTOMIZED LOGGING>.

log()

Usage   : $object->log->debug('some debugging message');
          $object->log->info('some info');
          $object->log->warn('something bad happened');
          $object->log->fatal('something really bad happened');
Returns : a Log::Log4perl::Logger instance
Args    : none
Function: This gives access to the $object's logging instance.
          L<Log::Log4perl> for more details.  See L</CUSTOMIZED LOGGING>
          for additional info on how to affect logging behavior
          for your subclass.

logconfig()

Usage   : $object->logconfig('a Log4perl configuration stanza');
Returns : the configuration stanza for $object
Args    : a Log4perl configuration stanza.  L<Log::Log4perl> for details
Function: This method allows you to set the configuration parameters for
          your subclass on a fine-grained level.  You can call this method
          at any time, and all logged packages will have their configurations
          reloaded.

          I've created a shortcut method, L</loglevel()> to easily update the
          Log::Log4perl::Logger instance's verbosity level() -- it's a lot
          easier than rewriting the configuration stanza.  If you would like
          easy access to other logger methods let me know and I'll add them.

loglevel()

Usage   : $self->loglevel('FATAL'); #only log fatal messages
Returns : 
Args    : a level string.  valid values, in order of ascending verbosity:
          OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL
Function: adjust Log::Log4perl::Logger logging level

_mangle_package()

Usage   : An internal method, not intended to be called
          externally.
Returns : A mangled package string
Args    : A package name
Function: this is an internal utility method for generating
          valid Log::Log4perl::Logger names

_make_logger()

An internal method. Returns a Log::Log4perl::Logger instance

INTERNAL UTILITY METHODS FOR LOGGING AND DIE/WARN TRAPPING

_die()

Usage   : This is an internal method, not intended to be called
          externally.
Function: logs a fatal message and calls CORE::die().
          Package::Base::Devel signal-traps die() calls to log
          them before really dying (via CORE::die()).
Returns : never.  program exits.
Args    : An epitaph for your program

_warn()

Usage   : This is an internal method, not intended to be called
          externally.
Function: logs a warning message and calls CORE::warn().
          Package::Base::Devel signal-traps warn() calls to log
          them before really warning (via CORE::warn()).
Returns : 1
Args    : A warning message for your program.