Skip to content

Commit

Permalink
Add tests and POD for Log::Any adapter
Browse files Browse the repository at this point in the history
  • Loading branch information
jjatria committed Oct 10, 2024
1 parent bbdf89a commit ba67bd0
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/Log/Any/Adapter/OpenTelemetry.pm
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ for my $method ( Log::Any::Adapter::Util::detection_methods() ) {

no strict 'refs';
*$method = sub {
$numeric <= $OTEL2LOG{ lc( otel_config('LOG_LEVEL') // 'info' ) };
my $level = $OTEL2LOG{ lc( otel_config('LOG_LEVEL') // 'info' ) };
$numeric <= ( $level // $OTEL2LOG{info} );
};
}

Expand Down
50 changes: 50 additions & 0 deletions lib/Log/Any/Adapter/OpenTelemetry.pod
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
=encoding UTF-8

=head1 NAME

Log::Any::Adapter::OpenTelemetry - Send Log::Any logs to OpenTelemetry

=head1 SYNOPSIS

use Log::Any::Adapter 'OpenTelemetry';

=head1 DESCRIPTION

This L<Log::Any> plugin configures your logger to generate L<OpenTelemetry>
log data using the configured L<OpenTelemetry::Logs::LoggerProvider>.

L<Log::Any> log levels are mapped to L<OpenTelemetry> log levels as follows:

=over

=item C<trace> maps to L<OpenTelemetry::Constants/LOG_LEVEL_TRACE>

=item C<debug> maps to L<OpenTelemetry::Constants/LOG_LEVEL_DEBUG>

=item C<info> and C<notice> map to L<OpenTelemetry::Constants/LOG_LEVEL_INFO>

=item C<warning> maps to L<OpenTelemetry::Constants/LOG_LEVEL_WARN>

=item C<error> maps to L<OpenTelemetry::Constants/LOG_LEVEL_ERROR>

=item C<critical>, C<alert>, and C<emergency> map to L<OpenTelemetry::Constants/LOG_LEVEL_FATAL>

=back

When determining whether a log level is enabled or not, the value
of C<OTEL_LOG_LEVEL> will be read from the environment, or that of
C<PERL_OTEL_LOG_LEVEL> if the former is not set. If neither is set,
or if that variable is set to an unknown value, the default value
will be "info".

=head1 ACKNOWLEDGEMENTS

Special thanks to L<CV-Library Ltd.|https://cv-library.co.uk> for their
support in the development of this library.

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2023 by José Joaquín Atria.

This is free software; you can redistribute it and/or modify it under the same
terms as the Perl 5 programming language system itself.
103 changes: 103 additions & 0 deletions t/Log/Any/Adapter/OpenTelemetry.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
#!/usr/bin/env perl

use Test2::V0;
use Test2::Tools::Spec;

use Object::Pad;
use OpenTelemetry ':all';
use Log::Any '$log';
use Log::Any::Adapter;

my @records;
class Local::LoggerProvider :isa(OpenTelemetry::Logs::LoggerProvider) {
use Test2::V0;
method logger ( %args ) {
return mock obj => add => [
emit_record => sub {
shift; push @records => { @_ };
},
];
}
}

otel_logger_provider = Local::LoggerProvider->new;

Log::Any::Adapter->set('OpenTelemetry');

after_each Cleanup => sub {
@records = ();
};

describe Levels => sub {
my ( $level, $first );

after_case Reset => sub { undef $first };

case Trace => sub { $level = 'trace' };
case Debug => sub { $level = 'debug' };
case Info => sub { $level = 'info' };
case Warn => sub { $level = 'warn' };
case Error => sub { $level = 'error' };
case Fatal => sub { $level = 'fatal' };
case Bad => sub { $level = 'bad'; $first = 'info' };

it Works => { flat => 1 } => sub {
local $ENV{OTEL_LOG_LEVEL} = $level;

for my $method ( Log::Any->logging_methods ) {
my $numeric = Log::Any::Adapter::Util::numeric_level($method);
$log->$method($numeric)
}

my $want = Log::Any::Adapter::Util::numeric_level( $first // $level );
is $records[0]->{body}, $want;
}
};

describe Body => sub {
my ( @args, $body, $attributes );

case String => sub {
@args = $body = 'string';
$attributes = DNE;
};

case Hash => sub {
@args = $body = { foo => 123 };
$attributes = DNE;
};

case Array => sub {
@args = ( body => [ foo => 122 ] );

( $body, my $rest ) = @args;
$attributes = { payload => $rest };
};

case Attributes => sub {
@args = (
body => (
foo => 123,
bar => 234,
),
);

( $body, my @rest ) = @args;
$attributes = { @rest };
};

it Works => { flat => 1 } => sub {
$log->info(@args);
is \@records, [
{
body => $body,
attributes => $attributes,
severity_number => E,
severity_text => 'info',
timestamp => T,
}
];
};
};

done_testing;

0 comments on commit ba67bd0

Please sign in to comment.