Commit | Line | Data |
8112b699 |
1 | package Log::Contextual::Role::Router; |
2 | |
3 | use Moo::Role; |
4 | |
5 | requires 'before_import'; |
6 | requires 'after_import'; |
8527bf52 |
7 | requires 'handle_log_request'; |
8112b699 |
8 | |
9 | 1; |
eab2ca3c |
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 | |
a5454e75 |
19 | package MyApp::Log::Router; |
6ae293d7 |
20 | |
eab2ca3c |
21 | use Moo; |
22 | use Log::Contextual::SimpleLogger; |
6ae293d7 |
23 | |
eab2ca3c |
24 | with 'Log::Contextual::Role::Router'; |
6ae293d7 |
25 | |
eab2ca3c |
26 | has logger => (is => 'lazy'); |
6ae293d7 |
27 | |
eab2ca3c |
28 | sub _build_logger { |
29 | return Log::Contextual::SimpleLogger->new({ levels_upto => 'debug' }); |
30 | } |
6ae293d7 |
31 | |
eab2ca3c |
32 | sub before_import { |
a5454e75 |
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"; |
eab2ca3c |
37 | } |
38 | |
39 | sub after_import { |
a5454e75 |
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"; |
eab2ca3c |
44 | } |
45 | |
46 | sub handle_log_request { |
a5454e75 |
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}"); |
6ae293d7 |
53 | |
a5454e75 |
54 | return unless defined $is_active && $logger->$is_active; |
55 | my $log_message = $log_code_block->(@$args); |
56 | $logger->$log_level_name($log_message); |
eab2ca3c |
57 | } |
58 | |
a5454e75 |
59 | package MyApp::Log::Contextual; |
eab2ca3c |
60 | |
61 | use Moo; |
a5454e75 |
62 | use MyApp::Log::Router; |
6ae293d7 |
63 | |
eab2ca3c |
64 | extends 'Log::Contextual'; |
65 | |
a5454e75 |
66 | #This example router is a singleton |
eab2ca3c |
67 | sub router { |
a5454e75 |
68 | our $Router ||= MyApp::Log::Router->new |
eab2ca3c |
69 | } |
70 | |
71 | package main; |
72 | |
a5454e75 |
73 | use strict; |
74 | use warnings; |
75 | use MyApp::Log::Contextual qw(:log); |
6ae293d7 |
76 | |
eab2ca3c |
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 | |
a5454e75 |
87 | These tasks are handled by the C<Log::Contextual> package. |
eab2ca3c |
88 | |
89 | =item Logger selection and invocation |
90 | |
a5454e75 |
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> |
eab2ca3c |
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 | |
a5454e75 |
111 | =item before_import($self, %import_info) |
eab2ca3c |
112 | |
a5454e75 |
113 | =item after_import($self, %import_info) |
eab2ca3c |
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 |
a5454e75 |
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. |
eab2ca3c |
119 | |
a5454e75 |
120 | The arguments are passed as a hash with the following keys: |
eab2ca3c |
121 | |
122 | =over 4 |
123 | |
a5454e75 |
124 | =item exporter |
eab2ca3c |
125 | |
a5454e75 |
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'. |
eab2ca3c |
128 | |
a5454e75 |
129 | =item target |
eab2ca3c |
130 | |
a5454e75 |
131 | This is the package name that is importing the logging API. In the case of the synopsis the |
eab2ca3c |
132 | value would be 'main'. |
133 | |
a5454e75 |
134 | =item arguments |
eab2ca3c |
135 | |
6ae293d7 |
136 | This is a hash reference containing the configuration values that were provided for the import. |
a5454e75 |
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 |
eab2ca3c |
139 | |
a5454e75 |
140 | use Log::Contextual qw( :log ), -logger => Custom::Logger->new({ levels => [qw( debug )] }); |
eab2ca3c |
141 | |
a5454e75 |
142 | then $import_info{arguments}->{logger} would contain that instance of Custom::Logger. |
eab2ca3c |
143 | |
a5454e75 |
144 | =back |
eab2ca3c |
145 | |
a5454e75 |
146 | =item handle_log_request($self, %message_info) |
eab2ca3c |
147 | |
a5454e75 |
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 |
eab2ca3c |
150 | |
151 | =over 4 |
152 | |
a5454e75 |
153 | =item exporter |
eab2ca3c |
154 | |
a5454e75 |
155 | This is the name of the package that created the logging methods used to generate the log event. |
eab2ca3c |
156 | |
a5454e75 |
157 | =item caller_package |
eab2ca3c |
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 | |
a5454e75 |
166 | =item log_level |
eab2ca3c |
167 | |
168 | This is the name of the log level associated with the log event. |
169 | |
a5454e75 |
170 | =item message_sub |
eab2ca3c |
171 | |
a5454e75 |
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 |
eab2ca3c |
174 | the log message and then pass the message as a string to the logger. |
175 | |
a5454e75 |
176 | =item message_args |
eab2ca3c |
177 | |
a5454e75 |
178 | This is an array reference that contains the arguments given to the message generating code block. |
6ae293d7 |
179 | When invoking the message generator it will almost certainly be expecting these argument values |
eab2ca3c |
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 | |