Skip to content

Commit

Permalink
Add frame information placeholders in Pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
atroxaper committed Apr 8, 2019
1 parent 39bb86d commit 9133358
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 5 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,16 @@ subpattern.
- `$dd` - day in 2 digits format;
- `$hh`, `$mm`, `$ss`, `$mss` - hours, minutes, seconds and milliseconds
- `$z` - timezone
- `%framefile` - for log caller frame file name. The same as `callframe().file`
in log call block;
- `%frameline` - for log caller frame file line. The same as `callframe().line`
at the same log call line;
- `%framename` - for log caller frame code name. The same as
`callframe().code.name` in log call block;

Note that using `%framefile`, `%frameline` or `%framename` in the pattern will
slow your program because it requires several `callframe` calls on each
resultative log call;

### Writer factory subroutines

Expand Down
23 changes: 20 additions & 3 deletions lib/LogP6/Context.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ has $!tname;
has @!ndc = [];
has %!mdc = %();
has %!sync = %();
has $!callframe;

submethod BUILD() {
$!thread = $*THREAD;
Expand Down Expand Up @@ -176,9 +177,25 @@ method sync-put($trait, $obj) {
%!sync{$trait} = $obj;
}

#|[Cleans all data values specified by logger (like date, msg, level and
#| exception). Normally the method is used by logger itself
#| Gets callframe of log caller level.
method callframe() {
return $_ with $!callframe;
# start with 3. it is much save and optimal
for 3..* -> $level {
with callframe($level) -> $frame {
next unless $frame.code.name
~~ any('trace', 'debug', 'info', 'warn', 'error');
# +1 to caller code and +1 to go from `with` block
$!callframe = callframe($level + 2);
last;
}
}
return $!callframe;
}

#|[Cleans all data values specified by logger (like date, msg, level,
#| exception and callframe). Normally the method is used by logger itself
#| after each logging.]
method clean() {
$!date = $!msg = $!x = $!level = DateTime;
$!callframe = $!date = $!msg = $!x = $!level = DateTime;
}
21 changes: 21 additions & 0 deletions lib/LogP6/WriterConf/Pattern.pm6
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,18 @@ class DateZone does PatternPart {
method show($d) { $d.timezone }
}

class FrameFile does PatternPart {
method show($context) { $context.callframe.file }
}

class FrameLine does PatternPart {
method show($context) { $context.callframe.line }
}

class FrameName does PatternPart {
method show($context) { $context.callframe.code.name }
}

my $lnames = [];
$lnames[trace.Int] = 'TRACE';
$lnames[debug.Int] = 'DEBUG';
Expand Down Expand Up @@ -189,6 +201,12 @@ grammar Grammar is export {
rule level-param:sym<warn> { 'WARN' '=' <word> }
rule level-param:sym<error> { 'ERROR' '=' <word> }
rule level-param:sym<length> { 'length' '=' <num> }
# %framefile - frame file path
token item:sym<framefile> { '%framefile' }
# %frameline - frame file line
token item:sym<frameline> { '%frameline' }
# %framename - frame code name
token item:sym<framename> { '%framename' }

token word { $<text>=<-[\s}]>+ }
token num { $<text>=\d+ }
Expand Down Expand Up @@ -254,4 +272,7 @@ class Actions is export {
method level-param:sym<warn>($/) { make warn.Int.Str => $<word>.Str }
method level-param:sym<error>($/) { make error.Int.Str => $<word>.Str }
method level-param:sym<length>($/) { make 'length' => $<num>.Str }
method item:sym<framefile>($/) { make FrameFile }
method item:sym<frameline>($/) { make FrameLine }
method item:sym<framename>($/) { make FrameName }
}
10 changes: 9 additions & 1 deletion t/00-grammar.t
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use LogP6::WriterConf::Pattern;
use LogP6::Context;
use IOString;

plan 10;
plan 11;

my LogP6::Context $context .= new;
$context.level-set($info);
Expand Down Expand Up @@ -62,4 +62,12 @@ is parse-process($level-line ~ '1}'), 'E', 'default level length 1';
is parse-process($level-line ~ '3}'), 'ERR', 'default level length 3';
is parse-process('%level{ERROR=warn}'), 'warn ', 'default level length';

# %frame*
sub info($frame) {
is parse-process('%framename %framefile %frameline').trim,
$frame.code.name ~ ' ' ~ $frame.file ~ ' ' ~ $frame.line, 'frames';
}
sub foo() { info(callframe) }
foo;

done-testing;
18 changes: 17 additions & 1 deletion t/00-logger.t
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use LogP6::LoggerPure;
use IOString;
use LogP6 :configure;

plan 6;
plan 7;

my ($h1, $h2, $h3) = (IOString.new xx 3).list;
sub clean-io() { $_.clean for ($h1, $h2, $h3) }
Expand Down Expand Up @@ -187,4 +187,20 @@ subtest {
does-ok $mute, LogP6::LoggerMute, 'create mute logger';
}, 'mute logger';

subtest {
plan 1;

cliche(:name<frame>, :matcher<frame>, grooves => (
writer(:pattern('%msg %framename %framefile %frameline'), :handle($h1)),
level($info)
));
my $frame = get-logger('frame');

$frame.info('line 1');
my $l1 = $h1.clean;
$frame.info('line 2');
my $l2 = $h1.clean;
isnt $l1, $l2, 'frames are different';
}, 'different frame';

done-testing;

0 comments on commit 9133358

Please sign in to comment.