use Exporter::Declare::Export::Generator;
use Data::Dumper::Concise;
use Scalar::Util 'blessed';
+use Log::Contextual::Router;
my @dlog = ((map "Dlog_$_", @levels), (map "DlogS_$_", @levels));
export_tag log => ('____');
import_arguments qw(logger package_logger default_logger);
+sub arg_router { return $_[1] if defined $_[1]; our $Router_Instance ||= Log::Contextual::Router->new }
+sub arg_logger { $_[1] }
+sub arg_levels { $_[1] || [qw(debug trace warn info error fatal)] }
+sub arg_package_logger { $_[1] }
+sub arg_default_logger { $_[1] }
+
sub before_import {
my ($class, $importer, $spec) = @_;
+ my $router = $class->arg_router;
die 'Log::Contextual does not have a default import list'
if $spec->config->{default};
+ $router->before_import(@_);
+
my @levels = @{$class->arg_levels($spec->config->{levels})};
for my $level (@levels) {
if ($spec->config->{log}) {
$spec->add_export("&log_$level", sub (&@) {
- _do_log( $level => _get_logger( caller ), shift @_, @_)
+ my ($code, @args) = @_;
+ my @loggers = $router->get_loggers(scalar(caller), $level);
+ foreach my $logger (@loggers) {
+ $logger->$level($code->(@args));
+ }
+ return @args;
});
$spec->add_export("&logS_$level", sub (&@) {
- _do_logS( $level => _get_logger( caller ), $_[0], $_[1])
+ my $code = shift;
+ my @loggers = $router->get_loggers(scalar(caller), $level);
+ foreach my $logger (@loggers) {
+ $logger->$level($code->(@_));
+ }
+ return shift;
});
}
if ($spec->config->{dlog}) {
$spec->add_export("&Dlog_$level", sub (&@) {
- my ($code, @args) = @_;
- return _do_log( $level => _get_logger( caller ), sub {
- local $_ = (@args?Data::Dumper::Concise::Dumper @args:'()');
- $code->(@_)
- }, @args );
+ my ($code, @args) = @_;
+ my $dumped = (@args?Data::Dumper::Concise::Dumper @args:'()');
+ my @loggers = $router->get_loggers(scalar(caller), $level);
+ foreach my $logger (@loggers) {
+ $logger->$level(do { local $_ = $dumped; $code->(@args); });
+ }
+ return @args;
});
$spec->add_export("&DlogS_$level", sub (&$) {
- my ($code, $ref) = @_;
- _do_logS( $level => _get_logger( caller ), sub {
- local $_ = Data::Dumper::Concise::Dumper $ref;
- $code->($ref)
- }, $ref )
+ my ($code, $ref) = @_;
+ my $dumped = Data::Dumper::Concise::Dumper $ref;
+ my @loggers = $router->get_loggers(scalar(caller), $level);
+ foreach my $logger (@loggers) {
+ $logger->$level(do { local $_ = $dumped; $code->($ref); });
+ }
+ return $ref;
});
}
}
}
-sub arg_logger { $_[1] }
-sub arg_levels { $_[1] || [qw(debug trace warn info error fatal)] }
-sub arg_package_logger { $_[1] }
-sub arg_default_logger { $_[1] }
-
-sub after_import {
- my ($class, $importer, $specs) = @_;
-
- if (my $l = $class->arg_logger($specs->config->{logger})) {
- set_logger($l)
- }
-
- if (my $l = $class->arg_package_logger($specs->config->{package_logger})) {
- _set_package_logger_for($importer, $l)
- }
-
- if (my $l = $class->arg_default_logger($specs->config->{default_logger})) {
- _set_default_logger_for($importer, $l)
- }
-}
-
-our $Get_Logger;
-our %Default_Logger;
-our %Package_Logger;
-
-sub _set_default_logger_for {
- my $logger = $_[1];
- if(ref $logger ne 'CODE') {
- die 'logger was not a CodeRef or a logger object. Please try again.'
- unless blessed($logger);
- $logger = do { my $l = $logger; sub { $l } }
- }
- $Default_Logger{$_[0]} = $logger
-}
-
-sub _set_package_logger_for {
- my $logger = $_[1];
- if(ref $logger ne 'CODE') {
- die 'logger was not a CodeRef or a logger object. Please try again.'
- unless blessed($logger);
- $logger = do { my $l = $logger; sub { $l } }
- }
- $Package_Logger{$_[0]} = $logger
-}
-
-sub _get_logger($) {
- my $package = shift;
- (
- $Package_Logger{$package} ||
- $Get_Logger ||
- $Default_Logger{$package} ||
- die q( no logger set! you can't try to log something without a logger! )
- )->($package, { caller_level => 2 });
-}
+sub after_import { return arg_router()->after_import(@_) }
sub set_logger {
- my $logger = $_[0];
- if(ref $logger ne 'CODE') {
- die 'logger was not a CodeRef or a logger object. Please try again.'
- unless blessed($logger);
- $logger = do { my $l = $logger; sub { $l } }
- }
+ my $router = arg_router();
+ my $meth = $router->can('set_logger');
- warn 'set_logger (or -logger) called more than once! This is a bad idea!'
- if $Get_Logger;
- $Get_Logger = $logger;
-}
+ die ref($router) . " does not support set_logger()"
+ unless defined $meth;
-sub with_logger {
- my $logger = $_[0];
- if(ref $logger ne 'CODE') {
- die 'logger was not a CodeRef or a logger object. Please try again.'
- unless blessed($logger);
- $logger = do { my $l = $logger; sub { $l } }
- }
- local $Get_Logger = $logger;
- $_[1]->();
+ return $router->$meth(@_);
}
-sub _do_log {
- my $level = shift;
- my $logger = shift;
- my $code = shift;
- my @values = @_;
-
- $logger->$level($code->(@_))
- if $logger->${\"is_$level"};
- @values
-}
+sub with_logger {
+ my $router = arg_router();
+ my $meth = $router->can('with_logger');
-sub _do_logS {
- my $level = shift;
- my $logger = shift;
- my $code = shift;
- my $value = shift;
+ die ref($router) . " does not support with_logger()"
+ unless defined $meth;
- $logger->$level($code->($value))
- if $logger->${\"is_$level"};
- $value
+ return $router->$meth(@_);
}
1;
--- /dev/null
+package Log::Contextual::Router;
+
+use Moo;
+use Scalar::Util 'blessed';
+
+with 'Log::Contextual::Role::Router';
+
+sub before_import { }
+
+sub after_import {
+ my ($self, $controller, $importer, $spec) = @_;
+ my $config = $spec->config;
+
+ if (my $l = $controller->arg_logger($config->{logger})) {
+ $self->set_logger($l)
+ }
+
+ if (my $l = $controller->arg_package_logger($config->{package_logger})) {
+ $self->_set_package_logger_for($importer, $l)
+ }
+
+ if (my $l = $controller->arg_default_logger($config->{default_logger})) {
+ $self->_set_default_logger_for($importer, $l)
+ }
+}
+
+sub with_logger {
+ my $logger = $_[1];
+ if(ref $logger ne 'CODE') {
+ die 'logger was not a CodeRef or a logger object. Please try again.'
+ unless blessed($logger);
+ $logger = do { my $l = $logger; sub { $l } }
+ }
+ local $_[0]->{Get_Logger} = $logger;
+ $_[2]->();
+}
+
+sub set_logger {
+ my $logger = $_[1];
+ if(ref $logger ne 'CODE') {
+ die 'logger was not a CodeRef or a logger object. Please try again.'
+ unless blessed($logger);
+ $logger = do { my $l = $logger; sub { $l } }
+ }
+
+ warn 'set_logger (or -logger) called more than once! This is a bad idea!'
+ if $_[0]->{Get_Logger};
+ $_[0]->{Get_Logger} = $logger;
+
+}
+
+sub _set_default_logger_for {
+ my $logger = $_[2];
+ if(ref $logger ne 'CODE') {
+ die 'logger was not a CodeRef or a logger object. Please try again.'
+ unless blessed($logger);
+ $logger = do { my $l = $logger; sub { $l } }
+ }
+ $_[0]->{Default_Logger}->{$_[1]} = $logger
+}
+
+sub _set_package_logger_for {
+ my $logger = $_[2];
+ if(ref $logger ne 'CODE') {
+ die 'logger was not a CodeRef or a logger object. Please try again.'
+ unless blessed($logger);
+ $logger = do { my $l = $logger; sub { $l } }
+ }
+ $_[0]->{Package_Logger}->{$_[1]} = $logger
+}
+
+sub get_loggers {
+ my ($self, $package, $level) = @_;
+ my $logger = (
+ $_[0]->{Package_Logger}->{$package} ||
+ $_[0]->{Get_Logger} ||
+ $_[0]->{Default_Logger}->{$package} ||
+ die q( no logger set! you can't try to log something without a logger! )
+ );
+
+ $logger = $logger->($package, { caller_level => 2 });
+
+ return $logger if $logger->${\"is_$level"};
+ return ();
+}
+
+1;
+