From: Gordon M. <gm...@gm...> - 2003-06-03 15:33:33
|
I noticed that the Log4perl was pretty much a singleton pattern a while back, so my object's constructor looks like this: our %BE = ( logger => "", ConfigFile => "/etc/lb_lutab", # List of all BE objects ALL => [ ], ); # tri-natured: function, class method, or object method sub _classobj { my $objclass = shift || __PACKAGE__; my $class = ref($objclass) || $objclass; no strict "refs"; # to convert sym ref to real one return \%$class; } for my $datum (keys %{ _classobj() } ) { # turn off strict refs so that we can register a method # in the symbol table no strict "refs"; *$datum = sub { use strict "refs"; my $self = shift->_classobj(); $self->{$datum} = shift if @_; return $self->{$datum}; } } # Constructor sub new { my ($caller,%arg) = @_; my $caller_is_obj = ref($caller); my $class = $caller_is_obj || $caller; my ($logger); unless (BE->logger) { Log::Log4perl::init_and_watch('/usr/LBBE/bootdiskmanager/bin/log.conf',10); my $logger = Log::Log4perl->get_logger('BE'); BE->logger($logger); } $logger = Log::Log4perl->get_logger('BE'); my $instance = { _name => $arg{name} || # Name of this BE undef, ... Other members of the object ... _logger => undef, }; # Save a copy of BE->logger here so the reference to the logger can survive # for use inside DESTROY $instance->{_logger} = $logger; # Append this to the Class list of all BEs my ($all) = BE->ALL(); push @{$all}, $instance; BE->ALL($all); bless $instance, $class; } Note the following: If this is the first BE object in the system, then we have to explicitly create the logger (singleton) and tuck it away. I also put a reference to it in my object's instance, so all of my objects have individual references to the logger. Thus, the logger should stay around until the very last BE object calls it's DESTROY method. This doesn't seem to be the case, as when the last BE object enters DESTROY, $self->{_logger} has the value "undef". Not good. On Tue, 2003-06-03 at 11:47, Mike Schilli wrote: > On Tue, 3 Jun 2003, Gordon Marler wrote: > > > I've been using Log::Log4perl for several months now, with great success > > - great job! > > Thanks! :) > > > I've designed my Perl object to contain a reference to a Log::Log4perl > > object, and this seems to work for all methods in the object except > > DESTROY. Here's an example of what my DESTROY method looks like (the > > name of my object and it's package is "BE"): > > > > sub DESTROY { > > my ($self) = @_; > > my ($logger) = Log::Log4perl->get_logger("BE"); > > $logger->info("Entering DESTROY method for " . __PACKAGE__ . "\n"); > > } > > Hmm ... I'm not quite sure how you're storing references to Log::Logp4erl > objects in your object -- there's really no "Log::Log4perl objects". > > Typically, you call > > use Log::Log4perl; > Log::Log4perl->init(...); > > at the beginning of your program and then, within your class code, > you use > > package MyClass; > > use Log::Log4perl; > > sub method { > my ($logger) = Log::Log4perl->get_logger("BE"); > $logger->info("message"); > } > > There's really no "Log::Log4perl objects" -- instead, Log4perl uses > a singleton mechanism for its loggers. > > You didn't submit your class' constructor method, so I can only speculate: > the problem might be related to storing this "Log::Log4perl reference". > Instead, just initialize Log::Log4perl once at the start of the main (!) > program and call the loggers in your custom class like shown above, that > should fix the problem. > > Hope that helps! > > -- Mike > > Mike Schilli > log...@pe... > http://perlmeister.com > http://log4perl.sourceforge.net -- Gordon Marler <gm...@gm...> |