I have been using Log4perl for quite some time in a large project of mine.   
There are about 20 perl programs, all of which should always be running.  I'm 
using init_and_watch to allow users to update the configuration file; i.e:

    # Init Log4perl
    Log::Log4perl->init_and_watch("../ANSlog.conf",'HUP');
    $logger = get_logger("category")

After updating the config file, I use a script to send SIGHUP to all the 
currently running processes (simple "kill -HUP <PID>").

Most of the time (I'd guess ~80%), this works fine.  When it doesn't work, I 
get the following error on STDERR (even though I've wrapped STDERR with a 
"Trapper" as described in the FAQ):

        Can't call method "log" on an undefined value at 
/opt/ActivePerl-5.8/lib/site_perl/5.8.7/Log/Log4perl/Appender.pm line 189.

And the perl program dies.

I'm using ActivePerl 5.8.7 due to an restriction from a third-party Perl 
module; I can't update perl itself or use another perl distribution.

I'm using Log4perl 1.20.  The system is CentOS 4.2.

My log4perl configuration is rather large, but it is below.  I tried removing 
the Database appender from the configuration (i.e. leaving only the File 
appender "Logfile"), but it still happens without it.


#-----------------------------------------------------------------------
##
## Root logger threshold and appenders
##
log4perl.rootLogger = DEBUG

##
## Categories for each ANS module
##
log4perl.category.ANS           = INFO, Logfile
log4perl.category.ANS.asistlog  = INFO, Database
log4perl.category.ANS.email     = INFO, Database
log4perl.category.ANS.event     = INFO, Database
log4perl.category.ANS.event.main = INFO
log4perl.category.ANS.event.readconfig = INFO
log4perl.category.ANS.event.forkchildren = INFO
log4perl.category.ANS.event.refork = INFO
log4perl.category.ANS.event.housekeeping = INFO
log4perl.category.ANS.event.connopen = INFO
log4perl.category.ANS.event.connclose = INFO
log4perl.category.ANS.event.connquery = WARN
log4perl.category.ANS.event.repeat = INFO
log4perl.category.ANS.event.GetFieldValue = INFO
log4perl.category.ANS.heartbeat = INFO, Database
log4perl.category.ANS.htmlizer  = INFO, Database
# This category is special -- no inheritance from ANS category,
# so messages only go to the alert database
log4perl.category.htmlizer.sql  = INFO, AlertDatabase
log4perl.category.asistlog.sql  = INFO, ASISTDatabase, DMZDatabase
#
log4perl.category.ANS.component = INFO, Database
log4perl.category.ANS.satwatch                  = INFO, Database
log4perl.category.ANS.satwatch.parse            = INFO
# ****** NOTE!  DEBUG output for Catalog iS HUUUUUGE ********
log4perl.category.ANS.satwatch.catalog          = INFO
log4perl.category.ANS.satwatch.filter           = INFO
log4perl.category.ANS.satwatch.typehandler      = INFO
log4perl.category.ANS.satwatch.grouphandler     = INFO
log4perl.category.ANS.satwatch.registerhandler  = INFO
log4perl.category.ANS.satwatch.filterhandler    = INFO
log4perl.category.ANS.satwatch.eventhandler     = INFO
log4perl.category.ANS.satwatch.regexphandler    = INFO
log4perl.category.ANS.satwatch.occurshandler    = INFO
log4perl.category.ANS.satwatch.intervalhandler  = INFO
log4perl.category.ANS.satwatch.ignore           = INFO
log4perl.category.ANS.satwatch.watch            = INFO
log4perl.category.ANS.satwatch.clear            = INFO
log4perl.category.ANS.satwatch.flush            = INFO
log4perl.category.ANS.satwatch.flushnow         = INFO
log4perl.category.ANS.satwatch.cleaner          = INFO
log4perl.category.ANS.satwatch.cleanup          = INFO
log4perl.category.ANS.source    = INFO, Database
log4perl.category.ANS.target    = INFO, SyncDatabase
log4perl.category.ANS.trapper   = INFO, Database

##
## Logfile appender
##
log4perl.appender.Logfile       = Log::Log4perl::Appender::File
log4perl.appender.Logfile.filename = \
        sub { if ($ENV{'ANSROOT'}) { \
                return "$ENV{'ANSROOT'}/ANSlog.txt" \
        } else { \
                die "ENV{ANSROOT} not defined!" \
        } }
log4perl.appender.Logfile.mode  = append
log4perl.appender.Logfile.recreate = 1
log4perl.appender.Logfile.recreate_check_signal = USR1
#log4perl.appender.Logfile.recreate_check_interval = 5
log4perl.appender.Logfile.layout= Log::Log4perl::Layout::PatternLayout
log4perl.appender.Logfile.layout.ConversionPattern = \
         %d{yyyy-DDD/HH:mm:ss} %-5p %F{2} %P %m%n

##
## Screen Appender
##
log4perl.appender.Screen         = Log::Log4perl::Appender::Screen
log4perl.appender.Screen.stderr  = 0
log4perl.appender.Screen.layout=Log::Log4perl::Layout::PatternLayout
log4perl.appender.Screen.layout.ConversionPattern = \
        %d{yyyy-DDD/HH:mm:ss} %-5p %F{2} %P %m%n

##
## Database Appender
##
# NOTE: DBI_Buffer uses all options from Log::Log4perl::Appender::DBI
log4perl.appender.Database              = Log::Log4perl::Appender::DBI
log4perl.appender.Database.usePreparedStmt = 1
log4perl.appender.Database.layout       = Log::Log4perl::Layout::NoopLayout
log4perl.appender.Database.datasource   = 
DBI:mysql:database=ansdb:host=localhost;mysql_auto_reconnect=1
log4perl.appender.Database.username     = foo
log4perl.appender.Database.password     = bar
log4perl.appender.Database.logbuffer    = 4000
log4perl.appender.Database.errorappender= Logfile
log4perl.appender.Database.errorstodatabase= 1
log4perl.appender.Database.sql          = \
        insert into anslog              \
        (date, loglevel, filename, hostname, PID, message) \
        values (?,?,?,?,?,?)
log4perl.appender.Database.params.1   = %d{yyyy-DDD/HH:mm:ss}
log4perl.appender.Database.params.2   = %p
log4perl.appender.Database.params.3   = %F{2}
log4perl.appender.Database.params.4   = %H
log4perl.appender.Database.params.5   = %P
log4perl.appender.Database.params.6   = %m

##
## Alert Database Appender
##
# NOTE: DBI_Buffer uses all options from Log::Log4perl::Appender::DBI
log4perl.appender.AlertDatabase                 = DBI_Buffer
log4perl.appender.AlertDatabase.layout          = 
Log::Log4perl::Layout::NoopLayout
log4perl.appender.AlertDatabase.warp_message    = 0
log4perl.appender.AlertDatabase.datasource      = 
DBI:mysql:database=ansdb:host=localhost;mysql_auto_reconnect=1
log4perl.appender.AlertDatabase.username        = foo
log4perl.appender.AlertDatabase.password        = bar
log4perl.appender.AlertDatabase.logbuffer       = 4000
log4perl.appender.AlertDatabase.errorappender   = Logfile
log4perl.appender.AlertDatabase.errorstodatabase= 0
log4perl.appender.AlertDatabase.sql     = \
        insert into alerts              \
        (date, loglevel, filename, hostname, PID, \
                timestamp, emailgroup, message) \
        values (?,?,?,?,?,?,?,?)
log4perl.appender.AlertDatabase.params.1   = %d{yyyy-DDD/HH:mm:ss}
log4perl.appender.AlertDatabase.params.2   = %p
log4perl.appender.AlertDatabase.params.3   = %F{2}
log4perl.appender.AlertDatabase.params.4   = %H
log4perl.appender.AlertDatabase.params.5   = %P
                                      #6 is timestamp from log call
                                      #7 is emailgroup from log call
                                      #8 is message from log call

##
## Define a filter routine to remove SDO Commands
## from the event log
##
log4perl.filter.CommandFilter   = sub { \
        !/CMH-I:CMD/ \
        };

##
## ASIST Database Appender
##
# NOTE: DBI_Buffer uses all options from Log::Log4perl::Appender::DBI
log4perl.appender.ASISTDatabase                 = DBI_Buffer
log4perl.appender.ASISTDatabase.Filter          = CommandFilter
log4perl.appender.ASISTDatabase.layout          = 
Log::Log4perl::Layout::NoopLayout
log4perl.appender.ASISTDatabase.warp_message    = 0
log4perl.appender.ASISTDatabase.datasource      = 
DBI:mysql:database=asistdb:host=localhost;mysql_auto_reconnect=1
log4perl.appender.ASISTDatabase.username        = foo
log4perl.appender.ASISTDatabase.password        = bar
log4perl.appender.ASISTDatabase.logbuffer       = 4000
log4perl.appender.ASISTDatabase.errorappender   = Logfile
log4perl.appender.ASISTDatabase.errorstodatabase = 0
log4perl.appender.ASISTDatabase.sql     = \
        insert into events              \
        (date, loglevel, filename, hostname, PID, \
                asisthost, timestamp, class, message) \
        values (?,?,?,?,?,?,?,?,?)
log4perl.appender.ASISTDatabase.params.1   = %d{yyyy-DDD/HH:mm:ss}
log4perl.appender.ASISTDatabase.params.2   = %p
log4perl.appender.ASISTDatabase.params.3   = %F{2}
log4perl.appender.ASISTDatabase.params.4   = %H
log4perl.appender.ASISTDatabase.params.5   = %P
                                      #6 is asisthost from log call
                                      #7 is timestamp from log call
                                      #8 is class from log call
                                      #9 is message from log call
##
##
## DMZ Database Appender
##
# NOTE: DBI_Buffer uses all options from Log::Log4perl::Appender::DBI
log4perl.appender.DMZDatabase                   = DBI_Buffer
log4perl.appender.DMZDatabase.Filter            = CommandFilter
log4perl.appender.DMZDatabase.layout            = 
Log::Log4perl::Layout::NoopLayout
log4perl.appender.DMZDatabase.warp_message      = 0
log4perl.appender.DMZDatabase.datasource        = 
DBI:mysql:database=asistdb:host=remotesys;mysql_auto_reconnect=1
log4perl.appender.DMZDatabase.username          = foo
log4perl.appender.DMZDatabase.password          = bar
log4perl.appender.DMZDatabase.logbuffer         = 4000
log4perl.appender.DMZDatabase.errorappender     = Logfile
log4perl.appender.DMZDatabase.errorstodatabase  = 0
log4perl.appender.DMZDatabase.sql       = \
        insert into events              \
        (date, loglevel, filename, hostname, PID, \
                asisthost, timestamp, class, message) \
        values (?,?,?,?,?,?,?,?,?)
log4perl.appender.DMZDatabase.params.1   = %d{yyyy-DDD/HH:mm:ss}
log4perl.appender.DMZDatabase.params.2   = %p
log4perl.appender.DMZDatabase.params.3   = %F{2}
log4perl.appender.DMZDatabase.params.4   = %H
log4perl.appender.DMZDatabase.params.5   = %P
                                      #6 is asisthost from log call
                                      #7 is timestamp from log call
                                      #8 is class from log call
                                      #9 is message from log call

##
## DB Syncronizer
##
# Technically, only the forked children for event.pl and target.pl
# need to be Sync'd, but we are syncing all of the modules
# If performance becomes an issue, try syncing only event.pl and target.pl
log4perl.appender.SyncDatabase            = 
Log::Log4perl::Appender::Synchronized
log4perl.appender.SyncDatabase.appender   = Database
# Random semaphore key; otherwise they clobber each other
log4perl.appender.SyncDatabase.key        = sub { int(rand(10000)); }


-- 
Thanks,
Rob

------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
log4perl-devel mailing list
log4perl-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/log4perl-devel

Reply via email to