Log::Any::Adapter::Daemontools - Logging adapter suitable for use in a Daemontools-style logging chain
version 0.100001
Default: log to STDOUT, log level info, prefix each line with level name unless it is info:
STDOUT
info
use Log::Any::Adapter 'Daemontools';
Default to log level notice, and write to STDERR:
notice
STDERR
use Log::Any::Adapter 'Daemontools', -init => { level => 'notice', out => \*STDERR };
Process @ARGV -v/-q and $ENV{DEBUG} to adjust the log level
@ARGV
-v
-q
$ENV{DEBUG}
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.
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:
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.
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)
sub is_trace { 0 }
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.
log_level
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
My scripts usually end up with a chunk of boilerplate in the option processing to raise or lower the log level. This module provides an option to get you common UNIX behavior in as little as 7 characters :-) It's flexible enough to give you many other common varieties, or you can ignore it because it isn't enabled by default.
caller
category
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 add caller info and/or category where the message originated, and allows full customization with coderefs.
format
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.
my $cfg= Log::Any::Adapter::Daemontools->global_config;
Returns the default config instance used by any adapter where you didn't specify one.
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.
The category of the Log::Any logger attached to this adapter. Read-only.
The Log::Any::Adapter::Daemontools::Config object which this adapter is tracking. Read-only reference ( but the config can be altered ).
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 proper 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.
Adapter instances support all the standard logging methods of Log::Any::Adapter
See Log::Any::Adapter
Michael Conrad <mike@nrdvana.net>
This software is copyright (c) 2016 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.
To install Log::Any::Adapter::Daemontools, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Log::Any::Adapter::Daemontools
CPAN shell
perl -MCPAN -e shell install Log::Any::Adapter::Daemontools
For more information on module installation, please visit the detailed CPAN module installation guide.