3

I'm reading up on Log4perl and want to try and use it for simple log management of my Perl scripts running on a Linux box. I've also read up on newsyslog and logrotate but want to use Log4perl if at all possible.

I'm trying to configure the /etc/log4perl.conf file so that it:

  • Defines a widget logger (INFO level) that will write all output to /opt/myapp/logs/myapp-<datetime>.log, where <datetime> is a date/time formatted string like 2012-12-20
  • This myapp-<datetime>.log file needs to be rotated daily (preferably at midnight), where the old file is deleted, and a new file is created with <datetime> + 1. For instance, myapp-2012-12-20.log would be replaced with myapp-2012-12-21.log, etc.

Here's my best attempt which I believe is close, but is still missing some configuration:

#####/etc/log4perl.conf############################################################
log4perl.logger.widget                      = INFO, MyAppLogAppender

log4perl.appender.MyAppLogAppender          = Log::Log4perl::Appender::File
log4perl.appender.MyAppLogAppender.filename = /opt/myapp/logs/myapp-???.log
log4perl.appender.MyAppLogAppender.layout   = Log::Log4perl::Layout::SimpleLayout
###################################################################################

How do I configure log4perl.appender.MyAppLogAppender to rotate once a day, delete the old file, and create a new one with a correct timestamp? Thanks in advance.

IAmYourFaja
  • 55,468
  • 181
  • 466
  • 756

2 Answers2

13

Here's an example of a Log::Log4perl configuration file, defining a daily rollover at midnight (date pattern yyyy-MM-dd), keeping a maximum of 5 saved logfiles around, at WARN level, and dumping everything to screen:

log4perl.logger                         = TRACE, Screen, Logfile

log4perl.appender.Logfile               = Log::Dispatch::FileRotate
log4perl.appender.Logfile.Threshold     = WARN
log4perl.appender.Logfile.filename      = test.log
log4perl.appender.Logfile.max           = 5
log4perl.appender.Logfile.DatePattern   = yyyy-MM-dd
log4perl.appender.Logfile.TZ            = PST
log4perl.appender.Logfile.layout        = Log::Log4perl::Layout::PatternLayout 
log4perl.appender.Logfile.layout.ConversionPattern = %d %m %n

log4perl.appender.Screen                = Log::Log4perl::Appender::Screen
log4perl.appender.Screen.stderr         = 0
log4perl.appender.Screen.utf8           = 1
log4perl.appender.Screen.layout         = Log::Log4perl::Layout::PatternLayout::Multiline
log4perl.appender.Screen.layout.ConversionPattern = [%p] %m %n

(reference: https://metacpan.org/module/Log::Log4perl::FAQ#How-can-I-roll-over-my-logfiles-automatically-at-midnight-)

creaktive
  • 5,193
  • 2
  • 18
  • 32
  • Awesome @creaktive (+1) - one more thing: what's the significance of the "\" after `log4perl.appender.Logfile.layout`? Can I remove it and just place the value beneath (`Log::Log4perl::Layout::PatternLayout`) on the same line? Thanks again! – IAmYourFaja Dec 18 '12 at 17:36
  • Also, I assume that *any* Perl script using `Log4perl` can then use this `widget` logger? – IAmYourFaja Dec 18 '12 at 17:38
  • Sorry, I promise this is the last followup: it looks like you're configuring the `WARN` level to use the `LogFile` appender. Is there a way to attach a logger to an appender for all log levels (WARN or otherwise)? Thanks again!! – IAmYourFaja Dec 18 '12 at 17:42
  • 1
    @HeineyBehinds: updated the example so it logs WARN messages to rotating logfile and prints everything on screen (TRACE is the most verbose level). The `\` character was line break marker, as in shell. Not necessary, at all :) – creaktive Dec 18 '12 at 17:49
  • Hmmm... I really *hate* to ask this because you've been so helpful so far (I wish I could upvote you more!) but what happens if I have other Perl scripts that want to log to other files besides just `test.log`? Once I can see the relationship of loggers, appenders and log files, I think all the lightbulbs will turn on! Thanks again so much for all the help! – IAmYourFaja Dec 18 '12 at 17:53
  • No problem, @HeineyBehinds! Unfortunately, I've never used the same `Log4perl.conf` to route messages to different files. But, AFAIK, that's what [Log4perl categories](https://metacpan.org/module/Log::Log4perl#Categories) are all about. – creaktive Dec 18 '12 at 18:07
  • Figured it out - you just list different logger via `log4perl.logger.` where `` is the name of your logger. You associate a log level and an appender with each logger as your example shows. Then you just add a configuration for each appender, and on each configuration, you specify a different file name. Thanks again for all your help! – IAmYourFaja Dec 18 '12 at 18:26
0

There is a gotcha in Log::Dispatch::FileRotate, if your daily job is run later in the day (say 23:00) and takes 2h (so ends at about 01:00), the log rotation will never happens with a "day" pattern like :

log4perl.appender.Logfile.DatePattern   = yyyy-MM-dd

A simple workaround is to use an "hourly" pattern like this :

log4perl.appender.Logfile.DatePattern   = yyyy-MM-dd-HH

So when the next run starts at 23:00, the log file get rotated as more than one hour has passed.

cbueche
  • 51
  • 2