perltidy code and add .perltidyrc to repo
[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 MyApp::Log::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, %export_info) = @_;
34      my $exporter = $export_info{exporter};
35      my $target = $export_info{target};
36      print STDERR "Package '$target' will import from '$exporter'\n";
37   }
38
39   sub after_import {
40      my ($self, %export_info) = @_;
41      my $exporter = $export_info{exporter};
42      my $target = $export_info{target};
43      print STDERR "Package '$target' has imported from '$exporter'\n";
44   }
45
46   sub handle_log_request {
47      my ($self, %message_info) = @_;
48      my $log_code_block = $message_info{message_sub};
49      my $args = $message_info{message_args};
50      my $log_level_name = $message_info{message_level};
51      my $logger = $self->logger;
52      my $is_active = $logger->can("is_${log_level_name}");
53
54      return unless defined $is_active && $logger->$is_active;
55      my $log_message = $log_code_block->(@$args);
56      $logger->$log_level_name($log_message);
57   }
58
59   package MyApp::Log::Contextual;
60
61   use Moo;
62   use MyApp::Log::Router;
63
64   extends 'Log::Contextual';
65
66   #This example router is a singleton
67   sub router {
68      our $Router ||= MyApp::Log::Router->new
69   }
70
71   package main;
72
73   use strict;
74   use warnings;
75   use MyApp::Log::Contextual qw(:log);
76
77   log_info { "Hello there" };
78
79 =head1 DESCRIPTION
80
81 Log::Contextual has three parts
82
83 =over 4
84
85 =item Export manager and logging method generator
86
87 These tasks are handled by the C<Log::Contextual> package.
88
89 =item Logger selection and invocation
90
91 The logging functions generated and exported by Log::Contextual call a method
92 on an instance of a log router object which is responsible for invoking any loggers
93 that should get an opportunity to receive the log message. The C<Log::Contextual::Router>
94 class implements the set_logger() and with_logger() functions as well as uses the
95 arg_ prefixed functions to configure itself and provide the standard C<Log::Contextual>
96 logger selection API.
97
98 =item Log message formatting and output
99
100 The logger objects themselves accept or reject a log message at a certain log
101 level with a guard method per level. If the logger is going to accept the
102 log message the router is then responsible for executing the log message code
103 block and passing the generated message to the logging object's log method.
104
105 =back
106
107 =head1 METHODS
108
109 =over 4
110
111 =item before_import($self, %import_info)
112
113 =item after_import($self,  %import_info)
114
115 These two required methods are called with identical arguments at two different places
116 during the import process. The before_import() method is invoked prior to the logging
117 subroutines being exported into the target package and after_import() is called when the
118 export is completed but before control returns to the package that imported the API.
119
120 The arguments are passed as a hash with the following keys:
121
122 =over 4
123
124 =item exporter
125
126 This is the name of the package that has been imported. It can also be 'Log::Contextual' itself. In
127 the case of the synopsis the value for exporter would be 'MyApp::Log::Contextual'.
128
129 =item target
130
131 This is the package name that is importing the logging API. In the case of the synopsis the
132 value would be 'main'.
133
134 =item arguments
135
136 This is a hash reference containing the configuration values that were provided for the import.
137 The key is the name of the configuration item that was specified without the leading hyphen ('-').
138 For instance if the logging API is imported as follows
139
140   use Log::Contextual qw( :log ), -logger => Custom::Logger->new({ levels => [qw( debug )] });
141
142 then $import_info{arguments}->{logger} would contain that instance of Custom::Logger.
143
144 =back
145
146 =item handle_log_request($self, %message_info)
147
148 This method is called by C<Log::Contextual> when a log event happens. The arguments are passed
149 as a hash with the following keys
150
151 =over 4
152
153 =item exporter
154
155 This is the name of the package that created the logging methods used to generate the log event.
156
157 =item caller_package
158
159 This is the name of the package that the log event has happened inside of.
160
161 =item caller_level
162
163 This is an integer that contains the value to pass to caller() that will provide
164 information about the location the log event was created at.
165
166 =item log_level
167
168 This is the name of the log level associated with the log event.
169
170 =item message_sub
171
172 This is the message generating code block associated with the log event passed as a subref. If
173 the logger accepts the log request the router should execute the subref to create
174 the log message and then pass the message as a string to the logger.
175
176 =item message_args
177
178 This is an array reference that contains the arguments given to the message generating code block.
179 When invoking the message generator it will almost certainly be expecting these argument values
180 as well.
181
182 =back
183
184 =back
185
186 =head1 SEE ALSO
187
188 =over 4
189
190 =item C<Log::Contextual>
191
192 =back
193
194