stop being a caveman! use log::log4perl;
DESCRIPTION
Stop Being A Caveman! use Log::Log4perl;. by Eric Andreychek [email protected]. A long time ago... in a galaxy far, far away people debugged Perl code using print and warn statements some of these Perl coders even used the legendary and infamous Perl debugger - PowerPoint PPT PresentationTRANSCRIPT
![Page 2: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/2.jpg)
A long time ago...
in a galaxy far, far away
people debugged Perl code
using print and warn statements
some of these Perl coders even used
the legendary and infamous Perl debugger
these hard working Perl coders were known as ...
Cavemen
![Page 3: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/3.jpg)
Put These To Rest
Log4perl can help us make ideas like print, warn, and the Perl debugger artifacts of history
![Page 4: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/4.jpg)
Lets get this part out of the way...
● Log4perl lets you log stuff
● In Perl
● And it's really cool
![Page 5: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/5.jpg)
All You Need...
● Define a logging level
● Define where and what to log
● Use the (so-simple-it's-silly) interface
![Page 6: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/6.jpg)
Log Levels
fatal
error
warn
info
debug
Highest
Lowest
![Page 7: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/7.jpg)
Logger Objects
● Logger objects ($logger) do the work– Retrieved using Log4perl's get_logger() method
● Logging may occur in any sub in your program– No need to pass $logger to each sub
● Messy and Annoying
● Log4perl stores the logger object internally– A call to get_logger() returns that stored object
● Called a singleton
![Page 8: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/8.jpg)
Logging Example
$logger = get_logger();
# Logs when warn, info, or debug
$logger->warn(“Help me Obi-Wan, you're my only hope”);
# Remains dormant when error or fatal!
![Page 9: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/9.jpg)
Initializing Log4perl
# To set up logging, you could use the following:
use Log::Log4perl qw( :easy );
Log::Log4perl->easy_init( $ERROR );
![Page 10: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/10.jpg)
Not!We don't need no steenking “easy”
# To set up logging, you could use the following:
use Log::Log4perl qw( :easy );
Log::Log4perl->easy_init( $ERROR );
![Page 11: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/11.jpg)
Initializing Log4perl: /The Real (:?wo)?man's Way/
# Darth.pl
use Darth();use Log::Log4perl();
$config = get_my_config();Log::Log4perl::init( $config );
![Page 12: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/12.jpg)
Using Log4perl
package Darth;
use Log::Log4perl qw( get_logger );
sub new { my ( $class, $name ) = @_; my $logger = get_logger();
$logger->debug(“Creating Darth $name”);
return bless( { darth => $name }, $class );}
![Page 13: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/13.jpg)
Using Log4perl
sub get_lightsaber { my $self = shift; my $logger = get_logger();
$logger->debug(“Fetching lightsaber from the armory”);
my $saber = $self->_saber_type || “Red Single-Sided Saber”; $logger->warn(“Giving Darth his light saber: $saber”);
return $saber;}
![Page 14: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/14.jpg)
Log4perl Return Values
● Logging functions return the number of places they were logged– If message logged: return true– If no message logged: return undef– $total = $logger->warn( $message );
● Being at the WARN level doesn't necessarily mean $logger->warn($message) will be logged– Log4perl could suppress the message– A suppressed message would return undef
![Page 15: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/15.jpg)
Using Log4perl: Errors# Later on in darth.plmy $saber = $darth->get_lightsaber;
unless ( $saber ) { my $error = “Nothing to defend against the good guys with, ” .
“not even an electronic sausage!”
# This will often work, but tends to be a really bad idea $logger->fatal( $error ) && die( $error )
# This utility method doesn't depend on the return value of # $logger->fatal, it will always die $logger->logdie( $error )}
![Page 16: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/16.jpg)
Future of Internet Keyboards
![Page 17: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/17.jpg)
Configuring The Beast
● Configuring Log4perl: TMTOWTDI– Perl– Config files– Both
![Page 18: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/18.jpg)
Config Files (my favorite)
use Log::Log4perl qw( get_logger );
Log::Log4perl::init( “log4perl.conf” );
my $logger = get_logger();
![Page 19: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/19.jpg)
Config File ExampleContents of log4perl.conf
log4perl.logger = INFO, Screen
log4perl.appender.Screen = Log::Dispatch::Screen
log4perl.appender.Screen.layout = SimpleLayout
![Page 20: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/20.jpg)
Config File: CategoryThis config applies to my what?
log4perl.logger = INFO, Screen
log4perl.appender.Screen = Log::Dispatch::Screen
log4perl.appender.Screen.layout = SimpleLayout
![Page 21: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/21.jpg)
Config File: AppenderYou want me to log where?
log4perl.logger = INFO, Screen
log4perl.appender.Screen = Log::Dispatch::Screen
log4perl.appender.Screen.layout = SimpleLayout
![Page 22: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/22.jpg)
Config File: Message LayoutYou want me to log how?
log4perl.logger = INFO, Screen
log4perl.appender.Screen = Log::Dispatch::Screen
log4perl.appender.Screen.layout = SimpleLayout
![Page 23: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/23.jpg)
Appender (log) Methods
● Log4perl uses Log::Dispatch to perform logging– Log::Dispatch supports a number of locations
● ApacheLog● DBI● Email● Files● STDOUT / STDERR (Screen)● Syslog● Jabber● Anything else you write
![Page 24: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/24.jpg)
Appender Location: Log to FileChange From Screen to File
log4perl.logger = INFO, Screen
log4perl.appender.Screen = Log::Dispatch::File
log4perl.appender.Screen.Filename = myfile.log
log4perl.appender.Screen.layout = SimpleLayout
![Page 25: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/25.jpg)
Appender NameShould Make Sense!
log4perl.logger = INFO, FileLog
log4perl.appender.FileLog = Log::Dispatch::File
log4perl.appender.FileLog.Filename = myfile.log
log4perl.appender.FileLog.layout = SimpleLayout
![Page 26: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/26.jpg)
Logging To Multiple LocationsChange to File and Screen with Two Appenders
log4perl.logger = INFO, Screen, FileLog
log4perl.appender.Screen = Log::Dispatch::Screen
log4perl.appender.Screen.layout = SimpleLayout
log4perl.appender.FileLog = Log::Dispatch::File
log4perl.appender.FileLog.filename = myfile.log
log4perl.appender.FileLog.layout = SimpleLayout
![Page 27: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/27.jpg)
Changing The Log Format
log4perl.logger = INFO, Screen
log4perl.appender.Screen = Log::Dispatch::Screen
log4perl.appender.Screen.layout = PatternLayout
log4perl.appender.Screen.layout.ConversionPattern=%F %L: %m%n
![Page 28: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/28.jpg)
Available Placeholders (16 total)
%c Category of the logging event. %C Fully qualified package (or class) name of the caller %d Current date in yyyy/MM/dd hh:mm:ss format %F File where the logging event occurred %H Hostname %l Fully qualified name of the calling method followed by the callers source the file name and line number between parentheses. %L Line number within the file where the log statement was issued %m The message to be logged %M Method or function where the logging request was issued %n Newline (OS-independent) %p Priority of the logging event %P pid of the current process %r Number of milliseconds elapsed from program start to logging event %x The topmost NDC (see below) %X{key} The entry 'key' of the MDC (see below) %% A literal percent (%) sign
![Page 29: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/29.jpg)
Custom Placeholders
# Define a conversion specifier (cspec) in the config file:
log4perl.logger = INFO, Screen
log4perl.appender.Screen = Log::Dispatch::Screen
log4perl.appender.Screen.layout = PatternLayout
log4perl.appender.Screen.layout.ConversionPattern=%O: %F %L %m%n
log4perl.PatternLayout.cspec.O = sub { return "OS $^O" }
![Page 30: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/30.jpg)
Perl Code In Config File# Programmatically get the filename and layout
log4perl.logger = INFO, FileLog
log4perl.appender.FileLog = Log::Dispatch::File
log4perl.appender.FileLog.Filename = \
sub { getFileName(); }
log4perl.appender.FileLog.layout = \
sub { getLayout(); }
![Page 31: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/31.jpg)
Code in the Config File: Notes
● We can put any code into the config file● This code is run within the main namespace● Some might consider this a security risk
– This feature can be disabled with: $Log::Log4perl::ALLOW_CODE_IN_CONFIG_FILE = 0;
![Page 32: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/32.jpg)
Take a Break
Everyone take a break, and allow Patrick a few moments to catch up
![Page 33: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/33.jpg)
Putting Categories to UseGoing Beyond the System Defined Root Logger
● One of Log4perl's key features is categories– Enable extra logging for just one portion of your
application– Remainder of application produces typical output
● Category name: often the name of the current package / class
● You've seen the default, root category– To use your own, pass a parameter into get_logger()
$logger = get_logger( $category_name );
![Page 34: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/34.jpg)
Using Categories: Config File
# This is the root category / logger
log4perl.logger = WARN, Screen
# Create a new category like so:
log4perl.logger.CategoryName = DEBUG, Screen
![Page 35: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/35.jpg)
Using Categories: Class ExampleSkywalker Class Hierarchy
![Page 36: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/36.jpg)
Log Using Multiple Categories● Leia knows what she wants● Vader is set in his ways● We can put these two at a normal log level of “warn”● Luke has issues● He should be put at a log level of “debug”
![Page 37: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/37.jpg)
Multiple Categories ExampleTwo categories: Log Skywalkers to Screen
log4perl.logger.Skywalker = WARN, Screen
log4perl.logger.Skywalker.Luke = DEBUG, Screen
log4perl.appender.Screen = Log::Dispatch::Screen
log4perl.appender.Screen.layout = SimpleLayout
![Page 38: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/38.jpg)
Multiple Categories ExampleLog base class to File, sub class to Screen and File
log4perl.logger.Skywalker = WARN, FileLog
log4perl.logger.Skywalker.Luke = DEBUG, Screen
log4perl.appender.FileLog = Log::Dispatch::File
log4perl.appender.FileLog.layout = SimpleLayout
log4perl.appender.FileLog.Filename = myfile.log
log4perl.appender.Screen = Log::Dispatch::Screen
log4perl.appender.Screen.layout = SimpleLayout
![Page 39: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/39.jpg)
Tell Log4perl Your CategoryPass in Your Class Name
● In package Skywalker: my $logger = get_logger( 'Skywalker' );
● In package Skywalker::Leia: my $logger = get_logger( 'Skywalker::Leia' );
● In package Skywalker::Luke: my $logger =
get_logger( 'Skywalker::Luke' );
● Or just... my $logger = get_logger( __PACKAGE__ );
![Page 40: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/40.jpg)
Now, Pay Attention!
![Page 41: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/41.jpg)
Important Logging Behavior
● Once a logger decides to log a message, it does a few things
● The message is first logged using each appender attached to that logger
● Then, the message is unconditionally logged using every appender attached to the logger's parents
![Page 42: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/42.jpg)
Important Logging BehaviorExample Config File
log4perl.logger = ERROR, Syslog
log4perl.logger.Skywalker.Luke = DEBUG, Screen
log4perl.appender.Syslog = Log::Dispatch::Syslog
log4perl.appender.Syslog.layout = SimpleLayout
log4perl.appender.Screen = Log::Dispatch::Screen
log4perl.appender.Screen.layout = SimpleLayout
![Page 43: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/43.jpg)
Important Logging Behavior
ERROR(inherited)
Log::Dispatch::Syslog
Skywalker
Skywalker::Luke Skywalker::Leia
ERROR(inherited)
DEBUG
Log::Dispatch::Screen
root logger
ERROR
![Page 44: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/44.jpg)
What This Means
Lets take a look at how logging will work throughout the hierarchy
![Page 45: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/45.jpg)
Logging Behavior: root logger Category root logger (when no category is defined) Properties Defines level: ERROR, location: Syslog
Code $logger->error( $light_saber );
Result Logs $light_saber to a syslog
![Page 46: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/46.jpg)
Logging Behavior:Skywalker, Skywalker::Leia
Category Skywalker and Skywalker::Leia Properties Inherits ERROR and Syslog from root logger
Code $logger->error( $light_saber );
Result Logs $light_saber to syslog
![Page 47: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/47.jpg)
Logging Behavior: Skywalker::Luke
Category Skywalker::Luke
Properties Defines level: DEBUG, location: Screen
Code $logger->error( $light_saber );
Result Logs $light_saber to the screen Logs $light_saber to syslog
![Page 48: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/48.jpg)
Logging Behavior: Skywalker::Luke
Category Skywalker::Luke
Properties Defines level: DEBUG, location: Screen
Code $logger->debug( $light_saber );
Result (even though parents are at ERROR) Logs $light_saber to the screen Logs $light_saber to syslog
![Page 49: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/49.jpg)
Logging Behavior
● Might be unnecessarily duplicating the logs– Luke's debug messages all going to syslog
● Take advantage of Log4perl!– Continue to log all debugging messages to the screen– Be more picky about what gets logged to syslog
● Should all of Skywalker::Luke's debugging messages be in our system logs?
– Remember, Luke has a lot of issues
![Page 50: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/50.jpg)
Preventing Duplicate Logs
● If this behavior isn't what you want, change it:– Set the additivity of a category to zero
● Prevents messages from bubbling up● Do this to the Skywalker::Luke category
– Set the threshold of an appender to some log level● Defines a minimum log level for oncoming messages● Do this to the root or parent category● Can also set a system-wide default threshold
![Page 51: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/51.jpg)
Setting AdditivityPrevent The Message From Bubbling Uplog4perl.logger = ERROR, Syslog
log4perl.logger.Skywalker.Luke = ERROR, Screen
log4perl.additivity.Skywalker.Luke = 0
log4perl.appender.Syslog = Log::Dispatch::Syslog
log4perl.appender.Syslog.layout = SimpleLayout
log4perl.appender.Screen = Log::Dispatch::Screen
log4perl.appender.Screen.layout = SimpleLayout
![Page 52: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/52.jpg)
Setting a ThresholdDefine minimum log level of ERRORlog4perl.logger = ERROR, Syslog
log4perl.logger.Skywalker.Luke = DEBUG, Screen
log4perl.appender.Syslog = Log::Dispatch::Syslog
log4perl.appender.Syslog.layout = SimpleLayout
log4perl.appender.Syslog.Threshold = ERROR
log4perl.appender.Screen = Log::Dispatch::Screen
log4perl.appender.Screen.layout = SimpleLayout
![Page 53: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/53.jpg)
One Last Look
● If a logger decides to fire, it sends the message to all of it's appenders
● The logger then has the message bubble up the hierarchy to hit all the other appenders on the way up
![Page 54: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/54.jpg)
Important Logging Behavior
This behavior effects our earlier examples!
![Page 55: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/55.jpg)
Preventing Duplicate LogsTwo categories: Log Skywalkers to Screen
# Does this previous example do what you think?
log4perl.logger.Skywalker = WARN, Screen
log4perl.logger.Skywalker.Luke = DEBUG, Screen
log4perl.appender.Screen = Log::Dispatch::Screen
log4perl.appender.Screen.layout = SimpleLayout
![Page 56: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/56.jpg)
Preventing Duplicate LogsUse Additivity To Your Advantage
log4perl.logger.Skywalker = WARN, Screen
log4perl.logger.Skywalker.Luke = DEBUG, Screen
log4perl.additivity.Skywalker.Luke = 0
log4perl.appender.Screen = Log::Dispatch::Screen
log4perl.appender.Screen.layout = SimpleLayout
![Page 57: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/57.jpg)
Preventing Duplicate Logs: FiltersYoda Filter: Do or do not, there is no “try”
log4perl.logger.Skywalker.Luke = DEBUG, Screen
log4perl.appender.Screen = Log::Dispatch::Screen
log4perl.appender.Screen.layout = SimpleLayout
log4perl.appender.Screen.filter = MyFilter
log4perl.filter.MyFilter = sub { /try/i }
log4perl.filter.MyFilter.AcceptOnMatch = false
![Page 58: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/58.jpg)
this door 0wnz j00
![Page 59: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/59.jpg)
Performance Penalties
● Logging has a (small) price tag– Decision to log is made at runtime
● Calls are optimized to run as fast as possible● There are still things you can do to help
![Page 60: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/60.jpg)
Bad Performance Example
# Current Log Level: WARN# (doesn't actually log)
use Data::Dumper;$logger->debug( “Contents: ”, Dumper( %config ));
![Page 61: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/61.jpg)
Optimizing Performance: Example 1
# Pass in a subroutine reference
$logger->debug( “Contents: ”, sub { use Data::Dumper; Dumper( %config ) });
![Page 62: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/62.jpg)
Optimizing Performance: Example 2
# Is it necessary to pass any parameters at all?
if ( $logger->is_debug ) { $logger->debug( “Array Contents: ”, @big_array );}
![Page 63: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/63.jpg)
Log4perl
● Log4perl has a boatload of features– Different log levels– Multiple logging destinations– Multiple categories
● There's more!
![Page 64: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/64.jpg)
Resources● Log4perl Homepage
http://log4perl.sourceforge.net
● Log4perl Documentation
http://log4perl.sourceforge.net/releases/LogLog4perl/docs/html/Log/Log4perl.htm
● Perl.com Article: Retire Your Debugger
http://www.perl.com/pub/a/2002/09/11/log4perl.html
● Most Recent Version of this Presentation
http://openthought.org
![Page 65: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/65.jpg)
Thank You
![Page 66: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/66.jpg)
More Cool Stuff(You've reached the bonus slides!)
![Page 67: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/67.jpg)
Automatically Rotate Logs
# Rotate logs daily, keep no more than 5 files log4perl.logger = WARN, Logfile log4perl.appender.Logfile = Log::Dispatch::FileRotate log4perl.appender.Logfile.filename = /var/log/log4perl.log log4perl.appender.Logfile.max = 5 log4perl.appender.Logfile.DatePattern = yyyy-MM-dd log4perl.appender.Logfile.TZ = EST log4perl.appender.Logfile.layout = SimpleLayout
![Page 68: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/68.jpg)
Reloading The Config
# To load the config, we originally wrote:
Log::Log4perl::init( “config.conf” );
# We can also check the config at regular intervals:
Log::Log4perl::init_and_watch( “config.conf”, 60 );
![Page 69: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/69.jpg)
Remote Config
# We can also use:
my $config = “http://openthought.org/config.pl”;
Log::Log4perl::init( $config );
# (this doesn't work with init_and_watch... yet)
![Page 70: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/70.jpg)
Decisions Based on Log LevelApplication Which Sends Email
my $email_address;
if ( $logger->is_debug ) { $email_address = “test_account”;}else { $email_address = “real_account”;}
send_email( $email_address );
![Page 71: Stop Being A Caveman! use Log::Log4perl;](https://reader035.vdocuments.us/reader035/viewer/2022062315/56815a80550346895dc7e963/html5/thumbnails/71.jpg)
More Decisions Based On Log LevelDatabase Application
if ( $logger->is_debug ) { $logger->debug( dumper(%data) ); return; # Don't even touch the database}elsif ( $logger->is_info ) { $database = “Test”;}else { $database = “Production”}
$self->insert_into_database( %data );