Changelog typo
[catagits/Catalyst-Runtime.git] / lib / Catalyst / Log.pm
CommitLineData
fc7ec1d9 1package Catalyst::Log;
2
e5ecd5bc 3use Moose;
531f1ab6 4with 'MooseX::Emulate::Class::Accessor::Fast';
5
f63c03e4 6use Data::Dump;
e106a59f 7use Class::MOP ();
9b2bc37b 8
c72d2e24 9our %LEVELS = (); # Levels stored as bit field, ergo debug = 1, warn = 2 etc
10our %LEVEL_MATCH = (); # Stored as additive, thus debug = 31, warn = 30 etc
a6433a05 11
3cdcf968 12has level => (is => 'rw');
5fb12dbb 13has _body => (is => 'rw');
3cdcf968 14has abort => (is => 'rw');
15
2f9e6321 16{
a6433a05 17 my @levels = qw[ debug info warn error fatal ];
846772b7 18
e106a59f 19 my $meta = Class::MOP::get_metaclass_by_name(__PACKAGE__);
c72d2e24 20 my $summed_level = 0;
21 for ( my $i = $#levels ; $i >= 0 ; $i-- ) {
846772b7 22
23 my $name = $levels[$i];
eaae9a92 24
846772b7 25 my $level = 1 << $i;
c72d2e24 26 $summed_level |= $level;
eaae9a92 27
a6433a05 28 $LEVELS{$name} = $level;
c72d2e24 29 $LEVEL_MATCH{$name} = $summed_level;
a6433a05 30
4090e3bb 31 $meta->add_method($name, sub {
846772b7 32 my $self = shift;
33
3cdcf968 34 if ( $self->level & $level ) {
846772b7 35 $self->_log( $name, @_ );
36 }
4090e3bb 37 });
846772b7 38
4090e3bb 39 $meta->add_method("is_$name", sub {
846772b7 40 my $self = shift;
3cdcf968 41 return $self->level & $level;
4090e3bb 42 });;
846772b7 43 }
a6433a05 44}
45
4090e3bb 46around new => sub {
47 my $orig = shift;
a6433a05 48 my $class = shift;
4090e3bb 49 my $self = $class->$orig;
e2422920 50
c72d2e24 51 $self->levels( scalar(@_) ? @_ : keys %LEVELS );
e2422920 52
a6433a05 53 return $self;
4090e3bb 54};
a6433a05 55
56sub levels {
57 my ( $self, @levels ) = @_;
58 $self->level(0);
59 $self->enable(@levels);
60}
61
62sub enable {
63 my ( $self, @levels ) = @_;
3cdcf968 64 my $level = $self->level;
c72d2e24 65 for(map { $LEVEL_MATCH{$_} } @levels){
3cdcf968 66 $level |= $_;
67 }
68 $self->level($level);
a6433a05 69}
846772b7 70
a6433a05 71sub disable {
72 my ( $self, @levels ) = @_;
3cdcf968 73 my $level = $self->level;
74 for(map { $LEVELS{$_} } @levels){
75 $level &= ~$_;
76 }
77 $self->level($level);
846772b7 78}
79
a6433a05 80sub _dump {
846772b7 81 my $self = shift;
f63c03e4 82 $self->info( Data::Dump::dump(@_) );
846772b7 83}
84
85sub _log {
86 my $self = shift;
87 my $level = shift;
846772b7 88 my $message = join( "\n", @_ );
1cf0345b 89 $message .= "\n" unless $message =~ /\n$/;
3cdcf968 90 my $body = $self->_body;
91 $body .= sprintf( "[%s] %s", $level, $message );
92 $self->_body($body);
4be535b1 93}
94
95sub _flush {
b5ecfcf0 96 my $self = shift;
3cdcf968 97 if ( $self->abort || !$self->_body ) {
b5ecfcf0 98 $self->abort(undef);
99 }
100 else {
3cdcf968 101 $self->_send_to_log( $self->_body );
4be535b1 102 }
3cdcf968 103 $self->_body(undef);
846772b7 104}
105
adee716c 106sub _send_to_log {
107 my $self = shift;
108 print STDERR @_;
109}
110
71415389 111# 5.7 compat code.
112# Alias _body to body, add a before modifier to warn..
113my $meta = __PACKAGE__->meta; # Calling meta method here fine as we happen at compile time.
114$meta->add_method('body', $meta->get_method('_body'));
eaae9a92 115my %package_hash; # Only warn once per method, per package.
71415389 116 # I haven't provided a way to disable them, patches welcome.
117$meta->add_before_method_modifier('body', sub {
118 my $class = blessed(shift);
119 $package_hash{$class}++ || do {
120 warn("Class $class is calling the deprecated method Catalyst::Log->body method,\n"
121 . "this will be removed in Catalyst 5.81");
122 };
123});
124# End 5.70 backwards compatibility hacks.
125
6680c772 126no Moose;
d14f9123 127__PACKAGE__->meta->make_immutable(inline_constructor => 0);
6680c772 128
846772b7 1291;
130
131__END__
fc7ec1d9 132
133=head1 NAME
134
135Catalyst::Log - Catalyst Log Class
136
137=head1 SYNOPSIS
138
82d2fcbe 139 $log = $c->log;
846772b7 140 $log->debug($message);
141 $log->info($message);
142 $log->warn($message);
143 $log->error($message);
144 $log->fatal($message);
846772b7 145
f4dbb0d9 146 if ( $log->is_debug ) {
846772b7 147 # expensive debugging
148 }
82d2fcbe 149
a6433a05 150
fc7ec1d9 151See L<Catalyst>.
152
153=head1 DESCRIPTION
154
adee716c 155This module provides the default, simple logging functionality for Catalyst.
156If you want something different set C<< $c->log >> in your application module,
157e.g.:
82d2fcbe 158
159 $c->log( MyLogger->new );
160
161Your logging object is expected to provide the interface described here.
397be447 162Good alternatives to consider are Log::Log4Perl and Log::Dispatch.
163
164If you want to be able to log arbitrary warnings, you can do something along
165the lines of
166
167 $SIG{__WARN__} = sub { MyApp->log->warn(@_); };
168
169however this is (a) global, (b) hairy and (c) may have unexpected side effects.
170Don't say we didn't warn you.
82d2fcbe 171
a6433a05 172=head1 LOG LEVELS
173
b5ecfcf0 174=head2 debug
a6433a05 175
176 $log->is_debug;
177 $log->debug($message);
178
b5ecfcf0 179=head2 info
a6433a05 180
181 $log->is_info;
182 $log->info($message);
183
b5ecfcf0 184=head2 warn
a6433a05 185
186 $log->is_warn;
187 $log->warn($message);
188
b5ecfcf0 189=head2 error
a6433a05 190
191 $log->is_error;
192 $log->error($message);
193
b5ecfcf0 194=head2 fatal
a6433a05 195
196 $log->is_fatal;
197 $log->fatal($message);
198
b22c6668 199=head1 METHODS
fc7ec1d9 200
b5ecfcf0 201=head2 new
a6433a05 202
26e73131 203Constructor. Defaults to enable all levels unless levels are provided in
a6433a05 204arguments.
205
206 $log = Catalyst::Log->new;
26e73131 207 $log = Catalyst::Log->new( 'warn', 'error' );
a6433a05 208
3cdcf968 209=head2 level
210
211Contains a bitmask of the currently set log levels.
212
b5ecfcf0 213=head2 levels
a6433a05 214
215Set log levels
b22c6668 216
a6433a05 217 $log->levels( 'warn', 'error', 'fatal' );
fc7ec1d9 218
b5ecfcf0 219=head2 enable
fc7ec1d9 220
a6433a05 221Enable log levels
fc7ec1d9 222
a6433a05 223 $log->enable( 'warn', 'error' );
fc7ec1d9 224
b5ecfcf0 225=head2 disable
fc7ec1d9 226
a6433a05 227Disable log levels
fc7ec1d9 228
a6433a05 229 $log->disable( 'warn', 'error' );
fc7ec1d9 230
b5ecfcf0 231=head2 is_debug
a2f2cde9 232
b5ecfcf0 233=head2 is_error
a2f2cde9 234
b5ecfcf0 235=head2 is_fatal
a2f2cde9 236
b5ecfcf0 237=head2 is_info
a2f2cde9 238
b5ecfcf0 239=head2 is_warn
49ba64d7 240
241Is the log level active?
242
b5ecfcf0 243=head2 abort
4be535b1 244
eaae9a92 245Should Catalyst emit logs for this request? Will be reset at the end of
246each request.
4be535b1 247
248*NOTE* This method is not compatible with other log apis, so if you plan
249to use Log4Perl or another logger, you should call it like this:
250
251 $c->log->abort(1) if $c->log->can('abort');
252
adee716c 253=head2 _send_to_log
254
255 $log->_send_to_log( @messages );
256
257This protected method is what actually sends the log information to STDERR.
258You may subclass this module and override this method to get finer control
259over the log output.
260
3cdcf968 261=head2 meta
262
fc7ec1d9 263=head1 SEE ALSO
264
265L<Catalyst>.
266
2f381252 267=head1 AUTHORS
fc7ec1d9 268
2f381252 269Catalyst Contributors, see Catalyst.pm
fc7ec1d9 270
271=head1 COPYRIGHT
272
536bee89 273This library is free software. You can redistribute it and/or modify
61b1e958 274it under the same terms as Perl itself.
fc7ec1d9 275
276=cut
277
e5ecd5bc 278__PACKAGE__->meta->make_immutable;
279
fc7ec1d9 2801;