NAME
Log::Any::Adapter::Daemontools - Logging adapter suitable for use in a Daemontools-style logging chain
VERSION
version 0.102
SYNOPSIS
Default: log to STDOUT
, log level info
, prefix each line with level name unless it is info
:
use Log::Any::Adapter 'Daemontools';
Default to log level notice
, and write to STDERR
:
use Log::Any::Adapter 'Daemontools', -init => { level => 'notice', out => \*STDERR };
Process @ARGV
-v
/-q
and $ENV{DEBUG}
to adjust the log level
use Log::Any::Adapter 'Daemontools', -init => { argv => 1, env => 1 };
Custom output formatting:
use Log::Any::Adapter 'Daemontools', -init => { format => '"$level: $_ (at $file on line $line)"' };
Change log level on the fly:
my $cfg= Log::Any::Adapter::Daemontools->global_config;
$SIG{USR1}= sub { $cfg->log_level_adjust(1); };
$SIG{USR2}= sub { $cfg->log_level_adjust(-1); };
# Those signal handlers can also be installed by the config:
use Log::Any::Adapter 'Daemontools', -init => { signals => ['USR1','USR2'] };
Create alternate configurations separate from the global config:
my $cfg2= Log::Any::Adapter::Daemontools->new_config(log_level => 'notice');
Log::Any::Adapter->set(
{ category => qr/^Noisy::Package::Hierarchy.*/ },
config => $cfg2
);
See Log::Any::Adapter::Daemontools::Config for most of the usage details.
DESCRIPTION
The measure of good software is low learning curve, low complexity, few dependencies, high efficiency, and high flexibility. (choose two. haha)
In the daemontools way of thinking, a daemon writes all its logging output to STDOUT
(or STDERR
), which is a pipe to a logger process. Doing this instead of other logging alternatives keeps your program simple and allows you to capture errors generated by deeper libraries (like libc) which aren't aware of your logging API. If you want complicated logging you can keep those details in the logging process and not bloat each daemon you write.
This module aims to be the easiest, simplest, most efficent way to get Log::Any messages to a file handle while still being flexible enough for the needs of the typical unix daemon or utility script.
Problems solved by this module are:
- Preserve log level
-
The downside of logging to a pipe is you don't get the log-level that you could have had with syslog or Log4perl. An simple way to preserve this information is to prefix each line with "error:" or etc, which can be re-parsed later (or by the logger process). See format.
- Efficiently squelch log levels
-
Trace logging is a great thing, but the methods can get a bit "hot" and you don't want it to impact performance. Log::Any provides the syntax
$log->trace(...) if $log->is_trace
which is great as long as "is_trace" is super-efficient. This module does subclassing/caching tricks so that suppressed log levels are effectively
sub is_trace { 0 }
(although as of Log::Any 1.03 there is still another layer of method call from the Log::Any::Proxy, which is unfortunate) - Dynamically adjust log levels
-
Log::Any::Adapter allows you to replace the current adapters with new ones with a different configuration, which you can use to adjust
log_level
, but it isn't terribly efficient, and if you are also using the regex feature (where different categories get different loggers) it's even worse.This module uses shared configurations on the back-end so you can alter the configuration in many ways without having to re-attach the adapters. (there is a small re-caching penalty, but it's done lazily)
--verbose
/--quiet
/$ENV{DEBUG}
-
My scripts usually end up with a chunk of boilerplate in the option processing to raise or lower the log level. This module replaces that with a simple
-init => { argv => 'consume', env => 1 };
It's flexible enough to give you many other common varieties, or you can ignore it because it isn't enabled by default.
- Display
caller
orcategory
, or custom formatting -
And of course, you often want to see additional details about the message or perform some of your own tweaks. This module provides a
format
option to easily addcaller
info and/orcategory
where the message originated, and allows full customization with coderefs. - Enable autoflush on output handle
-
I often forget to
$|= 1
, and then wonder why my log messages don't match what the program is currently doing. This module turns on autoflush ifoutput
is a file handle. (but if output is a coderef or other object, it's still up to you)
VERSION NOTICE
NOTE: Version 0.1 lost some of the features of version 0.002 when the internals of Log::Any changed in a way that made them impossible. I don't know if anyone was using them anyway, but pay close attention if you are upgrading. This new version adheres more closely to the specification for a logging adapter.
PACKAGE METHODS
global_config
my $cfg= Log::Any::Adapter::Daemontools->global_config;
Returns the default config instance used by any adapter where you didn't specify one.
new_config
my $cfg= Log::Any::Adapter::Daemontools->new_config( %attributes )
Returns a new instance of a config object appropriate for use with this adapter, but currently always an instance of Log::Any::Adapter::Daemontools::Config. See that package for available attributes.
Log::Any::Adapter->set( 'Daemontools', config => $cfg );
This method is preferred over calling ->new on the Log::Any::Adapter::Daemontools::Config package directly, in case some day I decide to play subclassing tricks with the Config objects.
ATTRIBUTES
category
The category of the Log::Any logger attached to this adapter. Read-only.
config
The Log::Any::Adapter::Daemontools::Config object which this adapter is tracking. Read-only reference ( but the config can be altered ).
-init
Log::Any::Adapter 'Daemontools', -init => { ... };
Not actually an attribute! If you pass this to the Daemontools adapter, the first time an instance of the Adapter is created it will call ->init on the adapter's configuration. This allows you to squeeze things onto one line.
The more verbose way to write the above example is:
use Log::Any::Adapter 'Daemontools';
Log::Any::Adapter::Daemontools->global_config->init( ... );
The implied init() call will happen exactly once per config object. (but you can call the init() method yourself as much as you like)
See "init" in Log::Any::Adapter::Daemontools::Config for the complete list of initialization options.
DO NOT pass un-sanitized user input to -init, because the 'format' attribute is processed as perl code.
METHODS
Adapter instances support all the standard logging methods of Log::Any::Adapter
AUTHOR
Michael Conrad <mike@nrdvana.net>
COPYRIGHT AND LICENSE
This software is copyright (c) 2019 by Michael Conrad.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.