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