Revision history for Log-Abstraction
0.32 Tue Jun 9 19:34:45 EDT 2026
[ Bug Fixes ]
- Fixed SMTP host/port validation in sendmail backend: croak calls were
inside the eval{} that catches delivery failures, so bad config was
silently swallowed instead of propagating. Validation now runs before
the eval so misconfigured host/port croaks immediately to the caller.
0.31 Jun 8 20:55:28 EDT 2026
[ Architecture ]
- Added use autodie qw(:all); file writes wrapped in eval{} to keep
logging failures silent (app must not crash when log file is unavailable)
- Extracted _format_message($self, $level, $str, $use_class) helper,
eliminating 4+ copies of the format-token substitution block
- Extracted _validate_file_path($self, $path) helper, unifying path
validation for hash-backend file, scalar-path, and self->{'file'} under
one implementation
- Added Readonly constants for all magic strings and numbers (SMTP defaults,
port range, syslog defaults, format strings, validation regexes)
- Collapsed _high_priority duplicate if/else blocks into one
- All public void methods now return $self to allow method chaining;
level() setter returns undef on invalid input to signal the error
- Fixed syslog priority mapping: all levels (trace→debug, debug→debug,
info→info, notice→notice, warn→warning, error→err) now correctly mapped
via %LEVEL_TO_SYSLOG_PRIORITY hash instead of a binary error/warning test
- Moved Readonly from test-only to runtime dependency (Makefile.PL, cpanfile)
[ Documentation ]
- Added Z-notation FORMAL SPECIFICATION to every public method POD
- Added API Specification (Params::Validate::Strict input and Return::Set
output schemas) to every public method POD
- Added MESSAGES table to every public method POD
- Added internal-routine comment blocks (purpose, entry, exit, side
effects, notes) for _log, _high_priority, _format_message,
_validate_file_path, _sanitize_email_header, DESTROY
- Suppressed %class% for the base Log::Abstraction class (appears empty,
as it added no useful information when not subclassed)
[ Tests ]
- Added t/locales.t: covers geographic (Locale::Country ISO-code sanity
with BAIL_OUT on drift, case-insensitive codes, concurrent instances) and
POSIX system-locale (LC_ALL en_US.UTF-8/de_DE.UTF-8/ja_JP.UTF-8 error
paths using local $! = ENOENT; my $msg = "$!" pattern)
- Updated edge_cases.t and function.t to use unified "Invalid file name"
error message (standardised via _validate_file_path)
[ Security ]
- Fixed path traversal in HASH-backend file logger: path regex now blocks
'..' sequences, preventing writes outside the intended directory
- Fixed open() in HASH-backend file logger to use the untainted $file
variable rather than the original $logger->{'file'} value
- Added path validation (same allowlist + '..' check) to the scalar-string
logger path, which previously called open() with no validation at all
- Validated SMTP host in sendmail backend: only [a-zA-Z0-9.-] characters
accepted, preventing header/protocol injection via a crafted hostname
- Validated SMTP port in sendmail backend: must be an integer 1-65535,
preventing SSRF port-scanning via an attacker-controlled config file
- Fixed %env_*% format expansion in HASH file backend to use /ge with
defined-or fallback, consistent with the fd and scalar-path backends
[ Bug Fixes ]
- Fixed use Readonly::Values::Syslog version in source to 0.04, matching
Makefile.PL and cpanfile (was still 0.03 after the 0.30 bump)
[ Documentation ]
- Fixed EXAMPLES POD: sample output class field was "main"; corrected to
"Log::Abstraction" (blessed class of the logger object)
- Fixed EXAMPLES POD: sample output warn-row level field was "warning";
corrected to "warn" to match what the module actually passes to callbacks
- Added note explaining that file/line resolve to the module's internal
dispatch for warn/error calls due to the extra _high_priority stack frame
- Replaced broken combined file+sendmail example (file backend writes
native text format, not CSV) with a correct sendmail-only example; added
level => 'warn' key to restrict emails to warn-and-above; noted that
combining CSV output with email requires both in a single code-ref
[ Tests ]
- Simplified $parse_line regex in integration.t: removed dead |"$ alternation
subsumed by "(?:,|$)
0.30 Wed May 27 13:09:35 EDT 2026
[ Enhancements ]
- Added EXAMPLES POD section: CSV file logging for BI import (code-ref
backend writing timestamp/level/class/file/line/message rows, with a
combined sendmail+min_interval variant for real-time alerting)
[ Bug Fixes]
- Bump minimum Readonly::Values::Syslog to 0.04 to fix is_debug() returning
false at trace level on older installations
Fixes https://www.cpantesters.org/cpan/report/32b653da-59c4-11f1-ba50-8ade6d8775ea
0.29 Tue May 26 20:36:13 EDT 2026
[ Enhancements ]
- Added min_interval throttle to sendmail backend: at most one email per
configured interval (seconds); cooldown state stored in _last_email_sent
on the object and inherited by clones
- Bump minimum Test::Mockingbird version to fix https://www.cpantesters.org/cpan/report/f148a3e6-50a2-11f1-8224-a122dd379578
0.28 Fri May 15 20:28:07 EDT 2026
[ Enhancements ]
- Added context (ctx) to code ref logger callbacks
[ Bug Fixes]
- Fixed carp_on_warn and croak_on_error when logging to an array backend
- Fixed cloning to a different level (level string now converted to integer)
- Fixed DESTROY to call Sys::Syslog::closelog() fully-qualified for correct mock interception
- Fixed warn(undef) and warn(warning => undef) to be silent no-ops
- Fixed warn(warning => [undef, ...]) to filter undef elements before joining
- Fixed odd-count plain list in warn/error (_high_priority now wraps get_params in eval)
- Fixed autovivification of sendmail key via exists() guards on sendmail hash access
- Fixed %env_foo% format token to expand missing env vars to empty string without warning
- Fixed ::new() to always construct normally regardless of arguments
- Removed spurious Carp::croak/carp fallback when array backend is defined
0.27 Sun Jan 11 09:52:54 EST 2026
Easier to read tests
Added fatal as a synonym for error
0.26 Wed Oct 15 17:03:58 EDT 2025
Added testing dashboard on GitHub Pages
Added croak_on_error
0.25 Sun Aug 17 20:41:38 EDT 2025
Added is_debug for consistency with Log::Any
Use Return::Set to assert return values within specification
Sanitize the e-mail headers
Started to add format argument to new()
Don't close fd that were passed in
Only load the mail modules when needed
0.24 Sat Jul 19 16:52:41 EDT 2025
Added the ability to send an email for higher priority messages
Only load Log::Log4perl when needed
Deep-clone the messages array during cloning
Map notice to info for Log::Log4perl
Syslog facility is now configurable (default is still local0)
Connections to the syslog are now persistent
0.23 Thu Jul 17 14:45:54 EDT 2025
Better error message when we don't know what to do
Allow the syslog config to say 'server' instead of 'host' for consistency with CHI
0.22 Thu Jul 17 08:22:16 EDT 2025
Error() now sends to syslog like warn()
Ensure undef isn't passed in the messages array to coderefs
0.21 Wed Jul 16 16:21:25 EDT 2025
Added error()
0.20 Sun Jun 15 21:19:03 EDT 2025
Fix GitHub#2
0.19 Tue Jun 10 08:32:28 EDT 2025
Bump minimum version of Sys::Syslog
More untaint checking
0.18 Fri Jun 6 15:52:27 EDT 2025
Fix level testing
0.17 Thu May 22 14:21:14 EDT 2025
Added the messages() method
0.16 Thu May 22 07:40:24 EDT 2025
Handle upper case levels, such as 'INFO'
0.15 Tue May 20 21:10:23 EDT 2025
No need to create a Log::Log4perl when sending output to a file
0.14 Tue May 20 07:44:19 EDT 2025
Adjusted minimum version of Config::Abstraction.
It should be 0.19 in terms of testing but it's best to use the fixes in 0.25
RT#165420 - ANDK
Added 'array' to the logger hash
Introduced 'level' - minimum level to log at, defaults to 'warn'
Fixed where to log bugs
Check and untaint the filename
0.13 Wed May 14 08:30:53 EDT 2025
Use '>' after level rather than ':' to files, like lower level loggers
Try not to put the name of this package in the logfiles,
it adds nothing apart from disc usage
Block setting logger => Log::Abstraction in new()
Croak if we don't know how to handle a message
0.12 Fri May 9 07:42:35 EDT 2025
Added the file parameter, so that both file and syslog can now be given,
and file can be read in from a configuration file
Added the fd descriptor - a file descriptor to log to
Added separators between fields in file output
0.11 Wed May 7 15:37:37 EDT 2025
Fixed calling can() on an unblessed variable
Honour carp_on_warn when syslog is set
0.10 Tue May 6 20:43:48 EDT 2025
Added carp_on_warn
0.09 Tue May 6 08:15:36 EDT 2025
If no logger is given, use Log4perl
0.08 Mon May 5 11:39:58 EDT 2025
Use Config::Abstraction instead of Config::Auto
Guess the value if script_name if it's not given
0.07 Mon Mar 24 08:36:01 EDT 2025
Handle "Socket operation on non-socket" on Solaris
Calling new on an object now returns a clone rather than setting the defaults in the new object
0.06 Wed Mar 12 13:23:24 EDT 2025
Don't put spaces between elements of an array
0.05 Tue Mar 11 14:10:10 EDT 2025
Handle being passed a reference to an array
0.04 Mon Mar 10 09:39:46 EDT 2025
Renamed from Log-YetAnother to Log-Abstraction
Added config_file argument to new()
0.03 Sat Mar 8 08:40:00 EST 2025
Fix passing an array to warn()
0.02 Thu Mar 6 17:09:32 EST 2025
Improved argument checking to new()
0.01 Thu Mar 6 15:42:04 EST 2025
First draft