Posterous theme by Cory Watilo

Filed under: cgi::carp

Perl. Еще одна причина ненавидеть дистрибутив CGI

На сей раз речь пойдет не о CGI.pm, а об CGI::Carp.

Работая в одном очень большом проекте, наткнулся на то, что в лог пишутся warn'ы в каком-то формате, причем в скрипте явно не указан формат вывода, просто идет использование warn.
warn 'START';
В логе следующее:
[Wed Aug  6 16:17:44 2008] название_скрипта: START  at название_скрипта.pl line 16.
Причем
print STDERR 'START';
печатает в лог то, что нужно.

Начал бегать по модулям и искать перехват warn'ов ($SIG{__WARN__} или CORE::GLOBAL::warn). Ничего не нашел.
Причем перехват в самом скрипте после подключения всех модулей - удавался.
Но я никак не мог понять, кто мешает мне работать.

Закомментировал всю логику в скрипте, начал постепенно отключать модули и смотреть лог, так я нашел начальную точку - модуль, подключая который начинаются форматированные логи.
Пройдясь по цепочки подключенных модулей в нем, перебрал 6 вложенностей, я нашел, что в одном из модулей предыдущий разработчик написал зловещую строчку:
use CGI::Carp qw(cluck);
Открыл исходник CGI::Carp:

$main::SIG{__WARN__}=\&CGI::Carp::warn; # $main::SIG - жжесть :)
sub stamp {    my $time = scalar(localtime);    my $frame = 0;    my ($id,$pack,$file,$dev,$dirs);    if (defined($CGI::Carp::PROGNAME)) {        $id = $CGI::Carp::PROGNAME;    } else {        do {            $id = $file;          ($pack,$file) = caller($frame++);        } until !$file;    }    ($dev,$dirs,$id) = File::Spec->splitpath($id);    return "[$time] $id: "; # нужный формат найден :)}sub warn {    ...    my $stamp = stamp;    ...}sub cluck   { CGI::Carp::warn Carp::longmess @_; }

В итоге, прибивать использование CGI::Carp я не стал, просто пользуюсь случаем передаю привет тому, кто использует его :)
В скрипте после подключения всех модулей написал такой блок, который переопределяет настройки SIG от CGI::Carp:


BEGIN
{
require Time::HiRes;
$SIG{'__WARN__'} = sub {
CORE::warn sprintf "[%s] [%s] %s", scalar localtime, Time::HiRes::time(), @_;
};
}

Конечно, не сильно отличается от CGI::Carp, но теперь я могу формат логов как угодно менять и теперь мне не кажется, что в логи пишет какой-то шайтанище )))

Original post http://sharifulin.livejournal.com/34411.html