yii2 Как вести log-файлы?

Как вести логирование в yii2?

yii2

Ответ

Возможность вести log-файлы полезна и на этапе знакомства с фреймворком, и в реальном проекте. В обоих случаях - для уточнения, что именно содержит переменная, или проверки, выполняется ли некоторый участок кода. Во втором случае ведение логов часто является требованием заказчика (например, при осуществлении платежей).

Логирование (по-русски: протоколирование)  можно вести:

а) в файл (FileTarget.php);
б) в системный файл посредством php-функции syslog (SyslogTarget.php);
в) на email (EmailTarget.php);
г) в базу данных (DbTarget.php);
д) любой другой ваш вариант.

Есть еще возможность профилирования.

В этом посте рассмотрим лог в файл. Конкретнее, реализуем возможность добавлять логи в файл itmathrepetitor.txt, находящийся в корне сайта (то есть около папок web, views, vendor и т.д.).

Открываем файл config/web.php и в массив $config добавляем строку 'bootstrap' => ['log'], (если она еще не добавлена, конечно).

Тем самым мы добавили log в предзагрузку.

Далее в подмассиве 'components'  изменяем/добавляем элемент 'log':

С помощью 'logVars' можно добавлять данные из переменных $_GET, $_POST, $_FILES, $_COOKIE, $_SESSION и $_SERVER. Например, 'logVars' => ['_GET', '_SERVER']. В нашем же случае никакие из этих переменных не используются (неудобно выискивать свои сообщения среди массы других).

Чтобы сообщения сразу добавлялись в файл, 'flushInterval' и 'exportInterval' установлены в 1. По умолчанию эти значения равны 1000, то есть сообщения накапливаются в памяти затем выгружаются в файл. Здесь могут быть проблемы с производительностью из-за частой выгрузки.

Уровень логирования выбран 'info'. Все варианты уровня из vendor/yiisoft/yii2/log/Target.php:

Если не указывать 'categories', то по умолчанию значение будет равно 'application' и к нашим сообщения будут добавлены многие другие. Например, подключение и запросы к базе данных.

Проверим работоспособность нашего кода. Для этого в каком-нибудь контроллере добавим строку Yii::info('test message','my_category'); и перейдем на страницу сайта, обрабатываемую этим контроллером.

В результате в itmathrepetitor.txt появятся строки:

Похоже, что задача выполнена. Но хотелось бы видеть результат лаконичнее:

Но тогда логирование получается настолько простым, что выгоднее создать обычное расширение для записи в файл без использования стандартного Logger-а (задача для самостоятельного решения). Кстати, при реализации пригодится константа php __METHOD__.

Мы же создадим в папке vendor/yiisoft/yii2/log копию файла FileTarget.php c именем MyFileTarget.php, изменим название класса в файле на MyFileTarget, добавим функцию formatMessage из файла Target.php и частично изменим ее код:

Теперь сообщения имеют нужный формат. Кстати, из кода следует, что передавать в log-файл можно не только строки, но и объекты ($text=VarDumper::export($text)).

Последнее замечание: хотелось бы вместо  Yii::info('test message','my_category');  писать Yii::show('test_message'), то есть не указывать категорию (лишние символы ведь). Напомню, что тогда по умолчанию категория равна 'application', что добавляет в log-файл дополнительные сообщения. Вторая задача для самостоятельного решения: реализовать такую возможность без изменения файла BaseYii.php. Мы же поступим, видимо, непрофессионально. Откроем файл vendor/yiisoft/yii2/BaseYii.php и добавим функцию show:

Остается проверить код Yii::show('test_message'); Для тренировки:
а) добавьте ограничение количества сообщений в файле - хранятся только последние 10;
б) каждое новое сообщение добавляется в начало файла.

Дополнительно о логировании смотрите https://github.com/yiisoft/yii2/blob/master/docs/guide-ru/runtime-logging.md и http://www.yiiframework.com/doc-2.0/yii-log-logger.html

Материалы по yii2

Факты и заблуждения профессионального программирования

 

Один комментарий к “yii2 Как вести log-файлы?

  1. Не гоже что то менять в папке vendor, правильнее будет отнаследоваться и переопределить.

    namespace app\components\log

    class MyFileTarget extends \yii\log\FileTarget
    {
    // Переопределяем, добавляем, изменяем
    public function formatMessage($message)
    {
    ...
    }
    }

    В конфиге указываем свой переопределённый класс MyFileTarget вместо FileTarget

    'log' => [
    ...
    'targets' => [
    [
    'class' => 'app\components\log\MyFileTarget',
    ...
    ],
    ],
    ...
    ],

Комментарии закрыты