I have tried the writing to the file handle before in the DESTROY. However the IO::File object seems to go out of scope or has its DESTROY called before I am able to write to it in my Log objects DESTROY. Here is my code below. I create an object of this class in a script and let it fall off the end of the script to test if the Finished line is written during the DESTROY however it never gets written unless I explicitly call DESTROY
package MyLog
$VERSION = '0.0.1';
use strict;
use Carp qw(croak longmess);
use English;
use File::Path;
use File::Basename;
use IO::File;
use MyModules::Date::Holiday qw(today);
our $home;
our $username;
BEGIN { $username = (getpwuid($<))[0]; $home = $ENV{HOME} ? $ENV{HOME}
+ : "/home/users/$username"; }
{
my $log;
my $fh;
# {{{ new
sub new {
# singleton pattern for the logger
if($log) {
return $log;
} else {
my $class = shift;
my $self = {};
$log = bless($self, $class);
$self->_init(@_);
return $self->new();
}
}
# }}}
# {{{ _init intialize all the inputs given to the constructor
sub _init {
my $self = shift;
if(@_) {
my %args = %{shift @_};
@$self{keys %args} = values %args;
}
if(!$self->{logfile}) {
my $basedir = $home . '/log/' . today() . '/';
# if for some reason we do not have the dated log directory cr
+eated, create one
unless(-d $basedir) {
eval {
mkpath($basedir);
};
if($@) {
croak("$0 cannot create log directory $basedir : $@");
}
}
my ($f,$d,$s) = fileparse($0);
$self->{'logfile'} = $basedir . $f . '.log';
}
if(!$self->{fh}) {
my $logfile = $self->{logfile};
if(-e $logfile) {
# if the logfile is there then append to it
$fh = new IO::File;
if($fh->open(">> $logfile")) {
$self->{'fh'} = $fh;
} else {
croak("$0 Could not open logfile $logfile for appendin
+g $OS_ERROR\n");
}
} else {
# create a new logfile if one does not exist
$fh = new IO::File;
if($fh->open("> $logfile")) {
$self->{'fh'} = $fh;
} else {
croak("$0 Could not create logfile $logfile $OS_ERROR\
+n");
}
}
}
print {$self->{'fh'}} $self->get_time() . " INFO | Started \n";
}
# }}}
# {{{ log($level,$msg)
sub log {
my $self = shift;
my $level = shift;
my $msg = shift;
my $fh = $self->{fh};
my $logentry = $self->get_time() . $level . ' | ' . "$msg";
# if it is an error, email it
if($level =~ /(ERROR|WARN)/i) {
if($self->{'to'}) {
croak($logentry,$self->{'to'});
} else {
croak($logentry);
}
}
print {$fh} "$logentry\n";
}
# }}}
# {{{ info($msg)
sub info {
my $self = shift;
my $msg = shift;
$self->log("INFO",$msg);
}
# }}}
# {{{ warn($msg)
sub warn {
my $self = shift;
my $msg = shift;
$self->log("WARN",$msg);
}
# }}}
# {{{ fatal($msg)
sub fatal {
my $self = shift;
my $msg = shift;
$self->log("ERROR",longmess() . " $msg");
$self->DESTROY();
die($msg);
}
# }}}
# {{{ get_time borrowed from Pavels LogFile.pm
sub get_time {
my ($sec, $min, $hour, $day, $mon, $year) = localtime();
my $date = sprintf "%4d.%02d.%02d %02d:%02d.%02d | ",
$year + 1900,
$mon + 1,
$day,
$hour,
$min,
$sec;
return $date;
}
# }}}
# {{{ log_file
sub log_file {
return shift->{'logfile'};
}
# }}}
# {{{ DESTROY
sub DESTROY {
my $self = shift;
if($fh && fileno $fh) {
print "Finish\n";
print {$fh} $self->get_time() . 'INFO | ' . "$0 Finished\n";
$fh->flush;
$fh->close;
}
undef $fh;
}
# }}}
1; # Magic true value required at end of module
__END__
|