From 9b2294c323dda7375f04fa94ae071537915970bd Mon Sep 17 00:00:00 2001 From: Mikko Koivunalho Date: Wed, 3 May 2023 22:55:54 +0200 Subject: [PATCH 1/7] Add support for hooks User can define a function to be called at a specific time. At the moment, there is only one hook: build_context. It is called right before passing the message and structured data to the Adapter. The hook makes using the context easier. Instead of defining the context everytime when you call a logging function, e.g. `$log->debugf()`, you can use the hook to define repeating information, like file name and line or timestamp. Because the hooks support several hooked sub routines, you can add more context temporarily when you need it. User can define the hooks either when `use`ing Log::Any or at any point afterwards. There can be several subroutines for each hook. They are executed in the order the hooks are added. Examples: use Log::Any q($log), hooks => { build_context => [ \&build_context, ] }; push @{ $log->hooks->{'build_context'} }, \&build_more_context; Signed-off-by: Mikko Koivunalho --- lib/Log/Any.pm | 18 +++++++- lib/Log/Any/Adapter/Util.pm | 14 +++++- lib/Log/Any/Proxy.pm | 20 ++++++++- t/hooks.t | 90 +++++++++++++++++++++++++++++++++++++ 4 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 t/hooks.t diff --git a/lib/Log/Any.pm b/lib/Log/Any.pm index 9d6c955..4e56347 100644 --- a/lib/Log/Any.pm +++ b/lib/Log/Any.pm @@ -95,9 +95,25 @@ sub get_logger { my $adapter = $class->_manager->get_adapter( $category ); my $context = $class->_manager->get_context(); + my $hooks_params = + defined $params{hooks} ? delete $params{hooks} : {}; + my $hooks = {}; + for my $hook_name (Log::Any::Adapter::Util::hook_names()) { + if( defined $hooks_params->{$hook_name} ) { + if( ref $hooks_params->{$hook_name} ne 'ARRAY' ) { + require Carp; + Carp::croak("Fault in hook definition: not array"); + } + $hooks->{$hook_name} = $hooks_params->{$hook_name}; + } else { + $hooks->{$hook_name} = []; + } + } + require_dynamic($proxy_class); return $proxy_class->new( - %params, adapter => $adapter, category => $category, context => $context + %params, adapter => $adapter, category => $category, context => $context, + hooks => $hooks, ); } diff --git a/lib/Log/Any/Adapter/Util.pm b/lib/Log/Any/Adapter/Util.pm index 950a2e7..cd2b511 100644 --- a/lib/Log/Any/Adapter/Util.pm +++ b/lib/Log/Any/Adapter/Util.pm @@ -36,6 +36,7 @@ our @EXPORT_OK = qw( logging_aliases logging_and_detection_methods logging_methods + hook_names make_method numeric_level read_file @@ -47,7 +48,8 @@ push @EXPORT_OK, keys %LOG_LEVELS; our %EXPORT_TAGS = ( 'levels' => [ keys %LOG_LEVELS ] ); my ( %LOG_LEVEL_ALIASES, @logging_methods, @logging_aliases, @detection_methods, - @detection_aliases, @logging_and_detection_methods ); + @detection_aliases, @logging_and_detection_methods, + @hook_names ); BEGIN { %LOG_LEVEL_ALIASES = ( @@ -63,6 +65,8 @@ BEGIN { @detection_methods = map { "is_$_" } @logging_methods; @detection_aliases = map { "is_$_" } @logging_aliases; @logging_and_detection_methods = ( @logging_methods, @detection_methods ); + @hook_names = + qw(build_context); } =sub logging_methods @@ -89,6 +93,14 @@ Returns a list of logging and detection methods (but not aliases). sub logging_and_detection_methods { @logging_and_detection_methods } +=sub hook_names + +Returns a list of hook names. + +=cut + +sub hook_names { @hook_names } + =sub log_level_aliases Returns key/value pairs mapping aliases to "official" names. E.g. "err" maps diff --git a/lib/Log/Any/Proxy.pm b/lib/Log/Any/Proxy.pm index 34f8bdd..4a8817a 100644 --- a/lib/Log/Any/Proxy.pm +++ b/lib/Log/Any/Proxy.pm @@ -55,6 +55,10 @@ sub new { require Carp; Carp::croak("$class requires a 'context' parameter"); } + unless ( $self->{hooks} ) { + require Carp; + Carp::croak("$class requires a 'hooks' parameter"); + } bless $self, $class; $self->init(@_); return $self; @@ -67,7 +71,7 @@ sub clone { sub init { } -for my $attr (qw/adapter category filter formatter prefix context/) { +for my $attr (qw/adapter category filter formatter prefix context hooks/) { no strict 'refs'; *{$attr} = sub { return $_[0]->{$attr} }; } @@ -91,14 +95,26 @@ foreach my $name ( Log::Any::Adapter::Util::logging_methods(), keys(%aliases) ) my ( $self, @parts ) = @_; return if !$self->{adapter}->$is_realname && !defined wantarray; + # Execute hook: build_context + my $caller = (caller 0)[0] ne 'Log::Any::Proxy' + && (caller 0)[3] eq 'Log::Any::Proxy::__ANON__' + ? [ caller 0 ] : [ caller 1 ]; + my %items; + foreach my $hook (@{ $self->{hooks}->{build_context} }) { + my %i = $hook->( $realname, $self->{category}, $caller, \%items); + @items{keys %i} = @i{keys %i}; + } + my $structured_logging = $self->{adapter}->can('structured') && !$self->{filter}; my $data_from_parts = pop @parts if ( @parts && ( ( ref $parts[-1] || '' ) eq ref {} ) ); my $data_from_context = $self->{context}; + my $data_from_hooks = \%items; my $data = - { map {%$_} grep {$_ && %$_} $data_from_context, $data_from_parts }; + { map {%$_} grep {$_ && %$_} $data_from_context, $data_from_parts, + $data_from_hooks, }; if ($structured_logging) { unshift @parts, $self->{prefix} if $self->{prefix}; diff --git a/t/hooks.t b/t/hooks.t new file mode 100644 index 0000000..1a7bfee --- /dev/null +++ b/t/hooks.t @@ -0,0 +1,90 @@ +use strict; +use warnings; +use Test::More tests => 1; + +use Log::Any::Adapter; +use Log::Any '$log'; + +use FindBin; +use lib $FindBin::RealBin; +use TestAdapters; + +sub create_normal_log_lines { + my ($log) = @_; + + $log->info('some info'); + $log->infof( 'more %s', 'info' ); + $log->infof( 'info %s %s', { with => 'data' }, 'and more text' ); + $log->debug( "program started", + { progname => "foo.pl", pid => 1234, perl_version => "5.20.0" } ); + +} + +Log::Any::Adapter->set('+TestAdapters::Structured'); + +push @{ $log->hooks->{'build_context'} }, \&build_context; +create_normal_log_lines($log); +pop @{ $log->hooks->{'build_context'} }; + +sub build_context { + my ($lvl, $cat, $caller, $data) = @_; + my %ctx; + $ctx{lvl} = $lvl; + $ctx{cat} = $cat; + $ctx{file} = $caller->[1]; + $ctx{line} = $caller->[2]; + $ctx{n} = 1; + return %ctx; +} + +is_deeply( + \@TestAdapters::STRUCTURED_LOG, + [ + { messages => ['some info'], level => 'info', category => 'main', + data => [ { + 'line' => 15, + 'cat' => 'main', + 'lvl' => 'info', + 'file' => 't/hooks.t', + 'n' => 1, + }], + }, + { messages => ['more info'], level => 'info', category => 'main', + data => [ { + 'line' => 16, + 'cat' => 'main', + 'lvl' => 'info', + 'file' => 't/hooks.t', + 'n' => 1, + }], + }, + { messages => ['info {with => "data"} and more text'], + level => 'info', + category => 'main', + data => [ + { + 'line' => 17, + 'cat' => 'main', + 'lvl' => 'info', + 'file' => 't/hooks.t', + 'n' => 1, + }, + ], + }, + { messages => ['program started'], + level => 'debug', + category => 'main', + data => [ + { + perl_version => "5.20.0", progname => "foo.pl", pid => 1234, + 'line' => 18, + 'cat' => 'main', + 'lvl' => 'debug', + 'file' => 't/hooks.t', + 'n' => 1, + } + ] + }, + ], + 'identical output of normal log lines when using structured log adapter' + ); From 2684768a940be756c3c621d3fdbfafac028aac7f Mon Sep 17 00:00:00 2001 From: Mikko Koivunalho Date: Fri, 5 May 2023 08:52:28 +0200 Subject: [PATCH 2/7] Move caller() parts to Log::Any::Adapter::Util Signed-off-by: Mikko Koivunalho --- lib/Log/Any/Adapter/Util.pm | 21 +++++++++++++++++++++ lib/Log/Any/Proxy.pm | 5 +---- t/hooks.t | 28 +++++++++++++++------------- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/lib/Log/Any/Adapter/Util.pm b/lib/Log/Any/Adapter/Util.pm index cd2b511..a135f11 100644 --- a/lib/Log/Any/Adapter/Util.pm +++ b/lib/Log/Any/Adapter/Util.pm @@ -180,6 +180,27 @@ sub make_method { *{ $pkg . "::$method" } = $code; } +=sub get_correct_caller + +Return the B information. +Use this sub routine only in a hook! + +Because caller stack is dependent on Log::Any internals +we provide it here. +If you are not using this sub routine from the root of +the hook call, use parameter B to specify the number +of stack layers you have. + +=cut + +sub get_correct_caller { + my ($nr_layers) = $_[0] // 2; + return (caller $nr_layers)[0] ne 'Log::Any::Proxy' + && (caller $nr_layers)[3] eq 'Log::Any::Proxy::__ANON__' + ? [ caller $nr_layers ] + : [ caller $nr_layers + 1 ]; +} + =sub require_dynamic (DEPRECATED) Given a class name, attempts to load it via require unless the class diff --git a/lib/Log/Any/Proxy.pm b/lib/Log/Any/Proxy.pm index 4a8817a..7b72f53 100644 --- a/lib/Log/Any/Proxy.pm +++ b/lib/Log/Any/Proxy.pm @@ -96,12 +96,9 @@ foreach my $name ( Log::Any::Adapter::Util::logging_methods(), keys(%aliases) ) return if !$self->{adapter}->$is_realname && !defined wantarray; # Execute hook: build_context - my $caller = (caller 0)[0] ne 'Log::Any::Proxy' - && (caller 0)[3] eq 'Log::Any::Proxy::__ANON__' - ? [ caller 0 ] : [ caller 1 ]; my %items; foreach my $hook (@{ $self->{hooks}->{build_context} }) { - my %i = $hook->( $realname, $self->{category}, $caller, \%items); + my %i = $hook->( $realname, $self->{category}, \%items); @items{keys %i} = @i{keys %i}; } diff --git a/t/hooks.t b/t/hooks.t index 1a7bfee..f4987b1 100644 --- a/t/hooks.t +++ b/t/hooks.t @@ -4,6 +4,7 @@ use Test::More tests => 1; use Log::Any::Adapter; use Log::Any '$log'; +use Log::Any::Adapter::Util; use FindBin; use lib $FindBin::RealBin; @@ -12,10 +13,10 @@ use TestAdapters; sub create_normal_log_lines { my ($log) = @_; - $log->info('some info'); - $log->infof( 'more %s', 'info' ); - $log->infof( 'info %s %s', { with => 'data' }, 'and more text' ); - $log->debug( "program started", + $log->info('(info) some info'); + $log->infof( '(infof) more %s', 'info' ); + $log->infof( '(infof) info %s %s', { with => 'data' }, 'and more text' ); + $log->debug( "(debug) program started", { progname => "foo.pl", pid => 1234, perl_version => "5.20.0" } ); } @@ -27,7 +28,8 @@ create_normal_log_lines($log); pop @{ $log->hooks->{'build_context'} }; sub build_context { - my ($lvl, $cat, $caller, $data) = @_; + my ($lvl, $cat, $data) = @_; + my $caller = Log::Any::Adapter::Util::get_correct_caller(); my %ctx; $ctx{lvl} = $lvl; $ctx{cat} = $cat; @@ -40,30 +42,30 @@ sub build_context { is_deeply( \@TestAdapters::STRUCTURED_LOG, [ - { messages => ['some info'], level => 'info', category => 'main', + { messages => ['(info) some info'], level => 'info', category => 'main', data => [ { - 'line' => 15, + 'line' => 16, 'cat' => 'main', 'lvl' => 'info', 'file' => 't/hooks.t', 'n' => 1, }], }, - { messages => ['more info'], level => 'info', category => 'main', + { messages => ['(infof) more info'], level => 'info', category => 'main', data => [ { - 'line' => 16, + 'line' => 17, 'cat' => 'main', 'lvl' => 'info', 'file' => 't/hooks.t', 'n' => 1, }], }, - { messages => ['info {with => "data"} and more text'], + { messages => ['(infof) info {with => "data"} and more text'], level => 'info', category => 'main', data => [ { - 'line' => 17, + 'line' => 18, 'cat' => 'main', 'lvl' => 'info', 'file' => 't/hooks.t', @@ -71,13 +73,13 @@ is_deeply( }, ], }, - { messages => ['program started'], + { messages => ['(debug) program started'], level => 'debug', category => 'main', data => [ { perl_version => "5.20.0", progname => "foo.pl", pid => 1234, - 'line' => 18, + 'line' => 19, 'cat' => 'main', 'lvl' => 'debug', 'file' => 't/hooks.t', From 3a60a2d61a7993abf3eb2e3b191840955398cede Mon Sep 17 00:00:00 2001 From: Mikko Koivunalho Date: Wed, 21 Jan 2026 22:10:50 +0100 Subject: [PATCH 3/7] Add encoding to pod, pod has unicode characters --- lib/Log/Any/Proxy.pm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/Log/Any/Proxy.pm b/lib/Log/Any/Proxy.pm index 7b72f53..ee0f83e 100644 --- a/lib/Log/Any/Proxy.pm +++ b/lib/Log/Any/Proxy.pm @@ -148,6 +148,10 @@ foreach my $name ( Log::Any::Adapter::Util::logging_methods(), keys(%aliases) ) 1; +=pod + +=encoding utf8 + =head1 SYNOPSIS # prefix log messages From 208c65ab0244709d481014bef05b357ea9b909e8 Mon Sep 17 00:00:00 2001 From: Mikko Koivunalho Date: Wed, 21 Jan 2026 22:12:27 +0100 Subject: [PATCH 4/7] Remove all hooks related from Log::Any::Adapter::Util --- lib/Log/Any/Adapter/Util.pm | 34 +--------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/lib/Log/Any/Adapter/Util.pm b/lib/Log/Any/Adapter/Util.pm index a135f11..04fb0da 100644 --- a/lib/Log/Any/Adapter/Util.pm +++ b/lib/Log/Any/Adapter/Util.pm @@ -36,7 +36,6 @@ our @EXPORT_OK = qw( logging_aliases logging_and_detection_methods logging_methods - hook_names make_method numeric_level read_file @@ -49,7 +48,7 @@ our %EXPORT_TAGS = ( 'levels' => [ keys %LOG_LEVELS ] ); my ( %LOG_LEVEL_ALIASES, @logging_methods, @logging_aliases, @detection_methods, @detection_aliases, @logging_and_detection_methods, - @hook_names ); + ); BEGIN { %LOG_LEVEL_ALIASES = ( @@ -65,8 +64,6 @@ BEGIN { @detection_methods = map { "is_$_" } @logging_methods; @detection_aliases = map { "is_$_" } @logging_aliases; @logging_and_detection_methods = ( @logging_methods, @detection_methods ); - @hook_names = - qw(build_context); } =sub logging_methods @@ -93,14 +90,6 @@ Returns a list of logging and detection methods (but not aliases). sub logging_and_detection_methods { @logging_and_detection_methods } -=sub hook_names - -Returns a list of hook names. - -=cut - -sub hook_names { @hook_names } - =sub log_level_aliases Returns key/value pairs mapping aliases to "official" names. E.g. "err" maps @@ -180,27 +169,6 @@ sub make_method { *{ $pkg . "::$method" } = $code; } -=sub get_correct_caller - -Return the B information. -Use this sub routine only in a hook! - -Because caller stack is dependent on Log::Any internals -we provide it here. -If you are not using this sub routine from the root of -the hook call, use parameter B to specify the number -of stack layers you have. - -=cut - -sub get_correct_caller { - my ($nr_layers) = $_[0] // 2; - return (caller $nr_layers)[0] ne 'Log::Any::Proxy' - && (caller $nr_layers)[3] eq 'Log::Any::Proxy::__ANON__' - ? [ caller $nr_layers ] - : [ caller $nr_layers + 1 ]; -} - =sub require_dynamic (DEPRECATED) Given a class name, attempts to load it via require unless the class From 466cc7ac272783ed352096015e7faedbab860fdc Mon Sep 17 00:00:00 2001 From: Mikko Koivunalho Date: Wed, 21 Jan 2026 22:27:12 +0100 Subject: [PATCH 5/7] Remove hooks from the required parameters, make them optional --- lib/Log/Any/Proxy.pm | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/Log/Any/Proxy.pm b/lib/Log/Any/Proxy.pm index ee0f83e..9463f5b 100644 --- a/lib/Log/Any/Proxy.pm +++ b/lib/Log/Any/Proxy.pm @@ -55,10 +55,6 @@ sub new { require Carp; Carp::croak("$class requires a 'context' parameter"); } - unless ( $self->{hooks} ) { - require Carp; - Carp::croak("$class requires a 'hooks' parameter"); - } bless $self, $class; $self->init(@_); return $self; From 773aacafc28bc216f1d67b0e1c4ee73a030f595c Mon Sep 17 00:00:00 2001 From: Mikko Koivunalho Date: Wed, 21 Jan 2026 22:28:18 +0100 Subject: [PATCH 6/7] Change hook name, execution place, add another hook * Add new class Log::Any::Proxy::Util to contain Proxy related utilities. * Rename hook build_context to context. * Change execution so that in the hook it is possible to change any log event property, including removing them. * Add execution of an other hook: proxy. This hook is not defined when Log::Any (Log::Any::Proxy) is used. It is defined when Adapter is defined and used. It allows Adapter to get information from Proxy, such as the name, file and row number of the logging function. --- lib/Log/Any.pm | 7 +++++-- lib/Log/Any/Proxy.pm | 29 +++++++++++++++++++---------- lib/Log/Any/Proxy/Util.pm | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 lib/Log/Any/Proxy/Util.pm diff --git a/lib/Log/Any.pm b/lib/Log/Any.pm index 4e56347..f2d8202 100644 --- a/lib/Log/Any.pm +++ b/lib/Log/Any.pm @@ -18,6 +18,7 @@ use Log::Any::Adapter::Util qw( logging_and_detection_methods logging_methods ); +use Log::Any::Proxy::Util (); # This is overridden in Log::Any::Test our $OverrideDefaultAdapterClass; @@ -98,7 +99,7 @@ sub get_logger { my $hooks_params = defined $params{hooks} ? delete $params{hooks} : {}; my $hooks = {}; - for my $hook_name (Log::Any::Adapter::Util::hook_names()) { + for my $hook_name (Log::Any::Proxy::Util::hook_names()) { if( defined $hooks_params->{$hook_name} ) { if( ref $hooks_params->{$hook_name} ne 'ARRAY' ) { require Carp; @@ -111,10 +112,12 @@ sub get_logger { } require_dynamic($proxy_class); - return $proxy_class->new( + my $proxy = $proxy_class->new( %params, adapter => $adapter, category => $category, context => $context, hooks => $hooks, ); + $adapter->{proxy} = $proxy; + return $proxy; } sub _get_proxy_class { diff --git a/lib/Log/Any/Proxy.pm b/lib/Log/Any/Proxy.pm index 9463f5b..084ebd3 100644 --- a/lib/Log/Any/Proxy.pm +++ b/lib/Log/Any/Proxy.pm @@ -91,24 +91,33 @@ foreach my $name ( Log::Any::Adapter::Util::logging_methods(), keys(%aliases) ) my ( $self, @parts ) = @_; return if !$self->{adapter}->$is_realname && !defined wantarray; - # Execute hook: build_context - my %items; - foreach my $hook (@{ $self->{hooks}->{build_context} }) { - my %i = $hook->( $realname, $self->{category}, \%items); - @items{keys %i} = @i{keys %i}; - } - my $structured_logging = $self->{adapter}->can('structured') && !$self->{filter}; my $data_from_parts = pop @parts if ( @parts && ( ( ref $parts[-1] || '' ) eq ref {} ) ); my $data_from_context = $self->{context}; - my $data_from_hooks = \%items; my $data = - { map {%$_} grep {$_ && %$_} $data_from_context, $data_from_parts, - $data_from_hooks, }; + { map {%$_} grep {$_ && %$_} $data_from_context, $data_from_parts }; + + # Hooks defined when using Log::Any::Proxy + if( defined $self->{hooks} ) { + foreach my $hook (@{ $self->{hooks}->{context} }) { + $hook->( $realname, $self->{category}, $data, + { proxy => $self, calling_sub => $name, } + ); + } + } + # Hooks defined when using Log::Any::Adapter + my $calling_sub = (caller 0)[0] eq __PACKAGE__ ? $name.q{f} : $name; + if( defined $self->{adapter}->{hooks}->{proxy} ) { + foreach my $hook (@{ $self->{adapter}->{hooks}->{proxy} }) { + $hook->( $realname, $self->{category}, $data, + { proxy => $self, calling_sub => $calling_sub, } + ); + } + } if ($structured_logging) { unshift @parts, $self->{prefix} if $self->{prefix}; $self->{adapter} diff --git a/lib/Log/Any/Proxy/Util.pm b/lib/Log/Any/Proxy/Util.pm new file mode 100644 index 0000000..952cf10 --- /dev/null +++ b/lib/Log/Any/Proxy/Util.pm @@ -0,0 +1,33 @@ +use 5.008001; +use strict; +use warnings; + +package Log::Any::Proxy::Util; + +# ABSTRACT: Common utility functions for Log::Any::Proxy objects +our $VERSION = '1.719'; + +use Exporter; +our @ISA = qw/Exporter/; + +our @EXPORT_OK = qw( + hook_names +); + +our %EXPORT_TAGS = ( ); + +my ( @hook_names ); + +BEGIN { + @hook_names = qw( context ); +} + +=sub hook_names + +Returns a list of hook names. + +=cut + +sub hook_names { @hook_names } + +1; From f0d4239c726d6099bf9a01054b905e3482313db5 Mon Sep 17 00:00:00 2001 From: Mikko Koivunalho Date: Wed, 21 Jan 2026 22:40:13 +0100 Subject: [PATCH 7/7] Update hooks test --- t/hooks.t | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/t/hooks.t b/t/hooks.t index f4987b1..02fc607 100644 --- a/t/hooks.t +++ b/t/hooks.t @@ -3,7 +3,7 @@ use warnings; use Test::More tests => 1; use Log::Any::Adapter; -use Log::Any '$log'; +use Log::Any qw( $log ); use Log::Any::Adapter::Util; use FindBin; @@ -16,27 +16,23 @@ sub create_normal_log_lines { $log->info('(info) some info'); $log->infof( '(infof) more %s', 'info' ); $log->infof( '(infof) info %s %s', { with => 'data' }, 'and more text' ); - $log->debug( "(debug) program started", - { progname => "foo.pl", pid => 1234, perl_version => "5.20.0" } ); - + $log->debug( '(debug) program started', + { progname => 'foo.pl', pid => 1234, perl_version => '5.20.0' } ); + return; } Log::Any::Adapter->set('+TestAdapters::Structured'); -push @{ $log->hooks->{'build_context'} }, \&build_context; +push @{ $log->hooks->{'context'} }, \&build_context; create_normal_log_lines($log); pop @{ $log->hooks->{'build_context'} }; sub build_context { my ($lvl, $cat, $data) = @_; - my $caller = Log::Any::Adapter::Util::get_correct_caller(); - my %ctx; - $ctx{lvl} = $lvl; - $ctx{cat} = $cat; - $ctx{file} = $caller->[1]; - $ctx{line} = $caller->[2]; - $ctx{n} = 1; - return %ctx; + $data->{lvl} = $lvl; + $data->{cat} = $cat; + $data->{n} = 1; + return; } is_deeply( @@ -44,19 +40,15 @@ is_deeply( [ { messages => ['(info) some info'], level => 'info', category => 'main', data => [ { - 'line' => 16, 'cat' => 'main', 'lvl' => 'info', - 'file' => 't/hooks.t', 'n' => 1, }], }, { messages => ['(infof) more info'], level => 'info', category => 'main', data => [ { - 'line' => 17, 'cat' => 'main', 'lvl' => 'info', - 'file' => 't/hooks.t', 'n' => 1, }], }, @@ -65,10 +57,8 @@ is_deeply( category => 'main', data => [ { - 'line' => 18, 'cat' => 'main', 'lvl' => 'info', - 'file' => 't/hooks.t', 'n' => 1, }, ], @@ -78,11 +68,9 @@ is_deeply( category => 'main', data => [ { - perl_version => "5.20.0", progname => "foo.pl", pid => 1234, - 'line' => 19, + perl_version => '5.20.0', progname => 'foo.pl', pid => 1234, 'cat' => 'main', 'lvl' => 'debug', - 'file' => 't/hooks.t', 'n' => 1, } ]