NAME
Medusa::XS - High-performance XS audit logging with the :Audit attribute
VERSION
Version 0.01
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: GUID generation, caller-stack walking, timestamp formatting, argument serialisation, 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 controlling which fields appear in each log line. All default to 1 (enabled):
{ date => 1, # timestamp guid => 1, # unique call ID level => 1, # log level label caller => 1, # caller stack trace elapsed_call => 1, # elapsed time (exit messages only) }
FUNCTIONS
These are available as Medusa::XS::function_name() and are implemented entirely in C.
generate_guid
my $uuid = Medusa::XS::generate_guid();
Returns a UUID v4 string (36 characters). Uses /dev/urandom where available, falling back to rand().
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($raw_dumper_output);
Single-pass cleanup of Data::Dumper output: strips $VAR1 = , trailing semicolons, and excess whitespace.
dump_sv
my $str = Medusa::XS::dump_sv($value);
Pure-C serialiser that produces compact Perl-like output for any SV (scalars, array/hash refs, blessed objects, coderefs, regexps). Handles circular references. 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.
SEE ALSO
Medusa::XS::Logger — the default XS file logger.
LICENSE
This module is free software; you may redistribute and/or modify it under the same terms as Perl itself.