NAME
Medusa::XS - High-performance XS audit logging with the :Audit attribute
VERSION
Version 0.02
SYNOPSIS
package MyApp::User;
use Medusa::XS;
sub create :Audit {
my ($self, %args) = @_;
# ... your code ...
return $user;
}
# Every call to create() is now automatically logged:
# entry - arguments, caller stack, GUID, timestamp
# exit - return values, elapsed time
DESCRIPTION
Medusa::XS is a drop-in XS replacement for Medusa that provides automatic subroutine audit logging via Perl attributes. Marking a subroutine with the :Audit attribute causes every call to be logged with entry arguments, return values, a unique GUID, caller stack trace, timestamp and elapsed time.
All hot-path work is done in C: UUID generation (via the Horus library, RFC 9562), caller-stack walking, timestamp formatting, argument serialisation (via the Loo library with optional ANSI colour), and log dispatch. The only Perl-level data is the %Medusa::XS::LOG configuration hash.
USAGE
Applying the :Audit attribute
use Medusa::XS;
sub my_method :Audit {
...
}
When the attribute is compiled, Medusa::XS wraps the subroutine with an XS wrapper that logs entry and exit automatically.
Passing configuration at import
use Medusa::XS (
LOG_LEVEL => 'info',
LOG_FILE => '/var/log/myapp-audit.log',
TIME => 'localtime',
TIME_FORMAT => '%Y-%m-%dT%H:%M:%S.%ms',
);
Key-value pairs are merged into %Medusa::XS::LOG.
CONFIGURATION
All configuration lives in the package variable %Medusa::XS::LOG. Defaults are set at BEGIN time and may be overridden before or after use Medusa::XS.
- LOGGER (string, default
"Medusa::XS::Logger") -
Class name of the logger to instantiate when
LOG_INITis called. - LOG_FILE (string, default
"audit.log") -
Path passed to the logger constructor.
- LOG_LEVEL (string, default
"debug") -
The log level written into each message. Also selects which method is called on the logger object (via
LOG_FUNCTIONS). - LOG_INIT (coderef)
-
Called once (lazily, on the first audited call) to create the logger object. Must return a blessed reference that is stored in
$LOG{LOG}. - LOG (object, default
undef) -
The live logger instance. Set automatically by
LOG_INIT, or assign your own object before any audited call:$Medusa::XS::LOG{LOG} = My::Logger->new;The object must implement the method named by
LOG_FUNCTIONSfor the currentLOG_LEVEL(e.g.debug,info, orerror). - TIME (string, default
"gmtime") -
"gmtime"or"localtime"— controls the time zone of timestamps. - TIME_FORMAT (string, default
"default") -
A
strftime(3)-compatible format string. The special token%msis replaced with zero-padded milliseconds. The literal string"default"producesstrftime("%a %b %e %H:%M:%S %Y"). - QUOTE (string, default
"†"(U+2020 DAGGER)) -
Delimiter wrapped around field values in the formatted log line.
- FORMAT_MESSAGE (coderef, default
\&xs_format_message) -
Formatter callback. When set to the built-in
xs_format_message(or left at the default), the fast all-C formatting path is used. Supply your own coderef to customize log output:$Medusa::XS::LOG{FORMAT_MESSAGE} = sub { my (%p) = @_; # %p contains: message, guid, caller, level, params, prefix, # elapsed_call (on exit) return "CUSTOM: $p{message}"; };Note: a custom Perl callback disables the zero-allocation fast path.
- LOG_FUNCTIONS (hashref)
-
Maps log level names to method names on the logger object:
{ error => 'error', info => 'info', debug => 'debug', } - OPTIONS (hashref)
-
Feature flags and GUID configuration. Boolean fields default to 1 (enabled):
{ date => 1, # timestamp guid => 1, # unique call ID guid_version => 4, # UUID version (1-8, 0=NIL, -1=MAX) guid_namespace => undef, # for v3/v5: dns, url, oid, x500, or UUID string guid_name => undef, # for v3/v5: arbitrary name string level => 1, # log level label caller => 1, # caller stack trace elapsed_call => 1, # elapsed time (exit messages only) colour => 1, # 0=off, 1=on, 'auto'=detect terminal colour_theme => 'default', # Loo theme name }colourcontrols ANSI colour output in serialised parameters. Set to0to disable,1to enable (default), or'auto'to auto-detect based on terminal and$ENV{NO_COLOR}.colour_themeselects the colour palette. Built-in themes:"default","light","monokai","none".Set
guid_versionto7for time-ordered UUIDs (recommended for database primary keys). Versions 3 and 5 requireguid_namespaceandguid_nameto be set.
FUNCTIONS
These are available as Medusa::XS::function_name() and are implemented entirely in C.
generate_guid
my $v4 = Medusa::XS::generate_guid(); # default (v4)
my $v7 = Medusa::XS::generate_guid(7); # time-ordered
my $v5 = Medusa::XS::generate_guid(5, 'dns', 'example.com');
my $nil = Medusa::XS::generate_guid(0); # NIL UUID
my $max = Medusa::XS::generate_guid(-1); # MAX UUID
Returns a UUID string (36 characters) generated via the Horus library (RFC 9562). The optional first argument selects the UUID version:
1- Time-based (Gregorian 100ns timestamp + node)3- MD5 namespace (requires namespace and name arguments)4- Random (default)5- SHA-1 namespace (requires namespace and name arguments)6- Reordered time (sortable, Gregorian)7- Unix epoch time-ordered (recommended for databases)8- Custom (random data with version/variant stamped)0- NIL UUID (all zeros)-1- MAX UUID (all ones)
For versions 3 and 5, the second argument is the namespace (one of "dns", "url", "oid", "x500", or a UUID string) and the third argument is the name string.
format_time
my $ts = Medusa::XS::format_time(); # gmtime, default fmt
my $ts = Medusa::XS::format_time(0); # localtime
my $ts = Medusa::XS::format_time(1, '%Y-%m-%d');
Returns a formatted timestamp string. First argument selects gmtime (true) or localtime (false); second is an optional strftime format.
collect_caller_stack
my $stack = Medusa::XS::collect_caller_stack();
Walks Perl's context stack in C and returns a string like "main:12->Foo::Bar:34->Baz::Qux:56".
clean_dumper
my $cleaned = Medusa::XS::clean_dumper($input);
Legacy pass-through kept for backward compatibility. Returns the input unchanged. Previously cleaned Data::Dumper output, but Loo's terse mode makes this unnecessary.
dump_sv
my $str = Medusa::XS::dump_sv($value);
Serialises any Perl value to a compact string using the Loo library. Supports scalars, array/hash refs, blessed objects, coderefs, regexps, and circular references. Respects the colour and colour_theme settings in $LOG{OPTIONS}. Used internally for argument logging.
is_audited
if (Medusa::XS::is_audited(\&Some::Sub)) { ... }
Returns true if the code reference has been wrapped with :Audit.
wrap_sub
Medusa::XS::wrap_sub(\&Some::Sub);
Medusa::XS::wrap_sub(\&Some::Sub, 'method_name');
Programmatically wraps a subroutine with audit logging (same effect as the :Audit attribute). Optional second argument overrides the method name used in log messages.
log_message
Medusa::XS::log_message(
message => 'something happened',
guid => $guid,
caller => $stack,
params => \@args,
prefix => 'arg',
);
Low-level: formats and dispatches a single log entry through the configured FORMAT_MESSAGE and logger.
xs_format_message
my $line = Medusa::XS::xs_format_message(%params);
The default FORMAT_MESSAGE implementation, written in C. Accepts the same keys as log_message and returns a formatted string.
init_logger
Medusa::XS::init_logger();
Calls $LOG{LOG_INIT} if $LOG{LOG} is not yet set. Normally called automatically on the first audited subroutine call.
DEPENDENCIES
Horus — pure C UUID library (header-only, bundled).
Loo — pure XS data serialiser with colour support (header-only, bundled).
Neither requires separate installation; both are compiled directly into Medusa::XS.
SEE ALSO
Medusa::XS::Logger — the default XS file logger.
Medusa — the pure-Perl original that this module replaces.
LICENSE
This module is free software; you may redistribute and/or modify it under the same terms as Perl itself.