B - OOish dynamic and customizable logging


NAME

Log::Dynamic - OOish dynamic and customizable logging


SYNOPSIS

Object instatiation

   use Log::Dynamic;
   # Set up logging so that _ALL_ log types are valid
   my $log = Log::Dynamic->open (
       file => 'logs/my.log',
       mode => 'append',
   );
      ## OR ##
   # Set up logging so that there is a set list of valid types
   my $log = Log::Dynamic->open (
       file  => 'logs/my.log',
       mode  => 'append',
       types => [qw/ foo bar baz /],
   );
      ## OR ##
   # Set up logging so that there is a set list of valid types
   # and override the default invalid type handler
   my $log = Log::Dynamic->open (
       file         => 'logs/my.log',
       mode         => 'append',
       types        => [qw/ foo bar baz /],
       invalid_type => sub { "INVALID TYPE: ".(shift)."\n" },
   );

Basic logging

   # Just like many other logging packages:
   $log->log('INFO', 'I can has info?');
   $log->log('ERROR', 'Oh crapz! Someone killed a kittah!');

Custom logging

   # Call any log type you like as an object method. For 
   # example, if you are logging cache hits and misses you 
   # might want to do something like:
   if ($CACHE->{$key}) {
       $log->cache_hit("Got hit on key $key");
       return $CACHE->{$key};
   } else {
       $log->cache_miss("Awww... Key $key was a miss");
       $CACHE->{$key} = do_expensive_operation(@args);
   }

Other usage

   # Use the object as a file handle for print() statements
   # from within your script or application:
   print {$$log} "This is a custom message. Pay attention!\n";


DESCRIPTION

Yet another darn logger? Why d00d?

Well, I wanted to write a lite weight logging module that...

 * developers could use in a way that felt natural to them
   and it would just work,
 * was adaptable enough that it could be used in dynamic, 
   ever changing environments,
 * was flexible enough to satisfy most logging needs without 
   too much overhead,
 * and gave developers full control over handling the myriad
   of log events that occur in large applications.

Log::Dynamic still has a ways to go, but the direction seems promising. Comments and suggestions are always welcome.


LOG FORMAT

Currently Log::Dynamic has only one format for the log entries which looks like:

    TIME/DATE STAMP [LOG TYPE] LOG MESSAGE (CALLER INFO)

Eventually this module will have support user defined log formats, as it should having a name like Log::Dynamic.


LOG TYPES

Log ``type'' refers to the string displayed in the square brackets of your log output. In the following example the type is 'BEER ERROR':

    Thu Nov  8 21:14:12 2007 [BEER ERROR] Need more (main bottles.pl 99)

For those unfamiliar with logging this is especially useful when grep-ing through your logs for specific types of errors, ala:

    % grep -i 'beer error' /path/to/my.log

As stated above, by default there is no set list of types that this module supports. If you want to have a new type start showing up in your logs just call an object method of that name and Log::Dynamic will automatically do what you want:

    $log->new_type('Hai!');


LIMITING LOG TYPES

By default Log::Dynamic supports any log type you throw at it. However, if you would like to define a finite set of valid (supported) log types you may do so using the 'types' parameter durning object instantiation. For example, if you would like only the types 'info', 'warn', and 'error' to be valid log types within your application you would instantiate you object like:

    my $log = Log::Dynamic->open (
        file  => 'my.log',
        types => [qw/ info warn error /],
    );

If you decide to define a set of valid types and your application attempts to log with an invalid type, then, by default Log::Dynamic will croak with an appropriate error. _HOWEVER_, if you don't want to go around your application wrapping each log call in an eval then you may override this behavior using the 'invalid_type' parameter:

    my $log = Log::Dynamic->open (
        file         => 'my.log',
        types        => [qw/ info warn error /],
        invalid_type => sub { warn (shift)." is bad! Moving on...\n" }
    );

If you choose to override the default invalid type handler Log::Dynamic will execute the provided subroutine and will pass it one parameter: the string of the invalid type that your application attempted to use.


METHODS


OTHER USAGE

While most OO modules bless a reference to a data structure, this module blesses a reference to an open file handle. Why did I do that? Because I can and I felt like doing something different. The only ``special'' thing this really lets you do is use the object as a file handle from within your script or application. All you have to do is dereference it when you use it. For example:

    # Normal log entry
    $log->info('This is information');
    # Special log entry
    print {$$log} "*** Hai. I am special. Pls give me attention! ***\n";

Obviously if you use the object in this special way you will not get any of the nice additional information (timestamp, log type, and caller information) that you would get when using the normal way. This simply gives you the flexibility to print anything you want to your log. A useful example would be a dump of an object or data structure:

    use Data::Dumper;
    print {$$log} "Object dump:\n" . Dumper($object);


BUGS

None that I know of yet.


AUTHOR

James Conerly <jconerly@cpan.org> 2007


LICENSE

This software is free to use. If you use pieces of my code in your scripts or applications all I ask is that you site me. Other than that, log away my friends.


SEE ALSO

Carp

 B - OOish dynamic and customizable logging