added docs to the log router role
[p5sagit/Log-Contextual.git] / lib / Log / Contextual / Role / Router.pm
1 package Log::Contextual::Role::Router;
2
3 use Moo::Role;
4
5 requires 'before_import';
6 requires 'after_import';
7 requires 'handle_log_request';
8
9 1;
10
11 __END__
12
13 =head1 NAME
14
15 Log::Contextual::Role::Router - Abstract interface between loggers and logging code blocks
16
17 =head1 SYNOPSIS
18
19   package Custom::Logging::Router;
20   
21   use Moo;
22   use Log::Contextual::SimpleLogger;
23   
24   with 'Log::Contextual::Role::Router';
25   
26   has logger => (is => 'lazy');
27   
28   sub _build_logger {
29      return Log::Contextual::SimpleLogger->new({ levels_upto => 'debug' });
30   }
31   
32   sub before_import {
33      my ($self, $log_class, $importer, $spec) = @_;
34      print STDERR "Package '$importer' will import '$log_class'\n";
35   }
36
37   sub after_import {
38      my ($self, $log_class, $importer, $spec) = @_;
39      print STDERR "Package '$importer' has imported '$log_class'\n";
40   }
41
42   sub handle_log_request {
43     my ($self, $metadata, $log_code_block, @args) = @_;
44     my $log_level_name = $metadata->{level};
45     my $logger = $self->logger;
46     my $is_active = $logger->can("is_$log_level_name");
47     
48     return unless defined $is_active && $logger->$is_active;
49     my $log_message = $log_code_block->(@args);
50     $logger->$log_level_name($log_message);
51   }
52
53   package Custom::Logging::Class;
54
55   use Moo;
56
57   extends 'Log::Contextual';
58
59   #Almost certainly the router object should be a singleton
60   sub router {
61      our $Router ||= Custom::Logging::Router->new
62   }
63
64   package main;
65
66   use strictures;
67   use Custom::Logging::Class qw(:log);
68   
69   log_info { "Hello there" };
70
71 =head1 DESCRIPTION
72
73 Log::Contextual has three parts
74
75 =over 4
76
77 =item Export manager and logging method generator
78
79 These tasks are handled by the C<Log::Contextual> class.
80
81 =item Logger selection and invocation
82
83 The log methods generated and exported by Log::Contextual call a method
84 on a log router object which is responsible for invoking any loggers that should
85 get an opportunity to receive the log message. The C<Log::Contextual::Router>
86 class implements the set_logger() and with_logger() methods as well as uses the
87 arg_ prefixed methods to configure itself and provide the standard C<Log::Contextual>
88 logger selection API.
89
90 =item Log message formatting and output
91
92 The logger objects themselves accept or reject a log message at a certain log
93 level with a guard method per level. If the logger is going to accept the
94 log message the router is then responsible for executing the log message code
95 block and passing the generated message to the logging object's log method.
96
97 =back
98
99 =head1 METHODS
100
101 =over 4
102
103 =item before_import($self, $log_class, $importer, $spec)
104
105 =item after_import($self, $log_class, $importer, $spec)
106
107 These two required methods are called with identical arguments at two different places
108 during the import process. The before_import() method is invoked prior to the logging
109 methods being exported into the consuming packages namespace. The after_import() method
110 is called when the export is completed but before control returns to the package that
111 imported the class.
112
113 The arguments are as follows:
114
115 =over 4
116
117 =item $log_class
118
119 This is the package name of the subclass of Log::Contextual that has been imported. It can
120 also be 'Log::Contextual' itself. In the case of the synopsis the value in $log_class would be
121 'Custom::Logging::Class'.
122
123 =item $importer
124
125 This is the package name that is importing the logging class. In the case of the synopsis the
126 value would be 'main'.
127
128 =item $spec
129
130 This is the import specification that is being used when exporting methods to $importer. The
131 value is an unmodified C<Exporter::Declare::Specs> object.
132
133 =back
134
135 =item handle_log_request($self, $info, $generator, @args)
136
137 This method is called by C<Log::Contextual> when a log event happens. The arguments are as
138 follows:
139
140 =over 4
141
142 =item $info
143
144 This is the metadata describing the log event. The value is a hash reference with the following
145 keys:
146
147 =over 4
148
149 =item controller
150
151 This is the name of the Log::Contextual subclass (or 'Log::Contextual' itself) that created
152 the logging methods used to generate the log event.
153
154 =item package
155
156 This is the name of the package that the log event has happened inside of.
157
158 =item caller_level
159
160 This is an integer that contains the value to pass to caller() that will provide
161 information about the location the log event was created at.
162
163 =item level
164
165 This is the name of the log level associated with the log event.
166
167 =back
168
169 =item $generator
170
171 This is the message generating block associated with the log event passed as a subref. If
172 the logger accepts the log request the router should execute the generator to create
173 the log message and then pass the message as a string to the logger.
174
175 =item @args
176
177 This is the arguments provided to the log block passed through completely unmodified. When
178 invoking the generator method it will almost certainly be expecting these argument values
179 as well.
180
181 =back
182
183 =back
184
185 =head1 SEE ALSO
186
187 =over 4
188
189 =item C<Log::Contextual>
190
191 =back
192
193