use strict; use warnings; use Class::Date qw(now); # global tokens my %TOKE = ( Z => { # my title val => 'Data::Logger', prm => 1 }, A => { # message val => 'Thanks for using Data::Logger!', prm => 1 }, F => { # users current "function title" val => 'main', prm => 0 }, S => { # users script name, doesn't need to be anything special val => 'testz0rz.pl', #basename($main::0),#'super cool script.pl',#'fake name', prm => 1 }, L => { # log level: info, debug, warning, fatal val => 'INFO', prm => 1 }, E => { # $! from the users script, or custom error message val => undef, prm => 1 }, Y => { val => sub { @{[ split(/(?:\s|:|-)+/,now) ]}[0] }, prm => 1 }, M => { val => sub { @{[ split(/(?:\s|:|-)+/,now) ]}[1] }, prm => 1 }, D => { val => sub { @{[ split(/(?:\s|:|-)+/,now) ]}[2] }, prm => 1 }, h => { val => sub { @{[ split(/(?:\s|:|-)+/,now) ]}[3] }, prm => 1 }, m => { val => sub { @{[ split(/(?:\s|:|-)+/,now) ]}[4] }, prm => 1 }, s => { val => sub { @{[ split(/(?:\s|:|-)+/,now) ]}[5] }, prm => 1 } ); # Y, M, D, h, m, and s are ugly but work print _decode('\\{%Y-%M-%D\\}[%h:%m:%s]{ %F:} (%L) - %A{ \\{%E\\}}'); # the decoder sub _decode { my $tdc = shift; while ($tdc =~ s/(?{prm} and defined $TOKE{$tok}->{val}) { if (ref $TOKE{$tok}->{val} eq 'CODE') { $blk =~ s/\%$tok/&{$TOKE{$tok}->{val}}/e; } else { $blk =~ s/\%$tok/$TOKE{$tok}->{val}/; } $tdc =~ s/\\CURRENT\//$blk/; } } $tdc =~ s/\\CURRENT\///go; # /g just for safety } while ($tdc =~ /\%(\S)/o) { my $tok = $1; if ($TOKE{$tok}->{prm}) { if (defined $TOKE{$tok}->{val}) { if (ref $TOKE{$tok}->{val} eq 'CODE') { $tdc =~ s/\%$tok/&{$TOKE{$tok}->{val}}/eg; } else { $tdc =~ s/\%$tok/$TOKE{$tok}->{val}/g; } } else { $tdc =~ s/\%$tok/\?/g; # tag is supposed to be defined } } else { $tdc =~ s/\%$tok//g; # tag isn't active } } $tdc =~ s/\\\{/\{/go; # would s/\\(\{|\}/$1/g; be faster? $tdc =~ s/\\\}/\}/go; # return $tdc; }