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;


In reply to Re: execution log by mscudder
in thread execution log by yburge

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.