这里我们假设logger()是你实现的写日志函数。
写日志
假设你的应用程序已经有日志机制。如果没有的话,最好加上。即便你不能添加,你也需要操作系统的内建日志机制。例如Linux的syslog,MS Windows的Event Logger,其它操作系统也有它们内部的日志机制。
在本文的例子里,我们使用一个自制logger()函数来代表这个想法。
捕获并写日志的完整例子
#!/usr/bin/perl
use strict;
use warnings;
local $SIG{__WARN__} = sub {
my $message = shift;
logger('warning', $message);
};
my $counter;
count();
print "$countern";
sub count {
$counter = $counter + 42;
}
sub logger {
my ($level, $msg) = @_;
if (open my $out, '>>', 'log.txt') {
chomp $msg;
print $out "$level - $msgn";
}
}
上面的代码会在log.txt文件中添加下面一行:
Use of uninitialized value in addition (+) at code_with_warnings.pl line 14.
变量$counter和函数count()仅是产生警告示例的一部分。
警告处理函数中的警告信息
__WARN__在其处理函数执行过程中是自动被禁用的。所以在警告处理函数执行过程中产生的(新)警告信息不会导致无限循环。
你可以在perlvar文档中了解到更多细节。
Avoid multiple warnings
需要注意的是重复的警告信息可能会充斥日志文件。我可以使用一个简单的类似缓存的特性来减少重复警告信息的数量。
#!/usr/bin/perl
use strict;
use warnings;
my %WARNS;
local $SIG{__WARN__} = sub {
my $message = shift;
return if $WARNS{$message}++;
logger('warning', $message);
};
my $counter;
count();
print "$countern";
$counter = undef;
count();
sub count {
$counter = $counter + 42;
}
sub logger {
my ($level, $msg) = @_;
if (open my $out, '>>', 'log.txt') {
chomp $msg;
print $out "$level - $msgn";
}
}
可以看到,我们把$counter变量赋值成undef,然后再次调用count()函数来产生同样的警告。









