convert to unobtrusive Dist::Zilla
[p5sagit/Log-Contextual.git] / lib / Log / Contextual / Role / Router.pm
index b6cd31c..d55c379 100644 (file)
@@ -1,5 +1,7 @@
 package Log::Contextual::Role::Router;
 
+# ABSTRACT: Abstract interface between loggers and logging code blocks
+
 use Moo::Role;
 
 requires 'before_import';
@@ -7,3 +9,174 @@ requires 'after_import';
 requires 'handle_log_request';
 
 1;
+
+__END__
+
+=head1 SYNOPSIS
+
+  package MyApp::Log::Router;
+
+  use Moo;
+  use Log::Contextual::SimpleLogger;
+
+  with 'Log::Contextual::Role::Router';
+
+  has logger => (is => 'lazy');
+
+  sub _build_logger {
+     return Log::Contextual::SimpleLogger->new({ levels_upto => 'debug' });
+  }
+
+  sub before_import {
+     my ($self, %export_info) = @_;
+     my $exporter = $export_info{exporter};
+     my $target = $export_info{target};
+     print STDERR "Package '$target' will import from '$exporter'\n";
+  }
+
+  sub after_import {
+     my ($self, %export_info) = @_;
+     my $exporter = $export_info{exporter};
+     my $target = $export_info{target};
+     print STDERR "Package '$target' has imported from '$exporter'\n";
+  }
+
+  sub handle_log_request {
+     my ($self, %message_info) = @_;
+     my $log_code_block = $message_info{message_sub};
+     my $args = $message_info{message_args};
+     my $log_level_name = $message_info{message_level};
+     my $logger = $self->logger;
+     my $is_active = $logger->can("is_${log_level_name}");
+
+     return unless defined $is_active && $logger->$is_active;
+     my $log_message = $log_code_block->(@$args);
+     $logger->$log_level_name($log_message);
+  }
+
+  package MyApp::Log::Contextual;
+
+  use Moo;
+  use MyApp::Log::Router;
+
+  extends 'Log::Contextual';
+
+  #This example router is a singleton
+  sub router {
+     our $Router ||= MyApp::Log::Router->new
+  }
+
+  package main;
+
+  use strict;
+  use warnings;
+  use MyApp::Log::Contextual qw(:log);
+
+  log_info { "Hello there" };
+
+=head1 DESCRIPTION
+
+Log::Contextual has three parts
+
+=over 4
+
+=item Export manager and logging method generator
+
+These tasks are handled by the C<Log::Contextual> package.
+
+=item Logger selection and invocation
+
+The logging functions generated and exported by Log::Contextual call a method
+on an instance of a log router object which is responsible for invoking any loggers
+that should get an opportunity to receive the log message. The C<Log::Contextual::Router>
+class implements the set_logger() and with_logger() functions as well as uses the
+arg_ prefixed functions to configure itself and provide the standard C<Log::Contextual>
+logger selection API.
+
+=item Log message formatting and output
+
+The logger objects themselves accept or reject a log message at a certain log
+level with a guard method per level. If the logger is going to accept the
+log message the router is then responsible for executing the log message code
+block and passing the generated message to the logging object's log method.
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item before_import($self, %import_info)
+
+=item after_import($self,  %import_info)
+
+These two required methods are called with identical arguments at two different places
+during the import process. The before_import() method is invoked prior to the logging
+subroutines being exported into the target package and after_import() is called when the
+export is completed but before control returns to the package that imported the API.
+
+The arguments are passed as a hash with the following keys:
+
+=over 4
+
+=item exporter
+
+This is the name of the package that has been imported. It can also be 'Log::Contextual' itself. In
+the case of the synopsis the value for exporter would be 'MyApp::Log::Contextual'.
+
+=item target
+
+This is the package name that is importing the logging API. In the case of the synopsis the
+value would be 'main'.
+
+=item arguments
+
+This is a hash reference containing the configuration values that were provided for the import.
+The key is the name of the configuration item that was specified without the leading hyphen ('-').
+For instance if the logging API is imported as follows
+
+  use Log::Contextual qw( :log ), -logger => Custom::Logger->new({ levels => [qw( debug )] });
+
+then $import_info{arguments}->{logger} would contain that instance of Custom::Logger.
+
+=back
+
+=item handle_log_request($self, %message_info)
+
+This method is called by C<Log::Contextual> when a log event happens. The arguments are passed
+as a hash with the following keys
+
+=over 4
+
+=item exporter
+
+This is the name of the package that created the logging methods used to generate the log event.
+
+=item caller_package
+
+This is the name of the package that the log event has happened inside of.
+
+=item caller_level
+
+This is an integer that contains the value to pass to caller() that will provide
+information about the location the log event was created at.
+
+=item log_level
+
+This is the name of the log level associated with the log event.
+
+=item message_sub
+
+This is the message generating code block associated with the log event passed as a subref. If
+the logger accepts the log request the router should execute the subref to create
+the log message and then pass the message as a string to the logger.
+
+=item message_args
+
+This is an array reference that contains the arguments given to the message generating code block.
+When invoking the message generator it will almost certainly be expecting these argument values
+as well.
+
+=back
+
+=back