—————————=head1 NAME
Log::Fine - Yet another logging framework
=head1 SYNOPSIS
Provides fine-grained logging and tracing.
use Log::Fine;
use Log::Fine::Levels::Syslog; # exports log levels
use Log::Fine::Levels::Syslog qw( :masks ); # exports masks and levels
# build a Log::Fine object
my $fine = Log::Fine->new();
# specify a custom map
my $fine = Log::Fine->new(levelmap => "Syslog");
# Get the name of the log object
my $name = $fine->name();
# use logger() to get a new logger object. If "foo" is not
# defined then a new logger with the name "foo" will be created.
my $log = Log::Fine->logger("foo");
# get list of names of defined logger objects
my @loggers = $log->listLoggers();
# register a handle, in this case a handle that logs to console.
my $handle = Log::Fine::Handle::Console->new();
$log->registerHandle( $handle );
# log a message
$log->log(INFO, "Log object successfully initialized");
=head1 DESCRIPTION
Log::Fine provides a logging framework for application developers
who need a fine-grained logging mechanism in their program(s). By
itself, Log::Fine provides a mechanism to get one or more logging
objects (called I<loggers>) from its stored namespace. Most logging
is then done through a logger object that is specific to the
application.
For a simple functional interface to the logging sub-system, see
L<Log::Fine::Utils|Log::Fine::Utils>.
=head2 Handles
Handlers provides a means to output log messages in one or more
ways. Currently, the following handles are provided:
=over 4
=item * L<Log::Fine::Handle::Console|Log::Fine::Handle::Console>
Provides logging to C<STDERR> or C<STDOUT>
=item * L<Log::Fine::Handle::File|Log::Fine::Handle::File>
Provides logging to a file
=item * L<Log::Fine::Handle::File::Timestamp|Log::Fine::Handle::File::Timestamp>
Same thing with support for time-stamped files
=item * L<Log::Fine::Handle::Syslog|Log::Fine::Handle::Syslog>
Provides logging to L<syslog>
=back
See the relevant perldoc information for more information. Additional
handlers can be defined to the user's taste.
=cut
use
strict;
use
warnings;
package
Log::Fine;
require
5.006;
use
Carp;
use
Log::Fine::Levels;
use
Log::Fine::Logger;
our
$VERSION
=
'0.56'
;
=head2 Formatters
A formatter specifies how Log::Fine displays messages. When a message
is logged, it gets passed through a formatter object, which adds any
additional information such as a time-stamp or caller information.
By default, log messages are formatted as follows using the
L<Basic|Log::Fine::Formatter::Basic> formatter object.
[<time>] <LEVEL> <MESSAGE>
For more information on the customization of log messages, see
L<Log::Fine::Formatter>.
=head1 INSTALLATION
To install Log::Fine:
perl Makefile.PL
make
make test
make install
=cut
# Private Methods
# --------------------------------------------------------------------
{
# private global variables
my
$levelmap
;
my
$loggers
= {};
my
$objcount
= 0;
# getter/setter for levelMap. Note that levelMap can only be
# set _once_. Once levelmap is set, any other value passed,
# whether a valid object or not, will be ignored!
sub
_levelMap
{
my
$map
=
shift
;
if
(
defined
$map
and
$map
->isa(
"Log::Fine::Levels"
)
and not
$levelmap
) {
$levelmap
=
$map
;
}
elsif
(
defined
$map
and not
$levelmap
) {
_fatal(
sprintf
(
"Invalid Value: \"%s\""
,
$map
||
"{undef}"
));
}
return
$levelmap
;
}
# _levelMap()
sub
_logger {
return
$loggers
}
sub
_objectCount {
return
$objcount
}
sub
_incrObjectCount {
return
++
$objcount
}
}
# --------------------------------------------------------------------
=head1 METHODS
The Log::Fine module, by itself, provides getters & setter methods for
loggers and level classes. After a logger is created, further actions
are done through the logger object. The following two constructors
are defined:
=head2 new
Creates a new Log::Fine object.
=head3 Parameters
A hash with the following keys
=over
=item * levelmap
[default: Syslog] Name of level map to use. See L<Log::Fine::Levels>
for further details
=item * no_croak
[optional] If set to true, then do not L<croak|Carp> when
L</"_fatal()"> is called.
=back
=head3 Returns
The newly bless'd object
=cut
sub
new
{
my
$class
=
shift
;
my
%h
=
@_
;
# bless the hash into a class
my
$self
=
bless
\
%h
,
$class
;
# perform any necessary initializations
$self
->_init();
# return the bless'd object
return
$self
;
}
# new()
=head2 listLoggers
Provides list of currently defined loggers
=head3 Parameters
None
=head3 Returns
Array containing list of currently defined loggers
=cut
sub
listLoggers {
return
keys
%{ _logger() } }
=head2 levelMap
Getter for the global level map.
=head3 Returns
A L<Log::Fine::Levels> subclass
=cut
sub
levelMap {
return
_levelMap() }
=head2 logger
Getter/Constructor for a logger object.
=head3 Parameters
=over
=item * logger name
The name of the logger object. If the specified logger object does
not exist, then a new one will be created.
=back
=head3 Returns
an L<Log::Fine::Logger> object
=cut
sub
logger
{
my
$self
=
shift
;
my
$name
=
shift
;
# name of logger
# validate name
$self
->_fatal(
"First parameter must be a valid name!"
)
unless
(
defined
$name
and
$name
=~ /\w/);
# If the requested logger is found, then return it, otherwise
# store and return a newly created logger object with the
# given name
_logger()->{
$name
} = Log::Fine::Logger->new(
name
=>
$name
)
unless
(
defined
_logger()->{
$name
}
and _logger()->{
$name
}->isa(
"Log::Fine::Logger"
));
# return the logger
return
_logger()->{
$name
};
}
# logger()
=head2 name
Getter for name of object
=head3 Parameters
None
=head3 Returns
String containing name of object, otherwise undef
=cut
sub
name {
return
$_
[0]->{name} ||
undef
}
# --------------------------------------------------------------------
=head2 _fatal
Private method that is called when a fatal (nonrecoverable) condition
is encountered. Will call L<croak|Carp> unless the {no_croak}
attribute is set. For internal Log::Fine use I<only!>
This method can be overridden per taste.
=head3 Parameters
=over
=item message
Message passed to L<croak|Carp>.
=back
=cut
sub
_fatal
{
my
$self
;
my
$msg
;
my
@call
=
caller
;
# how were we called?
if
(
scalar
@_
> 1) {
$self
=
shift
;
$msg
=
shift
;
}
else
{
$msg
=
shift
;
}
printf
STDERR
"\n[%s] {%s@%d} FATAL : %s\n"
,
strftime(
"%c"
,
localtime
(
time
)),
$call
[0] ||
"{undef}"
,
$call
[2] || 0,
$msg
||
"No reason given"
;
croak
$msg
if
((
defined
$self
and
$self
->isa(
"Log::Fine"
)
and not
$self
->{no_croak})
or (not
defined
$self
));
}
# _fatal()
##
# Initializes our object
sub
_init
{
my
$self
=
shift
;
# increment object count
_incrObjectCount();
# we set the objects name unless it is already set for us
unless
(
defined
$self
->{name} and
$self
->{name} =~ /\w/) {
# grab the class name
$self
->{name} =
ref
$self
;
$self
->{name} =~ /\:(\w+)$/;
$self
->{name} =
lc
($+) . _objectCount();
}
# Set our levels if we need to
_levelMap(Log::Fine::Levels->new(
$self
->{levelmap}))
unless
(
defined
_levelMap()
and _levelMap()->isa(
"Log::Fine::Levels"
));
# Victory!
return
$self
;
}
# _init()
# is "Python" a dirty word in perl POD documentation? Oh well.
=head1 ACKNOWLEDGMENTS
I'd like the thank the following people for either inspiration or past
work on logging: Josh Glover for his work as well as teaching me all I
know about object-oriented programming in perl. Dan Boger for taking
the time and patience to review this code and offer his own
suggestions. Additional thanks to Tom Maher and Chris Josephs for
encouragement.
=head2 Related Modules/Frameworks
The following logging frameworks provided inspiration for parts of Log::Fine.
=over 4
=item
Dave Rolsky's L<Log::Dispatch> module
=item
Sun Microsystem's C<java.utils.logging> framework
=item
The Python logging package
=back
=head1 BUGS
Please report any bugs or feature requests to
C<bug-log-fine at rt.cpan.org>, or through the web interface at
I will be notified, and then you'll automatically be notified of progress on
your bug as I make changes.
=head1 SUPPORT
You can find documentation for this module with the perldoc command.
perldoc Log::Fine
You can also look for information at:
=over 4
=item * AnnoCPAN: Annotated CPAN documentation
=item * CPAN Ratings
=item * RT: CPAN's request tracker
=item * Search CPAN
=back
=head1 CONTRIBUTING
Want to contribute? The source code repository for Log::Fine is now
available at L<http://github.com/cfuhrman/log-fine>. To clone your
own copy:
$ git clone git://github.com/cfuhrman/log-fine.git
Signed patches generated by L<git-format-patch>(1) may be submitted
L<via email|/AUTHOR>.
=head1 REVISION INFORMATION
$Id: 74a9a78fe2c62d8b703bc2055d7fad32a9180fc4 $
=head1 AUTHOR
Christopher M. Fuhrman, C<< <cfuhrman at panix.com> >>
=head1 SEE ALSO
L<perl>, L<syslog>, L<Log::Fine::Handle>, L<Log::Fine::Formatter>,
L<Log::Fine::Logger>, L<Log::Fine::Utils>, L<Sys::Syslog>
=head1 COPYRIGHT & LICENSE
Copyright (c) 2008-2011 Christopher M. Fuhrman,
All rights reserved.
This program is free software licensed under the...
The BSD License
The full text of the license can be found in the
LICENSE file included with this module.
=cut
1;
# End of Log::Fine