Newer Older
248 lines | 4.817kb
add files
Yuki Kimoto authored on 2014-03-26
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