/usr/share/perl5/Catalyst/Log.pm is in libcatalyst-perl 5.90115-1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 | package Catalyst::Log;
use Moose;
with 'MooseX::Emulate::Class::Accessor::Fast';
use Data::Dump;
use Moose::Util 'find_meta';
use Carp qw/ cluck /;
our %LEVELS = (); # Levels stored as bit field, ergo debug = 1, warn = 2 etc
our %LEVEL_MATCH = (); # Stored as additive, thus debug = 31, warn = 30 etc
has level => (is => 'rw');
has _body => (is => 'rw');
has abort => (is => 'rw');
has autoflush => (is => 'rw', default => sub {1});
has _psgi_logger => (is => 'rw', predicate => '_has_psgi_logger', clearer => '_clear_psgi_logger');
has _psgi_errors => (is => 'rw', predicate => '_has_psgi_errors', clearer => '_clear_psgi_errors');
sub clear_psgi {
my $self = shift;
$self->_clear_psgi_logger;
$self->_clear_psgi_errors;
}
sub psgienv {
my ($self, $env) = @_;
$self->_psgi_logger($env->{'psgix.logger'}) if $env->{'psgix.logger'};
$self->_psgi_errors($env->{'psgi.errors'}) if $env->{'psgi.errors'};
}
{
my @levels = qw[ debug info warn error fatal ];
my $meta = find_meta(__PACKAGE__);
my $summed_level = 0;
for ( my $i = $#levels ; $i >= 0 ; $i-- ) {
my $name = $levels[$i];
my $level = 1 << $i;
$summed_level |= $level;
$LEVELS{$name} = $level;
$LEVEL_MATCH{$name} = $summed_level;
$meta->add_method($name, sub {
my $self = shift;
if ( $self->level & $level ) {
$self->_log( $name, @_ );
}
});
$meta->add_method("is_$name", sub {
my $self = shift;
return $self->level & $level;
});;
}
}
around new => sub {
my $orig = shift;
my $class = shift;
my $self = $class->$orig;
$self->levels( scalar(@_) ? @_ : keys %LEVELS );
return $self;
};
sub levels {
my ( $self, @levels ) = @_;
$self->level(0);
$self->enable(@levels);
}
sub enable {
my ( $self, @levels ) = @_;
my $level = $self->level;
for(map { $LEVEL_MATCH{$_} } @levels){
$level |= $_;
}
$self->level($level);
}
sub disable {
my ( $self, @levels ) = @_;
my $level = $self->level;
for(map { $LEVELS{$_} } @levels){
$level &= ~$_;
}
$self->level($level);
}
our $HAS_DUMPED;
sub _dump {
my $self = shift;
unless ($HAS_DUMPED++) {
cluck("Catalyst::Log::_dump is deprecated and will be removed. Please change to using your own Dumper.\n");
}
$self->info( Data::Dump::dump(@_) );
}
sub _log {
my $self = shift;
my $level = shift;
my $message = join( "\n", @_ );
if ($self->can('_has_psgi_logger') and $self->_has_psgi_logger) {
$self->_psgi_logger->({
level => $level,
message => $message,
});
} else {
$message .= "\n" unless $message =~ /\n$/;
my $body = $self->_body;
$body .= sprintf( "[%s] %s", $level, $message );
$self->_body($body);
}
if( $self->autoflush && !$self->abort ) {
$self->_flush;
}
return 1;
}
sub _flush {
my $self = shift;
if ( $self->abort || !$self->_body ) {
$self->abort(undef);
}
else {
$self->_send_to_log( $self->_body );
}
$self->_body(undef);
}
sub _send_to_log {
my $self = shift;
if ($self->can('_has_psgi_errors') and $self->_has_psgi_errors) {
$self->_psgi_errors->print(@_);
} else {
binmode STDERR, ":utf8";
print STDERR @_;
}
}
# 5.7 compat code.
# Alias _body to body, add a before modifier to warn..
my $meta = __PACKAGE__->meta; # Calling meta method here fine as we happen at compile time.
$meta->add_method('body', $meta->get_method('_body'));
my %package_hash; # Only warn once per method, per package.
# I haven't provided a way to disable them, patches welcome.
$meta->add_before_method_modifier('body', sub {
my $class = blessed(shift);
$package_hash{$class}++ || do {
warn("Class $class is calling the deprecated method Catalyst::Log->body method,\n"
. "this will be removed in Catalyst 5.81");
};
});
# End 5.70 backwards compatibility hacks.
no Moose;
__PACKAGE__->meta->make_immutable(inline_constructor => 0);
1;
__END__
=for stopwords psgienv
=head1 NAME
Catalyst::Log - Catalyst Log Class
=head1 SYNOPSIS
$log = $c->log;
$log->debug($message);
$log->info($message);
$log->warn($message);
$log->error($message);
$log->fatal($message);
if ( $log->is_debug ) {
# expensive debugging
}
See L<Catalyst>.
=head1 DESCRIPTION
This module provides the default, simple logging functionality for Catalyst.
If you want something different set C<< $c->log >> in your application module,
e.g.:
$c->log( MyLogger->new );
Your logging object is expected to provide the interface described here.
Good alternatives to consider are Log::Log4Perl and Log::Dispatch.
If you want to be able to log arbitrary warnings, you can do something along
the lines of
$SIG{__WARN__} = sub { MyApp->log->warn(@_); };
however this is (a) global, (b) hairy and (c) may have unexpected side effects.
Don't say we didn't warn you.
=head1 LOG LEVELS
=head2 debug
$log->is_debug;
$log->debug($message);
=head2 info
$log->is_info;
$log->info($message);
=head2 warn
$log->is_warn;
$log->warn($message);
=head2 error
$log->is_error;
$log->error($message);
=head2 fatal
$log->is_fatal;
$log->fatal($message);
=head1 METHODS
=head2 new
Constructor. Defaults to enable all levels unless levels are provided in
arguments.
$log = Catalyst::Log->new;
$log = Catalyst::Log->new( 'warn', 'error' );
=head2 level
Contains a bitmask of the currently set log levels.
=head2 levels
Set log levels
$log->levels( 'warn', 'error', 'fatal' );
=head2 enable
Enable log levels
$log->enable( 'warn', 'error' );
=head2 disable
Disable log levels
$log->disable( 'warn', 'error' );
=head2 is_debug
=head2 is_error
=head2 is_fatal
=head2 is_info
=head2 is_warn
Is the log level active?
=head2 abort
Should Catalyst emit logs for this request? Will be reset at the end of
each request.
*NOTE* This method is not compatible with other log apis, so if you plan
to use Log4Perl or another logger, you should call it like this:
$c->log->abort(1) if $c->log->can('abort');
=head2 autoflush
When enabled (default), messages are written to the log immediately instead
of queued until the end of the request.
This option, as well as C<abort>, is provided for modules such as
L<Catalyst::Plugin::Static::Simple> to be able to programmatically
suppress the output of log messages. By turning off C<autoflush> (application-wide
setting) and then setting the C<abort> flag within a given request, all log
messages for the given request will be suppressed. C<abort> can still be set
independently of turning off C<autoflush>, however. It just means any messages
sent to the log up until that point in the request will obviously still be emitted,
since C<autoflush> means they are written in real-time.
If you need to turn off autoflush you should do it like this (in your main app
class):
after setup_finalize => sub {
my $c = shift;
$c->log->autoflush(0) if $c->log->can('autoflush');
};
=head2 _send_to_log
$log->_send_to_log( @messages );
This protected method is what actually sends the log information to STDERR.
You may subclass this module and override this method to get finer control
over the log output.
=head2 psgienv $env
$log->psgienv($env);
NOTE: This is not meant for public consumption.
Set the PSGI environment for this request. This ensures logs will be sent to
the right place. If the environment has a C<psgix.logger>, it will be used. If
not, we will send logs to C<psgi.errors> if that exists. As a last fallback, we
will send to STDERR as before.
=head2 clear_psgi
Clears the PSGI environment attributes set by L</psgienv>.
=head2 meta
=head1 SEE ALSO
L<Catalyst>.
=head1 AUTHORS
Catalyst Contributors, see Catalyst.pm
=head1 COPYRIGHT
This library is free software. You can redistribute it and/or modify
it under the same terms as Perl itself.
=cut
__PACKAGE__->meta->make_immutable;
1;
|