ДокументацияПрограммирование → Debug.pm

Используется практически всеми скриптами NoDeny и предназначен для ведения логов и вывода отладочных сообщений. Загружается самым первым, чтобы в случае критической ошибки, вывести ее в удобном и понятном виде.

Вначале вам не обязательно знать все нюансы этого модуля, фактически в 99% случаев вы будете его использовать так:

debug('Сообщение');

В админке это сообщение появится в debug-области и будет доступно при нажатии на кнопку Debug под эмблемой сети.

Примеры
    debug('Запускаем проверку балансов');
    debug('error', 'Ошибка!');
    debug('warn', "Предупреждение. У клиента uid = $uid отрицательный баланс");
    debug('Dump переменной $obj: ', $obj, ' - вот так!');
    debug(\%hash);

В примерах мы посылаем сообщения в основной Debug. Если необходимо вести несколько debug-ов/логов (врядли вам понадобится) - необходимо создать отдельный debug-объект:

perl код
    my $debug1 = Debug->new;
    my $debug2 = Debug->new;

    $debug1->add('start');
    $debug2->add('creating connection');
    $debug2->add('connection object info:', $connection);

Debug может работать в 3 режимах: web, консоль и файл. По умолчанию включен web-режим. В этом режиме данные сохраняются внутри debug-объекта и никуда не выводятся. Вывод осуществляется по команде:

    my $html = Debug->show;

Этим произойдет формирование html-фрагмента с текущим debug.

В NoDeny web-интерфейсе debug включен всегда. По мере выполнения скриптов он заполняется данными. По завершению выполнения, debug либо уничтожается либо рендерится (Debug->show) и посылается суперадминистратору. Несмотря на то, что для не суперадминистратора debug уничтожается, он все равно ведется, чтобы в случае критической ошибки все события были записаны в файл для дальнейшего изучения суперадминистратором. В этом случае web-интерфейс поступает подобным образом:

    Debug->param( -type=>'file', -file=>$cfg::debug_log, -nochain=>0 );
    Debug->show; # весь накопленный debug выводим в файл

Параметры Debug объекта, задаются методом param либо при создании объекта методом new:


    -type       : тип debug (file/console/web)
    -file       : имя файла для -type = file
    -drop_chain : 1 - не выводить цепочку подпрограмм для каждого сообщения (только для -type = file/console )
    -only_log   : 1 - заставит вести дебаг только при вызове подпрограммы tolog(), debug() будет игнорироваться

Для демонстрации, создайте файл ping.pl, вставьте в него следующий код и запустите на выполнение:

    use Debug;
    # set 0 for datail log
    my $mode = 0;
    my $log = Debug->new(
        -type       => 'file',
        -file       => 'debug.txt',
        -drop_chain => $mode,
        -only_log   => $mode,
    );
    $log->tolog('ping start');
    $log->debug("ping:", `ping -c3  127.0.0.1`);
    $log->tolog('ping end');

Результат смотрите в файле debug.txt.

С момента установки type = file/console, все последующие данные автоматически выводятся в файл/консоль, т.е. метод show вызывать не требуется.

В методах debug/tolog/add/insert первым параметром может идти одно из зарезервированных слов:

    error   : данное сообщение описывает ошибку
    warn    : данное сообщение описывает предупреждение
    pre     : сохранить форматирование
    head    : сообщение является заголовком

В случае 'error', debug-объект увеличивает свой внутренний счетчик ошибок:

    ....
    $error_msg && debug('error', $error_msg);
    ....
    $error_msg && debug('error', $error_msg);
    ....
    if( Debug->errors > 0)
    {   # произошло Debug->errors ошибок
        rollback;
    }


Замечания

Html, полученный методом show, содержит css стили, а также уникальны идентификаторы DOM, т.е допускается вывод нескольких debug в один html.

Дебаг в web-режиме обнулятся после накопления 1000 сообщений.

Многопоточность

Для переключения дебага в многопоточный режим, необходимо использовать метод threaded:

use threads;
use threads::shared;
use Debug;

Debug->param( -type=>'console' );
Debug->threaded;

threads->create( \&thread1 )->join();
threads->create( \&thread2 )->join();

sub thread1
{
   debug("thread 1: $_"), sleep 1 foreach( 1..3);
}

sub thread2
{
   debug("thread 2: $_"), sleep 1 foreach( 1..3);
}


Модуль debug-а предоставляет некоторые полезные возможности, например, формирование дампа переменных/объектов:

    use Debug;
    my $obj = { one =>  1, two => 2 };
    my $dump = Debug->dump( $obj );
    print $dump."\n";

Debug->dump использует Data::Dumper, т.е. вы можете не подгружать Data::Dumper явно через use, а использовать Debug.