File Coverage

File:blib/lib/Log/Abstraction/Backend/LogAny.pm
Coverage:42.9%

linestmtbrancondsubtimecode
1package Log::Abstraction::Backend::LogAny;
2
3# The log_any backend: send messages on to Log::Any
4
37
37
37
133
17
187
use strict;
5
37
37
37
27
31
479
use warnings;
6
7
37
37
37
63
29
58
use parent 'Log::Abstraction::Backend';
8
9
37
37
37
629
76
157
use Carp ();
10
37
37
37
37
16
131
use Readonly ();
11
37
37
37
28
20
3683
use Scalar::Util ();
12
13our $VERSION = '0.40';
14
15# The Log::Any method for each internal level name
16Readonly::Hash my %METHOD => (
17        trace     => 'trace',
18        debug     => 'debug',
19        info      => 'info',
20        notice    => 'notice',
21        warn      => 'warning',
22        error     => 'error',
23        critical  => 'critical',
24        alert     => 'alert',
25        emergency => 'emergency',
26);
27
28 - 59
=head1 NAME

Log::Abstraction::Backend::LogAny - send messages on to Log::Any

=head1 VERSION

0.40

=head1 DESCRIPTION

Built for the C<log_any> key of a C<logger> hash, or a L<Log::Any> logger
(C<Log::Any::Proxy>) as the C<logger>.  A category name is looked up with
C<Log::Any-E<gt>get_logger()> for the first message.  The message goes to
the method for its level (C<warn> becomes C<warning>), with the structured
fields as Log::Any's trailing hash reference; with a C<format>, the
formatted line instead.  If Log::Any dies, it carps.

Nothing is sent while a message is already being forwarded (see
C<$Log::Abstraction::Backend::FORWARDING>), so a message that comes back
through L<Log::Any::Adapter::Abstraction> doesn't loop.

For use by L<Log::Abstraction> only; see L<Log::Abstraction::Backend>.

=head1 METHODS

=head2 new

  my $backend = Log::Abstraction::Backend::LogAny->new(
      log_any => $proxy_or_category, level => $level, format => $format,
  );

=cut
60
61sub new {
62
0
        my ($class, %args) = @_;
63
64
0
        my $self = $class->SUPER::new(%args);
65
0
        $self->{'proxy'} = $args{'log_any'} if(Scalar::Util::blessed($args{'log_any'}));
66
0
        return $self;
67}
68
69 - 73
=head2 emit

  $backend->emit($logger, $event);

=cut
74
75sub emit {
76
0
        my ($self, $logger, $event) = @_;
77
78
0
        return if($Log::Abstraction::Backend::FORWARDING);
79
0
        local $Log::Abstraction::Backend::FORWARDING = 1;
80
81
0
        my $ok = eval {
82                # Proxies follow Log::Any::Adapter->set(), so one is enough
83
0
                my $proxy = $self->{'proxy'} //= do {
84
0
                        require Log::Any;
85
0
                        Log::Any->get_logger(category => $self->{'log_any'});
86                };
87
0
                my $method = $METHOD{$event->{'level'}};
88
0
                if(defined($self->{'format'})) {
89
0
                        $proxy->$method($event->{'render'}->($self->{'format'}));
90                } else {
91
0
                        $proxy->$method($event->{'message'}, ($event->{'fields'} ? ($event->{'fields'}) : ()));
92                }
93
0
                1;
94        };
95
0
        Carp::carp(ref($logger), ": Log::Any failed: $@") if(!$ok);
96}
97
98 - 114
=head1 AUTHOR

Nigel Horne C<njh@nigelhorne.com>

=head1 SEE ALSO

L<Log::Abstraction>, L<Log::Abstraction::Backend>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2025-2026 Nigel Horne

Usage is subject to the GPL2 licence terms.
If you use it,
please let me know.

=cut
115
1161;