in reply to execution log
If you mean logging from within a perl script, I wrote the package below for operations logging. It could (should?) be objectified (so you can have more than one logstream per application instance). If need be, you could also integrate it with an external logging service, e.g., syslog (*nix) or the Windows Event Service. However, there are undoubtedly extant perl modules which offer this.
Again, this code is intended for logging operations and is probably not appropriate for debug tracing. For the latter purpose, I've written a separate package with more suitable usage and formatting conventions (indents (someday!), trace levels (ditto), no timestamps, etc.). As well, there must be other debug tracing packages out there.
Regards,
Michael
use Time::Local; # ============================================== # # global state-of-the-module variables # # ============================================== # my $_logstarted=0; my $LOG; undef $LOG; my @_logstack=(); # ============================================== # # log 'stack' management # # ---------------------------------------------- # # Enables inclusion in logged messages of the # # name of the subroutine logging a particular # # message for diagnostics and debugging. # # ---------------------------------------------- # # usage: # # logstack('push', <caller>) # # logstack('pop') # # logstack('clear') # # logstack() # # ---------------------------------------------- # # logstack('push', $caller), logstack('pop') # # and logstack() return the callstack as a # # string of colon-separated fields; # # logstack('clear') returns numeric 1. # # ---------------------------------------------- # # To work correctly, requires subroutines # # to call logstack('push', $callername) on # # entry and logstack('pop') on return # # ---------------------------------------------- # # EXPORTED # # ============================================== # # examples: # 16 Apr 2006 16:05:50 myfiles: process: catalog: found 35 file(s) # 02 Feb 2006 10:48:02 myfiles: process: archive: error moving todaysf +iles.html: No such file or directory sub logstack { return if !$_logstarted; my $op=@_ ? shift : ""; @_logstack=(), return 1 if ($op eq 'clear'); push @_logstack, @_ if $op eq 'push'; pop @_logstack if $op eq 'pop'; return join (': ', @_logstack); } # ============================================== # # logstart -- initializes log service # # ---------------------------------------------- # # usage: # # logstart( # # directory => $logdirectory, # # filename => $logfilename, # # caller => $callername, # # path => $logpath, # # error => \$errmsg) # # # # The logfile must be specified with either # # <logpath> or [<directory>, <filename>], # # with <logpath> used if both are passed. # # # # The logfile is the only required parameter. # # ---------------------------------------------- # # Returns numeric 1 or 0, respectively, # # on success or failure # # # # On error or failure, logstart() returns # # an error message via the optional error # # parameter. # # ---------------------------------------------- # # EXPORTED # # ============================================== # sub logstart { return if $_logstarted || (@_<2); my $logdir=""; my $logfile=""; my $msg=""; undef $msg; my $caller=""; my $logpath=""; my $error; undef $error; my %argh=(); # collect and validate function args while (@_) { my $key=shift; my $value=shift; $argh{$key}=$value; } $caller=$argh{caller} if exists($argh{caller}); $msg=$argh{message} if exists($argh{message}); $error=$argh{error} if exists($argh{error}); if (exists $argh{path}) { $logpath=$argh{path}; } elsif ((exists $argh{directory}) && (exists $argh{filename})) { $argh{directory}=~s/\\$//; $logdir=$argh{directory}; $logfile=$argh{filename}; $logpath=$logdir."\\".$logfile; } else { $$error="missing logfile directory and filename" if $error; return 0; } # create log subdirectory if necessary if (!(-e $logdir) && !(mkdir $logdir)) { $$error="couldn't create log directory ".$logdir.": ".$! if $error; return 0; } # open logfile if (!(open($LOG, "+>>:utf8", $logpath))) { $$error="error opening logfile ".$logpath.": ".$! if $error; return 0; } $LOG->autoflush(1); print $LOG "\n"; $_logstarted=1; logstack('clear'); logstack('push', $caller) if $caller; logstack('push', 'logstart'); logmsg($msg) if $msg; logstack('pop'); logstack('pop') if $caller; return 1; } # ============================================== # # logstop -- shuts down log service # # ---------------------------------------------- # # usage: # # logstop() # # logstop($lastwords) # # # # The optional parameter $lastwords is a # # message to log before closing the logfile # # ---------------------------------------------- # # EXPORTED # # ============================================== # sub logstop { return if !$_logstarted; my $msg=shift; $msg and logmsg($msg); close $LOG; undef $LOG; $_logstarted=0; logstack('clear'); return; } # ============================================== # # logstr -- composes formatted string of form # # <date & time><TAB><callstack><TAB><msg> where # # date & time is of form # # <dd mmm yyyy> <MM>:<hh>:<ss> # # ---------------------------------------------- # # usage: # # logstr() # # logstr($msg) # # ---------------------------------------------- # # logstr() with no parameters returns # # a formatted timestamp only # # ---------------------------------------------- # # EXPORTED # # ============================================== # sub logstr { my $msg=shift; $msg=$msg?$msg:""; my ($sec, $min, $hour, $day, $month, $year, $weekday, $yday, $dst)=localtime(time); $year+=1900; my $timestamp=sprintf("%02d", $day)." ".$mmm[$month]." ". $year." ".sprintf("%02d", $hour).":".sprintf("%02d", $min). ":".sprintf("%02d", $sec); $msg=$timestamp."\t".join (': ', @_logstack).": ".$msg; return $msg } # ============================================== # # logmsg -- writes formatted string of form # # <date & time><TAB><callstack><TAB><msg> # # to the logfile specified when the log # # service was started with logstart() # # # # The content of <callstack> is # # managed using logstack() # # ---------------------------------------------- # # usage: # # logmsg($msg) # # ---------------------------------------------- # # Does nothing if $msg is missing or the log # # service wasn't previously started with # # logstart() # # ---------------------------------------------- # # EXPORTED # # ============================================== # sub logmsg { return if !$_logstarted || !(defined $LOG) || !@_; my $msg=logstr(shift()); print $LOG $msg."\n"; # print $msg."\n"; # optionally print duplicate message to STDOUT return $msg; }
keywords: log;logging;event;events;syslog;event logging;execution log;execution logging;event log; audit trail;log service;logging service;event service;
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: execution log
by yburge (Acolyte) on May 08, 2006 at 21:09 UTC | |
by mscudder (Initiate) on May 09, 2006 at 18:24 UTC | |
by yburge (Acolyte) on May 09, 2006 at 20:31 UTC | |
by mscudder (Initiate) on May 12, 2006 at 03:06 UTC |