NAME
Log::ger::Manual::Tutorial::481_Output_Composite - More on the Composite output
VERSION
version 0.040.000
DESCRIPTION
EXAMPLE 1: access log and error log
A very common thing to have in an application is two kids of logs: an error log and an access log (like in Apache or Squid). You can use Log::ger for both kinds of log and have them easily configurable.
Producing
You have two choices. First, you use the default logger with default procedural style for the error log, and another logger with OO style for the access log:
use Log::ger;
my $access_log = Log::ger->get_logger(category => 'access');
log_warn "goes to error log";
$access_log->info("goes to access log");
Or you can use OO style for both:
use Log::ger (); # don't export log_* procedural routines
my $error_log = Log::ger->get_logger(category => 'error');
my $access_log = Log::ger->get_logger(category => 'access');
$error_log->warn("goes to error log");
$access_log->info("goes to access log");
Or you can use procedural style for both using Log::ger::Plugin::Multisets:
use Log::ger::Plugin Multisets => (
log_sub_prefixes => {
# prefix => init args
log_ => {category=>'error' }, # or undef, to use the default init args (including category)
access_ => {category=>'access'},
},
is_sub_prefixes => {
# prefix => category
is_ => {category=>'error' },
access_is_ => {category=>'access'},
},
);
use Log::ger;
access_info "goes to access log";
access_warn "goes to access log";
log_warn "goes to error log";
log_debug "goes to error log";
...
The example below will use the first choice.
Usually, for the access log you will need to log additional pieces of information like the current user (and/or IP, and/or process ID, etc). A simple format for the access log is JSON, where each JSON object (hash) is printed as a single line and contains the necessary information pieces in hash keys. So let's create a wrapper to supply this information in a more convenient manner:
use Log::ger::Format 'None';
sub access_log {
my ($self, $action, $object, $note) = @_;
$access_log->info({
time => time(),
user => $self->user,
ip => $self->user_ip,
pid => $pid,
action => $action,
object => $object,
note => $note,
});
}
sub handle_request {
my $self = shift;
...
if ($is_success) {
$self->access_log($action => {file=>$file});
} else {
log_error ...;
}
}
Consuming
To display the logs, you can use Log::ger::Output::Composite, for example with this configuration:
use Log::ger::Output Composite => (
outputs => {
Screen => {
category_level => {access=>'off'}, # we don't show access log to screen
},
File => [
# error log file
{
conf => {path=>'/path/to/app-error.log'},
category_level => {access=>'off'}, # we don't show access log to error log file
},
# access log file
{
conf => {path=>'/path/to/app-access.log'},
level => 'off',
category_level => {access=>'info'}, # we only show access log to access log file
},
],
},
);
See also a real-world example in WWW::PAUSE::Simple and App::pause.
SEE ALSO
AUTHOR
perlancar <perlancar@cpan.org>
COPYRIGHT AND LICENSE
This software is copyright (c) 2022, 2020, 2019, 2018, 2017 by perlancar <perlancar@cpan.org>.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.