add files
|
1 |
package Mojo::Log; |
2 |
use Mojo::Base 'Mojo::EventEmitter'; |
|
3 | ||
4 |
use Carp 'croak'; |
|
5 |
use Fcntl ':flock'; |
|
6 |
use Mojo::Util 'encode'; |
|
7 | ||
8 |
has handle => sub { |
|
9 | ||
10 |
# File |
|
11 |
if (my $path = shift->path) { |
|
12 |
croak qq{Can't open log file "$path": $!} |
|
13 |
unless open my $file, '>>', $path; |
|
14 |
return $file; |
|
15 |
} |
|
16 | ||
17 |
# STDERR |
|
18 |
return \*STDERR; |
|
19 |
}; |
|
20 |
has level => 'debug'; |
|
21 |
has 'path'; |
|
22 | ||
23 |
# Supported log level |
|
24 |
my $LEVEL = {debug => 1, info => 2, warn => 3, error => 4, fatal => 5}; |
|
25 | ||
26 |
sub new { |
|
27 |
my $self = shift->SUPER::new(@_); |
|
28 |
$self->on(message => \&_message); |
|
29 |
return $self; |
|
30 |
} |
|
31 | ||
32 |
sub debug { shift->log(debug => @_) } |
|
33 |
sub error { shift->log(error => @_) } |
|
34 |
sub fatal { shift->log(fatal => @_) } |
|
35 | ||
36 |
sub format { |
|
37 |
my ($self, $level, @lines) = @_; |
|
38 |
return encode 'UTF-8', |
|
39 |
'[' . localtime(time) . "] [$level] " . join("\n", @lines, ''); |
|
40 |
} |
|
41 | ||
42 |
sub info { shift->log(info => @_) } |
|
43 | ||
44 |
sub is_debug { shift->is_level('debug') } |
|
45 |
sub is_error { shift->is_level('error') } |
|
46 |
sub is_fatal { shift->is_level('fatal') } |
|
47 |
sub is_info { shift->is_level('info') } |
|
48 | ||
49 |
sub is_level { |
|
50 |
my ($self, $level) = @_; |
|
51 |
return $LEVEL->{lc $level} >= $LEVEL->{$ENV{MOJO_LOG_LEVEL} || $self->level}; |
|
52 |
} |
|
53 | ||
54 |
sub is_warn { shift->is_level('warn') } |
|
55 | ||
56 |
sub log { shift->emit('message', lc(shift), @_) } |
|
57 | ||
58 |
sub warn { shift->log(warn => @_) } |
|
59 | ||
60 |
sub _message { |
|
61 |
my ($self, $level) = (shift, shift); |
|
62 | ||
63 |
return unless $self->is_level($level) && (my $handle = $self->handle); |
|
64 | ||
65 |
flock $handle, LOCK_EX; |
|
66 |
$handle->print($self->format($level, @_)) or croak "Can't write to log: $!"; |
|
67 |
flock $handle, LOCK_UN; |
|
68 |
} |
|
69 | ||
70 |
1; |
|
71 | ||
72 |
=encoding utf8 |
|
73 | ||
74 |
=head1 NAME |
|
75 | ||
76 |
Mojo::Log - Simple logger |
|
77 | ||
78 |
=head1 SYNOPSIS |
|
79 | ||
80 |
use Mojo::Log; |
|
81 | ||
82 |
# Log to STDERR |
|
83 |
my $log = Mojo::Log->new; |
|
84 | ||
85 |
# Customize log file location and minimum log level |
|
86 |
my $log = Mojo::Log->new(path => '/var/log/mojo.log', level => 'warn'); |
|
87 | ||
88 |
# Log messages |
|
89 |
$log->debug('Why is this not working?'); |
|
90 |
$log->info('FYI: it happened again.'); |
|
91 |
$log->warn('This might be a problem.'); |
|
92 |
$log->error('Garden variety error.'); |
|
93 |
$log->fatal('Boom!'); |
|
94 | ||
95 |
=head1 DESCRIPTION |
|
96 | ||
97 |
L<Mojo::Log> is a simple logger for L<Mojo> projects. |
|
98 | ||
99 |
=head1 EVENTS |
|
100 | ||
101 |
L<Mojo::Log> inherits all events from L<Mojo::EventEmitter> and can emit the |
|
102 |
following new ones. |
|
103 | ||
104 |
=head2 message |
|
105 | ||
106 |
$log->on(message => sub { |
|
107 |
my ($log, $level, @lines) = @_; |
|
108 |
... |
|
109 |
}); |
|
110 | ||
111 |
Emitted when a new message gets logged. |
|
112 | ||
113 |
$log->unsubscribe('message'); |
|
114 |
$log->on(message => sub { |
|
115 |
my ($log, $level, @lines) = @_; |
|
116 |
say "$level: ", @lines; |
|
117 |
}); |
|
118 | ||
119 |
=head1 ATTRIBUTES |
|
120 | ||
121 |
L<Mojo::Log> implements the following attributes. |
|
122 | ||
123 |
=head2 handle |
|
124 | ||
125 |
my $handle = $log->handle; |
|
126 |
$log = $log->handle(IO::Handle->new); |
|
127 | ||
128 |
Log filehandle used by default L</"message"> event, defaults to opening |
|
129 |
L</"path"> or C<STDERR>. |
|
130 | ||
131 |
=head2 level |
|
132 | ||
133 |
my $level = $log->level; |
|
134 |
$log = $log->level('debug'); |
|
135 | ||
136 |
Active log level, defaults to C<debug>. Available log levels are C<debug>, |
|
137 |
C<info>, C<warn>, C<error> and C<fatal>, in that order. Note that the |
|
138 |
MOJO_LOG_LEVEL environment variable can override this value. |
|
139 | ||
140 |
=head2 path |
|
141 | ||
142 |
my $path = $log->path |
|
143 |
$log = $log->path('/var/log/mojo.log'); |
|
144 | ||
145 |
Log file path used by L</"handle">. |
|
146 | ||
147 |
=head1 METHODS |
|
148 | ||
149 |
L<Mojo::Log> inherits all methods from L<Mojo::EventEmitter> and implements |
|
150 |
the following new ones. |
|
151 | ||
152 |
=head2 new |
|
153 | ||
154 |
my $log = Mojo::Log->new; |
|
155 | ||
156 |
Construct a new L<Mojo::Log> object and subscribe to L</"message"> event with |
|
157 |
default logger. |
|
158 | ||
159 |
=head2 debug |
|
160 | ||
161 |
$log = $log->debug('You screwed up, but that is ok.'); |
|
162 |
$log = $log->debug('All', 'cool!'); |
|
163 | ||
164 |
Log debug message. |
|
165 | ||
166 |
=head2 error |
|
167 | ||
168 |
$log = $log->error('You really screwed up this time.'); |
|
169 |
$log = $log->error('Wow', 'seriously!'); |
|
170 | ||
171 |
Log error message. |
|
172 | ||
173 |
=head2 fatal |
|
174 | ||
175 |
$log = $log->fatal('Its over...'); |
|
176 |
$log = $log->fatal('Bye', 'bye!'); |
|
177 | ||
178 |
Log fatal message. |
|
179 | ||
180 |
=head2 format |
|
181 | ||
182 |
my $msg = $log->format(debug => 'Hi there!'); |
|
183 |
my $msg = $log->format(debug => 'Hi', 'there!'); |
|
184 | ||
185 |
Format log message. |
|
186 | ||
187 |
=head2 info |
|
188 | ||
189 |
$log = $log->info('You are bad, but you prolly know already.'); |
|
190 |
$log = $log->info('Ok', 'then!'); |
|
191 | ||
192 |
Log info message. |
|
193 | ||
194 |
=head2 is_level |
|
195 | ||
196 |
my $bool = $log->is_level('debug'); |
|
197 | ||
198 |
Check log level. |
|
199 | ||
200 |
=head2 is_debug |
|
201 | ||
202 |
my $bool = $log->is_debug; |
|
203 | ||
204 |
Check for debug log level. |
|
205 | ||
206 |
=head2 is_error |
|
207 | ||
208 |
my $bool = $log->is_error; |
|
209 | ||
210 |
Check for error log level. |
|
211 | ||
212 |
=head2 is_fatal |
|
213 | ||
214 |
my $bool = $log->is_fatal; |
|
215 | ||
216 |
Check for fatal log level. |
|
217 | ||
218 |
=head2 is_info |
|
219 | ||
220 |
my $bool = $log->is_info; |
|
221 | ||
222 |
Check for info log level. |
|
223 | ||
224 |
=head2 is_warn |
|
225 | ||
226 |
my $bool = $log->is_warn; |
|
227 | ||
228 |
Check for warn log level. |
|
229 | ||
230 |
=head2 log |
|
231 | ||
232 |
$log = $log->log(debug => 'This should work.'); |
|
233 |
$log = $log->log(debug => 'This', 'too!'); |
|
234 | ||
235 |
Emit L</"message"> event. |
|
236 | ||
237 |
=head2 warn |
|
238 | ||
239 |
$log = $log->warn('Dont do that Dave...'); |
|
240 |
$log = $log->warn('No', 'really!'); |
|
241 | ||
242 |
Log warn message. |
|
243 | ||
244 |
=head1 SEE ALSO |
|
245 | ||
246 |
L<Mojolicious>, L<Mojolicious::Guides>, L<http://mojolicio.us>. |
|
247 | ||
248 |
=cut |