Perl中警告传播的最佳实践

时间:2014-03-06 23:02:56

标签: perl logging warnings

是否有一个已建立的最佳实践,用于处理perl程序中的不同类别的警告,例如,记录到syslog(或实际上是非标准行为)?

例如,要向syslog发送警告:

$SIG{__WARN__} = sub {
    syslog(LOG_ERR,shift);
}

但现在想象并非所有警告都是平等的。有些人应该被视为噪音和降级。例如,许多MIME警告并未真正表明存在严重问题:

  

忽略字符集“WINDOWS-1252”中的文字       在/usr/share/perl5/MIME/Parser/Filer.pm第659行

例如,这可以更好地记录为LOG_INFO或其他一些不会提醒管理员注意问题的优先级。

实现这一目标的最佳方法是什么?

一个简单的解决方案可能是:

$SIG{__WARN__} = sub {
    my $msg = shift;
    my $prio = $msg =~ /(ignoring|Filer.pm)/ ? LOG_INFO : LOG_ERR;
    syslog($prio,$msg)
}

但是这需要我的代码和它调用的任何库之间的(IMO)不合需要的紧密耦合,必须仔细匹配警告消息......而且它也不是很优雅或可维护。

我看到的一个可能的解决方案是,当我控制代码时,稍微改进一点就是确保我的警告都有一个前缀:

warn "MIME parsing error: $@";

这使警告处理程序更简单:

$SIG{__WARN__} = sub {
    my $msg = shift;
    my $prio = $msg =~ /^MIME parsing error:/ ? LOG_INFO : LOG_ERR;
    syslog($prio,$msg)
}

但是,对警告进行字符串解析以确定其分类似乎仍然不够优雅。

还有更优雅的解决方案吗?我正在寻找通用的最佳实践 - 即使它要求重写所有警告发布库。

1 个答案:

答案 0 :(得分:2)

与异常对象类似,您可以引入警告对象:

$SIG{__WARN__} = sub {
    my $w = shift;
    if ($w->is_info) {
        print STDERR 'INFO:', $w->msg, "\n";
    }
};

warn 'My::Warning'->new( msg      => 'problem',
                         severity => 'info',
                        );