Hello community, here is the log from the commit of package perl-Log-Any for openSUSE:Factory checked in at 2020-01-14 21:10:22 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/perl-Log-Any (Old) and /work/SRC/openSUSE:Factory/.perl-Log-Any.new.6675 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "perl-Log-Any" Tue Jan 14 21:10:22 2020 rev:25 rq:764296 version:1.708 Changes: -------- --- /work/SRC/openSUSE:Factory/perl-Log-Any/perl-Log-Any.changes 2018-08-31 10:43:59.447170027 +0200 +++ /work/SRC/openSUSE:Factory/.perl-Log-Any.new.6675/perl-Log-Any.changes 2020-01-14 21:13:37.542938511 +0100 @@ -1,0 +2,27 @@ +Tue Jan 14 03:08:57 UTC 2020 - <[email protected]> + +- updated to 1.708 + see /usr/share/doc/packages/perl-Log-Any/Changes + + 1.708 2020-01-12 22:56:43-05:00 America/New_York + + [Added] + + - Added 'Capture' adapter for capturing log messages in an array or + running an arbitrary callback. This makes it easier to test log + messages, collect messages from a certain scope for later display. + Thanks @nrdvana! [Github #77] + + - Added Log::Any::Adapter 'get' class method to get an adapter for + a category. This allows bypassing the Proxy and using the Adapter + directly. Doing so breaks all the features enabled by a Proxy, and + so should only be used in special circumstances (definitely not in + CPAN modules). Thanks @nrdvana! [Github #78] + + - Added 'Multiplex' adapter for directing log output to one or more + Log::Any adapters. This allows, for example, basic logging to + Stderr and logging to a remote Syslogd or Elastic. Thanks + @jrubinator and @GrantStreetGroup for contributing this! + [Github #79, Github #16] + +------------------------------------------------------------------- Old: ---- Log-Any-1.707.tar.gz New: ---- Log-Any-1.708.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ perl-Log-Any.spec ++++++ --- /var/tmp/diff_new_pack.mtum1A/_old 2020-01-14 21:13:38.022938730 +0100 +++ /var/tmp/diff_new_pack.mtum1A/_new 2020-01-14 21:13:38.022938730 +0100 @@ -1,7 +1,7 @@ # # spec file for package perl-Log-Any # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,18 +12,18 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # Name: perl-Log-Any -Version: 1.707 +Version: 1.708 Release: 0 %define cpan_name Log-Any Summary: Bringing loggers and listeners together License: Artistic-1.0 OR GPL-1.0-or-later Group: Development/Libraries/Perl -Url: http://search.cpan.org/dist/Log-Any/ +Url: https://metacpan.org/release/%{cpan_name} Source0: https://cpan.metacpan.org/authors/id/P/PR/PREACTION/%{cpan_name}-%{version}.tar.gz Source1: cpanspec.yml BuildArch: noarch @@ -73,14 +73,14 @@ %prep %setup -q -n %{cpan_name}-%{version} -find . -type f ! -name \*.pl -print0 | xargs -0 chmod 644 +find . -type f ! -path "*/t/*" ! -name "*.pl" ! -path "*/bin/*" ! -path "*/script/*" ! -name "configure" -print0 | xargs -0 chmod 644 %build -%{__perl} Makefile.PL INSTALLDIRS=vendor -%{__make} %{?_smp_mflags} +perl Makefile.PL INSTALLDIRS=vendor +make %{?_smp_mflags} %check -%{__make} test +make test %install %perl_make_install ++++++ Log-Any-1.707.tar.gz -> Log-Any-1.708.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/Changes new/Log-Any-1.708/Changes --- old/Log-Any-1.707/Changes 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/Changes 2020-01-13 04:56:51.000000000 +0100 @@ -2,6 +2,27 @@ ** denotes an incompatible change +1.708 2020-01-12 22:56:43-05:00 America/New_York + + [Added] + + - Added 'Capture' adapter for capturing log messages in an array or + running an arbitrary callback. This makes it easier to test log + messages, collect messages from a certain scope for later display. + Thanks @nrdvana! [Github #77] + + - Added Log::Any::Adapter 'get' class method to get an adapter for + a category. This allows bypassing the Proxy and using the Adapter + directly. Doing so breaks all the features enabled by a Proxy, and + so should only be used in special circumstances (definitely not in + CPAN modules). Thanks @nrdvana! [Github #78] + + - Added 'Multiplex' adapter for directing log output to one or more + Log::Any adapters. This allows, for example, basic logging to + Stderr and logging to a remote Syslogd or Elastic. Thanks + @jrubinator and @GrantStreetGroup for contributing this! + [Github #79, Github #16] + 1.707 2018-08-01 22:55:01-05:00 America/Chicago [Fixed] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/MANIFEST new/Log-Any-1.708/MANIFEST --- old/Log-Any-1.707/MANIFEST 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/MANIFEST 2020-01-13 04:56:51.000000000 +0100 @@ -12,8 +12,10 @@ lib/Log/Any.pm lib/Log/Any/Adapter.pm lib/Log/Any/Adapter/Base.pm +lib/Log/Any/Adapter/Capture.pm lib/Log/Any/Adapter/Development.pod lib/Log/Any/Adapter/File.pm +lib/Log/Any/Adapter/Multiplex.pm lib/Log/Any/Adapter/Null.pm lib/Log/Any/Adapter/Stderr.pm lib/Log/Any/Adapter/Stdout.pm @@ -31,6 +33,7 @@ t/TestAdapters.pm t/adapter-import.t t/author-pod-syntax.t +t/capture.t t/context.t t/default-adapter-env.t t/default-adapter-params.t @@ -43,6 +46,7 @@ t/inner-adapter.t t/log-any-test.t t/memory.t +t/multiplex.t t/null-proxy.t t/proxy.t t/release-backcompat.t diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/META.json new/Log-Any-1.708/META.json --- old/Log-Any-1.707/META.json 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/META.json 2020-01-13 04:56:51.000000000 +0100 @@ -51,6 +51,7 @@ "File::Basename" : "0", "FindBin" : "0", "IO::File" : "0", + "List::Util" : "0", "Storable" : "0", "Sys::Syslog" : "0", "Test::Builder" : "0", @@ -75,63 +76,71 @@ "provides" : { "Log::Any" : { "file" : "lib/Log/Any.pm", - "version" : "1.707" + "version" : "1.708" }, "Log::Any::Adapter" : { "file" : "lib/Log/Any/Adapter.pm", - "version" : "1.707" + "version" : "1.708" }, "Log::Any::Adapter::Base" : { "file" : "lib/Log/Any/Adapter/Base.pm", - "version" : "1.707" + "version" : "1.708" + }, + "Log::Any::Adapter::Capture" : { + "file" : "lib/Log/Any/Adapter/Capture.pm", + "version" : "1.708" }, "Log::Any::Adapter::File" : { "file" : "lib/Log/Any/Adapter/File.pm", - "version" : "1.707" + "version" : "1.708" + }, + "Log::Any::Adapter::Multiplex" : { + "file" : "lib/Log/Any/Adapter/Multiplex.pm", + "version" : "1.708" }, "Log::Any::Adapter::Null" : { "file" : "lib/Log/Any/Adapter/Null.pm", - "version" : "1.707" + "version" : "1.708" }, "Log::Any::Adapter::Stderr" : { "file" : "lib/Log/Any/Adapter/Stderr.pm", - "version" : "1.707" + "version" : "1.708" }, "Log::Any::Adapter::Stdout" : { "file" : "lib/Log/Any/Adapter/Stdout.pm", - "version" : "1.707" + "version" : "1.708" }, "Log::Any::Adapter::Syslog" : { "file" : "lib/Log/Any/Adapter/Syslog.pm", - "version" : "1.707" + "version" : "1.708" }, "Log::Any::Adapter::Test" : { "file" : "lib/Log/Any/Adapter/Test.pm", - "version" : "1.707" + "version" : "1.708" }, "Log::Any::Adapter::Util" : { "file" : "lib/Log/Any/Adapter/Util.pm", - "version" : "1.707" + "version" : "1.708" }, "Log::Any::Manager" : { "file" : "lib/Log/Any/Manager.pm", - "version" : "1.707" + "version" : "1.708" }, "Log::Any::Proxy" : { "file" : "lib/Log/Any/Proxy.pm", - "version" : "1.707" + "version" : "1.708" }, "Log::Any::Proxy::Null" : { "file" : "lib/Log/Any/Proxy/Null.pm", - "version" : "1.707" + "version" : "1.708" }, "Log::Any::Proxy::Test" : { "file" : "lib/Log/Any/Proxy/Test.pm", - "version" : "1.707" + "version" : "1.708" }, "Log::Any::Test" : { "file" : "lib/Log/Any/Test.pm", - "version" : "1.707" + "version" : "1.708" } }, "release_status" : "stable", @@ -146,24 +155,26 @@ "web" : "https://github.com/preaction/Log-Any" } }, - "version" : "1.707", + "version" : "1.708", "x_authority" : "cpan:PREACTION", "x_contributors" : [ "bj5004 <[email protected]>", "cm-perl <[email protected]>", + "Jonathan <[email protected]>", "Karen Etheridge <[email protected]>", "Konstantin S. Uvarin <[email protected]>", "Lucas Kanashiro <[email protected]>", "Maros Kollar <[email protected]>", "Maxim Vuets <[email protected]>", "mephinet <[email protected]>", + "Michael Conrad <[email protected]>", "Nick Tonkin <[email protected]>", "Paul Durden <[email protected]>", "Philipp Gortan <[email protected]>", "Phill Legault <[email protected]>", "Shlomi Fish <[email protected]>" ], - "x_generated_by_perl" : "v5.26.1", - "x_serialization_backend" : "Cpanel::JSON::XS version 4.02" + "x_generated_by_perl" : "v5.28.0", + "x_serialization_backend" : "Cpanel::JSON::XS version 4.06" } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/META.yml new/Log-Any-1.708/META.yml --- old/Log-Any-1.707/META.yml 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/META.yml 2020-01-13 04:56:51.000000000 +0100 @@ -34,49 +34,55 @@ provides: Log::Any: file: lib/Log/Any.pm - version: '1.707' + version: '1.708' Log::Any::Adapter: file: lib/Log/Any/Adapter.pm - version: '1.707' + version: '1.708' Log::Any::Adapter::Base: file: lib/Log/Any/Adapter/Base.pm - version: '1.707' + version: '1.708' + Log::Any::Adapter::Capture: + file: lib/Log/Any/Adapter/Capture.pm + version: '1.708' Log::Any::Adapter::File: file: lib/Log/Any/Adapter/File.pm - version: '1.707' + version: '1.708' + Log::Any::Adapter::Multiplex: + file: lib/Log/Any/Adapter/Multiplex.pm + version: '1.708' Log::Any::Adapter::Null: file: lib/Log/Any/Adapter/Null.pm - version: '1.707' + version: '1.708' Log::Any::Adapter::Stderr: file: lib/Log/Any/Adapter/Stderr.pm - version: '1.707' + version: '1.708' Log::Any::Adapter::Stdout: file: lib/Log/Any/Adapter/Stdout.pm - version: '1.707' + version: '1.708' Log::Any::Adapter::Syslog: file: lib/Log/Any/Adapter/Syslog.pm - version: '1.707' + version: '1.708' Log::Any::Adapter::Test: file: lib/Log/Any/Adapter/Test.pm - version: '1.707' + version: '1.708' Log::Any::Adapter::Util: file: lib/Log/Any/Adapter/Util.pm - version: '1.707' + version: '1.708' Log::Any::Manager: file: lib/Log/Any/Manager.pm - version: '1.707' + version: '1.708' Log::Any::Proxy: file: lib/Log/Any/Proxy.pm - version: '1.707' + version: '1.708' Log::Any::Proxy::Null: file: lib/Log/Any/Proxy/Null.pm - version: '1.707' + version: '1.708' Log::Any::Proxy::Test: file: lib/Log/Any/Proxy/Test.pm - version: '1.707' + version: '1.708' Log::Any::Test: file: lib/Log/Any/Test.pm - version: '1.707' + version: '1.708' requires: B: '0' Carp: '0' @@ -86,6 +92,7 @@ File::Basename: '0' FindBin: '0' IO::File: '0' + List::Util: '0' Storable: '0' Sys::Syslog: '0' Test::Builder: '0' @@ -96,21 +103,23 @@ bugtracker: https://github.com/preaction/Log-Any/issues homepage: https://github.com/preaction/Log-Any repository: https://github.com/preaction/Log-Any.git -version: '1.707' +version: '1.708' x_authority: cpan:PREACTION x_contributors: - 'bj5004 <[email protected]>' - 'cm-perl <[email protected]>' + - 'Jonathan <[email protected]>' - 'Karen Etheridge <[email protected]>' - 'Konstantin S. Uvarin <[email protected]>' - 'Lucas Kanashiro <[email protected]>' - 'Maros Kollar <[email protected]>' - 'Maxim Vuets <[email protected]>' - 'mephinet <[email protected]>' + - 'Michael Conrad <[email protected]>' - 'Nick Tonkin <[email protected]>' - 'Paul Durden <[email protected]>' - 'Philipp Gortan <[email protected]>' - 'Phill Legault <[email protected]>' - 'Shlomi Fish <[email protected]>' -x_generated_by_perl: v5.26.1 +x_generated_by_perl: v5.28.0 x_serialization_backend: 'YAML::Tiny version 1.73' diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/Makefile.PL new/Log-Any-1.708/Makefile.PL --- old/Log-Any-1.707/Makefile.PL 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/Makefile.PL 2020-01-13 04:56:51.000000000 +0100 @@ -24,6 +24,7 @@ "File::Basename" => 0, "FindBin" => 0, "IO::File" => 0, + "List::Util" => 0, "Storable" => 0, "Sys::Syslog" => 0, "Test::Builder" => 0, @@ -38,7 +39,7 @@ "IPC::Open3" => 0, "Test::More" => 0 }, - "VERSION" => "1.707", + "VERSION" => "1.708", "test" => { "TESTS" => "t/*.t" } @@ -58,6 +59,7 @@ "IO::File" => 0, "IO::Handle" => 0, "IPC::Open3" => 0, + "List::Util" => 0, "Storable" => 0, "Sys::Syslog" => 0, "Test::Builder" => 0, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/cpanfile new/Log-Any-1.708/cpanfile --- old/Log-Any-1.707/cpanfile 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/cpanfile 2020-01-13 04:56:51.000000000 +0100 @@ -6,6 +6,7 @@ requires "File::Basename" => "0"; requires "FindBin" => "0"; requires "IO::File" => "0"; +requires "List::Util" => "0"; requires "Storable" => "0"; requires "Sys::Syslog" => "0"; requires "Test::Builder" => "0"; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Adapter/Base.pm new/Log-Any-1.708/lib/Log/Any/Adapter/Base.pm --- old/Log-Any-1.707/lib/Log/Any/Adapter/Base.pm 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any/Adapter/Base.pm 2020-01-13 04:56:51.000000000 +0100 @@ -4,7 +4,7 @@ package Log::Any::Adapter::Base; -our $VERSION = '1.707'; +our $VERSION = '1.708'; our @CARP_NOT = ( 'Log::Any::Adapter' ); # we import these in case any legacy adapter uses them as class methods @@ -52,7 +52,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 AUTHORS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Adapter/Capture.pm new/Log-Any-1.708/lib/Log/Any/Adapter/Capture.pm --- old/Log-Any-1.707/lib/Log/Any/Adapter/Capture.pm 1970-01-01 01:00:00.000000000 +0100 +++ new/Log-Any-1.708/lib/Log/Any/Adapter/Capture.pm 2020-01-13 04:56:51.000000000 +0100 @@ -0,0 +1,240 @@ +use 5.008001; +use strict; +use warnings; + +package Log::Any::Adapter::Capture; + +# ABSTRACT: Adapter for capturing log messages into an arrayref +our $VERSION = '1.708'; + +use Log::Any::Adapter::Util (); + +use Log::Any::Adapter::Base; +our @ISA = qw/Log::Any::Adapter::Base/; + +# Subclass for optional structured logging +@Log::Any::Adapter::Capture::_Structured::ISA = ( __PACKAGE__ ); + +sub init { + my ($self) = @_; + + # Handle 'text' and 'structured' aliases + if ( defined $self->{text} ) { + $self->{format} = 'text'; + $self->{to} = delete $self->{text}; + } + if ( defined $self->{structured} ) { + $self->{format} = 'structured'; + $self->{to} = delete $self->{structured}; + } + + my $to = $self->{to}; + unless ( $to and ref $to eq 'CODE' || ref $to eq 'ARRAY' ) { + require Carp; + Carp::croak( "Capture destination 'to' must be an arrayref or coderef" ); + } + + my $format = $self->{format} || 'messages'; + if ( $format eq 'text' ) { + $self->{_callback} = # only pass the message text argument + ref $to eq 'CODE' ? sub { $to->($_[2]) } + : sub { push @$to, $_[2] }; + } + elsif ( $format eq 'messages' ) { + $self->{_callback} = ref $to eq 'CODE' ? $to : sub { push @$to, [ @_ ] }; + } + elsif ( $format eq 'structured' ) { + $self->{_callback} = ref $to eq 'CODE' ? $to : sub { push @$to, [ @_ ] }; + # Structured logging is determined by whether or not the package + # contains a method of that name. If structured logging were enabled, + # the proxy would always call ->structured rather than its default + # behavior of flattening to a string, even for the case where the user + # of this module wanted strings. So, enable/disable of structured + # capture requires changing the class of this object. + # This line is written in a way to make subclassing possible. + bless $self, ref($self).'::_Structured' unless $self->can('structured'); + } + else { + require Carp; + Carp::croak( "Unknown capture format '$format' (expected 'text', 'messages', or 'structured')" ); + } + + if ( defined $self->{log_level} && $self->{log_level} =~ /\D/ ) { + my $numeric_level = Log::Any::Adapter::Util::numeric_level( $self->{log_level} ); + if ( !defined($numeric_level) ) { + require Carp; + Carp::carp( "Invalid log level '$self->{log_level}'. Will capture all messages." ); + } + $self->{log_level} = $numeric_level; + } +} + +# Each logging method simply passes its arguments (minus $self) to the _callback +# Logging can be skipped if a log_level is in effect. +foreach my $method ( Log::Any::Adapter::Util::logging_methods() ) { + no strict 'refs'; + my $method_level = Log::Any::Adapter::Util::numeric_level($method); + *{$method} = sub { + my ( $self, $text ) = @_; + return if defined $self->{log_level} and $method_level > $self->{log_level}; + $self->{_callback}->( $method, $self->{category}, $text ); + }; +} + +# Detection methods return true unless a log_level is in effect +foreach my $method ( Log::Any::Adapter::Util::detection_methods() ) { + no strict 'refs'; + my $base = substr( $method, 3 ); + my $method_level = Log::Any::Adapter::Util::numeric_level($base); + *{$method} = sub { + return !defined $_[0]{log_level} || !!( $method_level <= $_[0]{log_level} ); + }; +} + +# A separate package is required for handling the ->structured Adapter API. +# See notes in init() +sub Log::Any::Adapter::Capture::_Structured::structured { + my ( $self, $method, $category, @parts ) = @_; + return if defined $self->{log_level} + and Log::Any::Adapter::Util::numeric_level($method) > $self->{log_level}; + $self->{_callback}->( $method, $category, @parts ); +}; + +1; + +__END__ + +=pod + +=encoding UTF-8 + +=head1 NAME + +Log::Any::Adapter::Capture - Adapter for capturing log messages into an arrayref + +=head1 VERSION + +version 1.708 + +=head1 SYNOPSIS + + # temporarily redirect arrays of [ $level, $category, $message ] into an array + Log::Any::Adapter->set( { lexically => \my $scope }, Capture => to => \my @array ); + + # temporarily redirect just the text of log messages into an array + Log::Any::Adapter->set( { lexically => \my $scope }, Capture => text => \my @array ); + + # temporarily redirect the full argument list and context of each call, but only for + # log levels 'info' and above. + Log::Any::Adapter->set( + { lexically => \my $scope }, + Capture => + format => 'structured', + to => \my @array, + log_level => 'info' + ); + +=head1 DESCRIPTION + +This logging adapter provides a convenient way to capture log messages into a callback +or arrayref of your choice without needing to write your own adapter. It is intended +for cases where you want to temporarily capture log messages, such as showing them to +a user of your application rather than having them written to a log file. + +=head1 ATTRIBUTES + +=head2 to + +Specify a coderef or arrayref where the messages will be delivered. The content pushed onto +the array or passed to the coderef depends on L</format>. + +=head2 format + +=over + +=item C<'messages'> + + sub ( $level, $category, $message_text ) { ... } + push @to, [ $level, $category, $message_text ]; + +This is the default format. It passes/pushes 3 arguments: the name of the log level, +the logging category, and the message text as a plain string. + +=item C<'text'> + + sub ( $message_text ) { ... } + push @to, $message_text; + +This format is the simplest, and only passes/pushes the text of the message. + +=item C<'structured'> + + sub ( $level, $category, @message_parts, \%context? ) { ... } + push @to, [ $level, $category, @message_parts, \%context? ]; + +This passes/pushes the full information available about the call to the logging method. +The C<@message_parts> are the actual arguments passed to the logging method, and if the final +argument is a hashref, it is the combined C<context> from the logging proxy and any overrides +passed to the logging method. + +=back + +=head2 log_level + +Like other logging adapters, this optional argument can filter out any log messages above the +specified threshhold. The default is to pass through all messages regardless of level. + +=head1 ATTRIBUTE ALIASES + +These are not actual attributes, just shortcuts for others: + +=head2 text + + text => $dest + +is shorthand for + + format => 'text', to => $dest + +=head2 structured + + structured => $dest + +is shorthand for + + format => 'structured', to => $dest + +=head1 AUTHORS + +=over 4 + +=item * + +Jonathan Swartz <[email protected]> + +=item * + +David Golden <[email protected]> + +=item * + +Doug Bell <[email protected]> + +=item * + +Daniel Pittman <[email protected]> + +=item * + +Stephen Thirlwall <[email protected]> + +=back + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2017 by Jonathan Swartz, David Golden, and Doug Bell. + +This is free software; you can redistribute it and/or modify it under +the same terms as the Perl 5 programming language system itself. + +=cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Adapter/Development.pod new/Log-Any-1.708/lib/Log/Any/Adapter/Development.pod --- old/Log-Any-1.707/lib/Log/Any/Adapter/Development.pod 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any/Adapter/Development.pod 2020-01-13 04:56:51.000000000 +0100 @@ -16,7 +16,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Adapter/File.pm new/Log-Any-1.708/lib/Log/Any/Adapter/File.pm --- old/Log-Any-1.707/lib/Log/Any/Adapter/File.pm 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any/Adapter/File.pm 2020-01-13 04:56:51.000000000 +0100 @@ -5,7 +5,7 @@ package Log::Any::Adapter::File; # ABSTRACT: Simple adapter for logging to files -our $VERSION = '1.707'; +our $VERSION = '1.708'; use Config; use Fcntl qw/:flock/; @@ -80,7 +80,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Adapter/Multiplex.pm new/Log-Any-1.708/lib/Log/Any/Adapter/Multiplex.pm --- old/Log-Any-1.707/lib/Log/Any/Adapter/Multiplex.pm 1970-01-01 01:00:00.000000000 +0100 +++ new/Log-Any-1.708/lib/Log/Any/Adapter/Multiplex.pm 2020-01-13 04:56:51.000000000 +0100 @@ -0,0 +1,187 @@ +package Log::Any::Adapter::Multiplex; + +# ABSTRACT: Adapter to use allow structured logging across other adapters +# VERSION + +use Log::Any; +use Log::Any::Adapter; +use Log::Any::Adapter::Util qw(make_method); +use Log::Any::Manager; +use Log::Any::Proxy; +use Carp; +use strict; +use warnings; +use base qw(Log::Any::Adapter::Base); + +sub init { + my $self = shift; + + my $adapters = $self->{adapters}; + if ( ( ref($adapters) ne 'HASH' ) || + ( grep { ref($_) ne 'ARRAY' } values %$adapters ) ) { + Carp::croak("A list of adapters and their arguments must be provided"); + } +} + +sub structured { + my ($self, $level, $category, @structured_log_args) = @_; + my %adapters = %{ $self->{adapters} }; + my $unstructured_log_args; + + for my $adapter ( $self->_get_adapters($category) ) { + my $is_level = "is_$level"; + + if ($adapter->$is_level) { + # Very simple mimicry of Log::Any::Proxy + # We don't have to handle anything but the difference in + # non-structured interfaces + if ($adapter->can('structured')) { + $adapter->structured($level, $category, @structured_log_args) + } + else { + if (!$unstructured_log_args) { + $unstructured_log_args = [ + _unstructured_log_args( @structured_log_args ) + ]; + } + $adapter->$level(@$unstructured_log_args); + } + } + } +} + +sub _unstructured_log_args { + my @structured = @_; + my @unstructured = @structured; + + if ( @structured && ( ( ref $structured[-1] ) eq ref {} ) ) { + @unstructured = ( + @structured[ 0 .. $#structured - 1 ], + Log::Any::Proxy::_stringify_params( $structured[-1] ), + ) + } + return @unstructured; +} + +# Delegate detection methods to other adapters +# +foreach my $method ( Log::Any->detection_methods() ) { + make_method( + $method, + sub { + my ($self) = @_; + # Not using List::Util::any because it could break older perl builds + my @logging_adaptors = grep { $_->$method } $self->_get_adapters(); + return @logging_adaptors ? 1 : 0; + } + ); +} + +sub _get_adapters { + my ($self) = @_; + my $category = $self->{category}; + # Log::Any::Manager#get_adapter has similar code + # But has to handle rejiggering the stack + # And works with one adapter at a time (instead of a list, as below) + # Keeping track of multiple categories here is just future-proofing. + # + my $category_cache = $self->{category_cache}; + if ( !defined( $category_cache->{$category} ) ) { + my $new_cache = []; + my %adapters = %{ $self->{adapters} }; + while ( my ($adapter_name, $adapter_args) = each %adapters ) { + my $adapter_class = Log::Any::Manager->_get_adapter_class($adapter_name); + push @$new_cache, $adapter_class->new( + @$adapter_args, + category => $category + ); + } + + $self->{category_cache}{$category} = $new_cache; + } + + return @{ $self->{category_cache}{$category} }; +} + +1; + +__END__ + +=pod + +=encoding UTF-8 + +=head1 NAME + +Log::Any::Adapter::Multiplex - Adapter to use allow structured logging across other adapters + +=head1 VERSION + +version 1.708 + +=head1 SYNOPSIS + + Log::Any::Adapter->set( + 'Multiplex', + adapters => { + 'Stdout' => [], + 'Stderr' => [ log_level => 'warn' ], + ... + $adapter => \@adapter_args + }, + ); + +=head1 DESCRIPTION + +This built-in L<Log::Any> adapter provides a simple means of routing logs to +multiple other L<Log::Any::Adapter>s. + +Adapters receiving messages from this adapter can behave just like they are the +only recipient of the log message. That means they can, for example, use +L<Log::Any::Adapter::Development/Structured logging> (or not). + +C<adapters> is a hashref whose keys should be adapters, and whose +values are the arguments to pass those adapters on initialization. + +Note that this differs from other loggers like L<Log::Dispatch>, which will +only provide its output modules a single string C<$message>, and not the full +L<Log::Any/Log context data>. + +=head1 SEE ALSO + +L<Log::Any>, L<Log::Any::Adapter> + +=head1 AUTHORS + +=over 4 + +=item * + +Jonathan Swartz <[email protected]> + +=item * + +David Golden <[email protected]> + +=item * + +Doug Bell <[email protected]> + +=item * + +Daniel Pittman <[email protected]> + +=item * + +Stephen Thirlwall <[email protected]> + +=back + +=head1 COPYRIGHT AND LICENSE + +This software is copyright (c) 2017 by Jonathan Swartz, David Golden, and Doug Bell. + +This is free software; you can redistribute it and/or modify it under +the same terms as the Perl 5 programming language system itself. + +=cut diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Adapter/Null.pm new/Log-Any-1.708/lib/Log/Any/Adapter/Null.pm --- old/Log-Any-1.707/lib/Log/Any/Adapter/Null.pm 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any/Adapter/Null.pm 2020-01-13 04:56:51.000000000 +0100 @@ -5,7 +5,7 @@ package Log::Any::Adapter::Null; # ABSTRACT: Discards all log messages -our $VERSION = '1.707'; +our $VERSION = '1.708'; use Log::Any::Adapter::Base; our @ISA = qw/Log::Any::Adapter::Base/; @@ -33,7 +33,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Adapter/Stderr.pm new/Log-Any-1.708/lib/Log/Any/Adapter/Stderr.pm --- old/Log-Any-1.707/lib/Log/Any/Adapter/Stderr.pm 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any/Adapter/Stderr.pm 2020-01-13 04:56:51.000000000 +0100 @@ -5,7 +5,7 @@ package Log::Any::Adapter::Stderr; # ABSTRACT: Simple adapter for logging to STDERR -our $VERSION = '1.707'; +our $VERSION = '1.708'; use Log::Any::Adapter::Util (); @@ -62,7 +62,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Adapter/Stdout.pm new/Log-Any-1.708/lib/Log/Any/Adapter/Stdout.pm --- old/Log-Any-1.707/lib/Log/Any/Adapter/Stdout.pm 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any/Adapter/Stdout.pm 2020-01-13 04:56:51.000000000 +0100 @@ -5,7 +5,7 @@ package Log::Any::Adapter::Stdout; # ABSTRACT: Simple adapter for logging to STDOUT -our $VERSION = '1.707'; +our $VERSION = '1.708'; use Log::Any::Adapter::Util (); @@ -62,7 +62,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Adapter/Syslog.pm new/Log-Any-1.708/lib/Log/Any/Adapter/Syslog.pm --- old/Log-Any-1.707/lib/Log/Any/Adapter/Syslog.pm 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any/Adapter/Syslog.pm 2020-01-13 04:56:51.000000000 +0100 @@ -5,7 +5,7 @@ package Log::Any::Adapter::Syslog; # ABSTRACT: Send Log::Any logs to syslog -our $VERSION = '1.707'; +our $VERSION = '1.708'; use Log::Any::Adapter::Util qw{make_method}; use base qw{Log::Any::Adapter::Base}; @@ -141,7 +141,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Adapter/Test.pm new/Log-Any-1.708/lib/Log/Any/Adapter/Test.pm --- old/Log-Any-1.707/lib/Log/Any/Adapter/Test.pm 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any/Adapter/Test.pm 2020-01-13 04:56:51.000000000 +0100 @@ -4,7 +4,7 @@ package Log::Any::Adapter::Test; -our $VERSION = '1.707'; +our $VERSION = '1.708'; use Log::Any::Adapter::Util qw/dump_one_line/; use Test::Builder; @@ -218,7 +218,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 AUTHORS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Adapter/Util.pm new/Log-Any-1.708/lib/Log/Any/Adapter/Util.pm --- old/Log-Any-1.707/lib/Log/Any/Adapter/Util.pm 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any/Adapter/Util.pm 2020-01-13 04:56:51.000000000 +0100 @@ -5,7 +5,7 @@ package Log::Any::Adapter::Util; # ABSTRACT: Common utility functions for Log::Any -our $VERSION = '1.707'; +our $VERSION = '1.708'; use Exporter; our @ISA = qw/Exporter/; @@ -241,7 +241,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 DESCRIPTION diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Adapter.pm new/Log-Any-1.708/lib/Log/Any/Adapter.pm --- old/Log-Any-1.707/lib/Log/Any/Adapter.pm 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any/Adapter.pm 2020-01-13 04:56:51.000000000 +0100 @@ -5,7 +5,7 @@ package Log::Any::Adapter; # ABSTRACT: Tell Log::Any where to send its logs -our $VERSION = '1.707'; +our $VERSION = '1.708'; use Log::Any; our @CARP_NOT = ( 'Log::Any::Manager' ); @@ -25,6 +25,11 @@ Log::Any->_manager->remove(@_) } +sub get { + my $pkg = shift; + Log::Any->_manager->get_adapter(@_); +} + 1; __END__ @@ -39,7 +44,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 SYNOPSIS @@ -221,6 +226,23 @@ } $log->error("aiggh!"); # this goes nowhere again +=head1 BUILDING ON THE Log::Any BACKEND + +=over + +=item get + + my $adapter= Log::Any::Adapter->get($category); + +The primary intended way to extend the producing-side of Log::Any is with a custom +L<Log::Any::Proxy> class. However, for special logging scenarios you might also +just want access to the adapter for a given category. The API of an adapter object +is described in L<Log::Any::Adapter::Development>. Beware that adapter objects can +be "rewritten" on the fly, so any conditional behavior you write depending on the +capabilities of an adapter must be re-checked every time you access the adapter. + +=back + =head1 SEE ALSO L<Log::Any|Log::Any> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Manager.pm new/Log-Any-1.708/lib/Log/Any/Manager.pm --- old/Log-Any-1.707/lib/Log/Any/Manager.pm 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any/Manager.pm 2020-01-13 04:56:51.000000000 +0100 @@ -4,7 +4,7 @@ package Log::Any::Manager; -our $VERSION = '1.707'; +our $VERSION = '1.708'; sub new { my $class = shift; @@ -171,9 +171,8 @@ # Reselect adapter for each category matching $pattern # - while ( my ( $category, $category_info ) = - each( %{ $self->{category_cache} } ) ) - { + for my $category ( keys %{ $self->{category_cache} } ) { + my $category_info = $self->{category_cache}->{$category}; my $new_entry = $self->_choose_entry_for_category($category); if ( $new_entry ne $category_info->{entry} ) { my $new_adapter = @@ -249,7 +248,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 AUTHORS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Proxy/Null.pm new/Log-Any-1.708/lib/Log/Any/Proxy/Null.pm --- old/Log-Any-1.707/lib/Log/Any/Proxy/Null.pm 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any/Proxy/Null.pm 2020-01-13 04:56:51.000000000 +0100 @@ -5,7 +5,7 @@ package Log::Any::Proxy::Null; # ABSTRACT: Log::Any generator proxy for no adapters -our $VERSION = '1.707'; +our $VERSION = '1.708'; use Log::Any::Adapter::Util (); use Log::Any::Proxy; @@ -57,7 +57,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 AUTHORS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Proxy/Test.pm new/Log-Any-1.708/lib/Log/Any/Proxy/Test.pm --- old/Log-Any-1.707/lib/Log/Any/Proxy/Test.pm 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any/Proxy/Test.pm 2020-01-13 04:56:51.000000000 +0100 @@ -4,7 +4,7 @@ package Log::Any::Proxy::Test; -our $VERSION = '1.707'; +our $VERSION = '1.708'; use Log::Any::Proxy; our @ISA = qw/Log::Any::Proxy/; @@ -42,7 +42,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 AUTHORS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Proxy.pm new/Log-Any-1.708/lib/Log/Any/Proxy.pm --- old/Log-Any-1.707/lib/Log/Any/Proxy.pm 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any/Proxy.pm 2020-01-13 04:56:51.000000000 +0100 @@ -5,7 +5,7 @@ package Log::Any::Proxy; # ABSTRACT: Log::Any generator proxy object -our $VERSION = '1.707'; +our $VERSION = '1.708'; use Log::Any::Adapter::Util (); use overload; @@ -150,7 +150,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any/Test.pm new/Log-Any-1.708/lib/Log/Any/Test.pm --- old/Log-Any-1.707/lib/Log/Any/Test.pm 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any/Test.pm 2020-01-13 04:56:51.000000000 +0100 @@ -5,7 +5,7 @@ package Log::Any::Test; # ABSTRACT: Test what you're logging with Log::Any -our $VERSION = '1.707'; +our $VERSION = '1.708'; no warnings 'once'; $Log::Any::OverrideDefaultAdapterClass = 'Log::Any::Adapter::Test'; @@ -25,7 +25,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/lib/Log/Any.pm new/Log-Any-1.708/lib/Log/Any.pm --- old/Log-Any-1.707/lib/Log/Any.pm 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/lib/Log/Any.pm 2020-01-13 04:56:51.000000000 +0100 @@ -5,7 +5,7 @@ package Log::Any; # ABSTRACT: Bringing loggers and listeners together -our $VERSION = '1.707'; +our $VERSION = '1.708'; use Log::Any::Manager; use Log::Any::Proxy::Null; @@ -134,7 +134,7 @@ =head1 VERSION -version 1.707 +version 1.708 =head1 SYNOPSIS @@ -475,7 +475,7 @@ =head1 CONTRIBUTORS -=for stopwords bj5004 cm-perl Karen Etheridge Konstantin S. Uvarin Lucas Kanashiro Maros Kollar Maxim Vuets mephinet Nick Tonkin Paul Durden Philipp Gortan Phill Legault Shlomi Fish +=for stopwords bj5004 cm-perl Jonathan Karen Etheridge Konstantin S. Uvarin Lucas Kanashiro Maros Kollar Maxim Vuets mephinet Michael Conrad Nick Tonkin Paul Durden Philipp Gortan Phill Legault Shlomi Fish =over 4 @@ -489,6 +489,10 @@ =item * +Jonathan <[email protected]> + +=item * + Karen Etheridge <[email protected]> =item * @@ -513,6 +517,10 @@ =item * +Michael Conrad <[email protected]> + +=item * + Nick Tonkin <[email protected]> =item * diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/t/00-compile.t new/Log-Any-1.708/t/00-compile.t --- old/Log-Any-1.707/t/00-compile.t 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/t/00-compile.t 2020-01-13 04:56:51.000000000 +0100 @@ -6,13 +6,15 @@ use Test::More; -plan tests => 15 + ($ENV{AUTHOR_TESTING} ? 1 : 0); +plan tests => 17 + ($ENV{AUTHOR_TESTING} ? 1 : 0); my @module_files = ( 'Log/Any.pm', 'Log/Any/Adapter.pm', 'Log/Any/Adapter/Base.pm', + 'Log/Any/Adapter/Capture.pm', 'Log/Any/Adapter/File.pm', + 'Log/Any/Adapter/Multiplex.pm', 'Log/Any/Adapter/Null.pm', 'Log/Any/Adapter/Stderr.pm', 'Log/Any/Adapter/Stdout.pm', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/t/00-report-prereqs.dd new/Log-Any-1.708/t/00-report-prereqs.dd --- old/Log-Any-1.707/t/00-report-prereqs.dd 2018-08-02 05:55:07.000000000 +0200 +++ new/Log-Any-1.708/t/00-report-prereqs.dd 2020-01-13 04:56:51.000000000 +0100 @@ -19,6 +19,7 @@ 'File::Basename' => '0', 'FindBin' => '0', 'IO::File' => '0', + 'List::Util' => '0', 'Storable' => '0', 'Sys::Syslog' => '0', 'Test::Builder' => '0', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/t/capture.t new/Log-Any-1.708/t/capture.t --- old/Log-Any-1.707/t/capture.t 1970-01-01 01:00:00.000000000 +0100 +++ new/Log-Any-1.708/t/capture.t 2020-01-13 04:56:51.000000000 +0100 @@ -0,0 +1,96 @@ +use strict; +use warnings; +use Test::More tests => 12; +use Log::Any; +use Log::Any::Adapter::Util qw(cmp_deeply); + +BEGIN { + $Log::Any::OverrideDefaultProxyClass = 'Log::Any::Proxy::Test'; +} + +{ + + package Foo; + use Log::Any qw($log); + + sub log_debug { + my ( $class, $text ) = @_; + $log->debug($text) if $log->is_debug(); + } +} +{ + + package Bar; + use Log::Any qw($log); + + sub log_info { + my ( $class, $text ) = @_; + $log->info($text) if $log->is_info(); + } +} + +require Log::Any::Adapter; + +my $main_log = Log::Any->get_logger(); +my $foo_log = $Foo::log; + +# redirect to array +{ + Log::Any::Adapter->set( { lexically => \my $scope }, Capture => to => \my @array ); + $main_log->info('Test'); + is_deeply( shift @array, [ 'info', 'main', 'Test' ], 'main logged to arrayref' ); + $main_log->info('Test', 'Test2', { val => 42 }); + is_deeply( shift @array, [ 'info', 'main', 'Test Test2 {val => 42}' ], 'main logged flattened arguments' ); + $foo_log->trace('Test2'); + is_deeply( shift @array, [ 'trace', 'Foo', 'Test2' ], 'Foo logged to arrayref' ); +} + +# redirect_to_coderef +{ + my @last; + Log::Any::Adapter->set( { lexically => \my $scope }, Capture => to => sub { @last= @_ } ); + $main_log->info('Test'); + is_deeply( \@last, [ 'info', 'main', 'Test' ], 'main logged to coderef' ); + $foo_log->trace('Test2'); + is_deeply( \@last, [ 'trace', 'Foo', 'Test2' ], 'Foo logged to coderef' ); +} + +# redirect text only +{ + Log::Any::Adapter->set( + { lexically => \my $scope }, + Capture => ( text => \my @array, log_level => 'info' ) + ); + $main_log->info('Test'); + is_deeply( shift @array, 'Test', 'main logged text-only to arrayref' ); + $main_log->info('Test', 'Test2', { val => 42 }); + is_deeply( shift @array, 'Test Test2 {val => 42}', 'main logged flattened arguments' ); + $foo_log->trace('Test2'); + is_deeply( shift @array, undef, 'Foo ->trace was ignored' ); +} + +# redirect structured +{ + { + Log::Any::Adapter->set( + { lexically => \my $scope }, + Capture => ( structured => \my @array ) + ); + $main_log->info('Test', 'Test2', { blah => 1 }); + is_deeply( shift @array, [ 'info', 'main', 'Test', 'Test2', { blah => 1 } ], 'main logged full data' ); + local $main_log->context->{val} = 42; + $main_log->info('Test', 'Test2', { blah => 1 }); + is_deeply( shift @array, [ 'info', 'main', 'Test', 'Test2', { blah => 1, val => 42 } ], 'main logged combined context' ); + } + { + Log::Any::Adapter->set( + { lexically => \my $scope }, + Capture => ( format => 'structured', to => \my @array ) + ); + $foo_log->trace('Test3', ['Test4']); + is_deeply( shift @array, [ 'trace', 'Foo', 'Test3', ['Test4'] ], 'Foo logged full data' ); + local $foo_log->context->{val} = 42; + $foo_log->trace('Test3', ['Test4']); + is_deeply( shift @array, [ 'trace', 'Foo', 'Test3', ['Test4'], { val => 42 } ], 'Foo logged combined context' ); + } +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/Log-Any-1.707/t/multiplex.t new/Log-Any-1.708/t/multiplex.t --- old/Log-Any-1.707/t/multiplex.t 1970-01-01 01:00:00.000000000 +0100 +++ new/Log-Any-1.708/t/multiplex.t 2020-01-13 04:56:51.000000000 +0100 @@ -0,0 +1,160 @@ +use strict; +use warnings; +use Test::More tests => 16; + +use Log::Any; +use Log::Any::Adapter; + +{ + package _My::Structured::Adapter; + use base 'Log::Any::Adapter::Base'; + use Log::Any::Adapter::Util qw(make_method); + + our $instance; + our $is_logging = 0; + our @structured_args = (); + + sub init { $instance = shift } + + sub structured { @structured_args = @_ } + foreach my $method ( Log::Any->detection_methods() ) { + make_method( $method, sub { $is_logging } ); + } +} + +{ + package _My::Unstructured::Adapter; + use base 'Log::Any::Adapter::Base'; + use Log::Any::Adapter::Util qw(make_method); + + our $instance; + our $is_logging = 0; + our %unstructured_args = (); + + sub init { $instance = shift } + + # Log what we called at each severity + foreach my $method ( Log::Any->logging_methods() ) { + make_method( $method, sub { $unstructured_args{$method} = [@_] } ); + } + + foreach my $method ( Log::Any->detection_methods() ) { + make_method( $method, sub { $is_logging } ); + } +} + +require_ok('Log::Any::Adapter::Multiplex'); + +# basic_arg_validation +{ + # helpful for making sure init() is called on each set() below + my $log = Log::Any->get_logger; + + eval { Log::Any::Adapter->set( 'Multiplex' ) }; + ok $@, 'adapters are required'; + + eval { + Log::Any::Adapter->set( + 'Multiplex', + adapters => 'Stdout' + ) + }; + ok $@, 'adapters must be a hash'; + + eval { + Log::Any::Adapter->set( + 'Multiplex', + adapters => 'Stdout' + ) + }; + ok $@, 'adapters must be a hash'; + + eval { + Log::Any::Adapter->set( + 'Multiplex', + adapters => { + Stdout => {} + } + ) + }; + ok $@, 'adapters values must be arrays'; + + eval { + Log::Any::Adapter->set( + 'Multiplex', + adapters => { + Stdout => [ log_level => 'info' ], + Stderr => [], + } + ) + }; + ok !$@, "Multiplex set up as expected" + or diag $@; +} + +# multiplex_implementation +{ + my %random_args = ( log_level => 'scream' ); + + my $entry = Log::Any::Adapter->set( + 'Multiplex', + adapters => { + '+_My::Structured::Adapter' => [ %random_args ], + '+_My::Unstructured::Adapter' => [ %random_args ], + } + ); + + my $log = Log::Any->get_logger(); + ok !$log->is_info, "multiplex logging off for both destinations"; + + $_My::Structured::Adapter::is_logging = 1; + $_My::Unstructured::Adapter::is_logging = 0; + ok $log->is_info, "multiplex logging on for one destination"; + + $_My::Structured::Adapter::is_logging = 0; + $_My::Unstructured::Adapter::is_logging = 1; + ok $log->is_info, "multiplex logging on for other destination"; + + $_My::Structured::Adapter::is_logging = 1; + $_My::Unstructured::Adapter::is_logging = 1; + ok $log->is_info, "multiplex logging on for both destinations"; + + my $structured_adapter = $_My::Structured::Adapter::instance; + my $unstructured_adapter = $_My::Unstructured::Adapter::instance; + + is $structured_adapter->{log_level}, + $random_args{log_level}, + "Arguments passed to structured adapter"; + is $unstructured_adapter->{log_level}, + $random_args{log_level}, + "Arguments passed to unstructured adapter"; + + my $message = "In a bottle"; + my $level = 'info'; + my $cat = __PACKAGE__; + $log->context->{foo} = 'bar'; + my $ctx_str = '{foo => "bar"}'; + $log->$level($message); + + is_deeply [ @_My::Structured::Adapter::structured_args ], + [ $structured_adapter, $level, $cat, $message, $log->context ], + "Passed appropriate structured args"; + is_deeply $_My::Unstructured::Adapter::unstructured_args{$level}, + [ $unstructured_adapter, $message, $ctx_str ], + "Passed appropriate unstructured args"; + + @_My::Structured::Adapter::structured_args = (); + $_My::Structured::Adapter::is_logging = 0; + $log->$level($message); + is_deeply [ @_My::Structured::Adapter::structured_args ], + [ ], + "structured adapter not called when not logging"; + + $_My::Structured::Adapter::is_logging = 1; + %_My::Unstructured::Adapter::unstructured_args = (); + $_My::Unstructured::Adapter::is_logging = 0; + $log->$level($message); + is_deeply { %_My::Unstructured::Adapter::unstructured_args }, + { }, + "unstructured adapter not called when not logging"; +}
