Yii предоставляет гибкий и расширяемый функционал протоколирования. Сообщения можно классифицировать в соответствии с уровнем протоколирования и типом сообщений. Используя фильтры по уровню и категории, можно направить поток сообщений в файлы, электронную почту, окно браузера и т.д.
Сообщение может быть запротоколировано путем вызова Yii::log или Yii::trace. Разница между ними заключается в том, что последний пишет в лог только тогда, когда приложение работает в режиме отладки.
Yii::log($message, $level, $category);
Yii::trace($message, $category);
Для внесения сообщения в лог, необходимо указать категорию и уровень сообщения.
Категория представляет собой строку формата xxx.yyy.zzz
, что очень схоже с форматом
представления псевдонима пути. Например, если сообщение
добавляется в лог в CController, мы можем использовать категорию system.web.CController
.
Уровень сообщения может иметь одно из следующих значений:
trace
: этот уровень используется методом Yii::trace. Он предназначен для отслеживания процесса выполнения
приложения в ходе разработки;
info
: этот уровень предназначен для протоколирования информации общего характера;
profile
: данный уровень используется для профилирования (измерения) производительности;
warning
: этот уровень предназначен для сообщений-предупреждений;
error
: этот уровень используется для сообщений о критических ошибках.
Сообщения, протоколируемые с использованием Yii::log или Yii::trace, хранятся в памяти. Как правило, нам требуется либо отобразить их в окне браузера, либо сохранить в файле, отправить электронным письмом и пр. Направление сообщений в различные места назначения называется маршрутизацией сообщений.
В Yii за маршрутизацию сообщений отвечает компонент приложения CLogRouter. Этот компонент управляет множеством так называемых маршрутов сообщений. Каждый маршрут представляет одно место назначения потока сообщений. Сообщения, направляемые по тому или иному маршруту, можно отфильтровать в зависимости от их уровня и типа.
Для того, чтобы воспользоваться маршрутизацией сообщений, нам необходимо установить и подгрузить заранее компонент приложения CLogRouter. Кроме того, необходимо настроить свойство routes этого компонента, указав маршруты сообщений, которые предполагается использовать. Ниже приведен пример необходимой конфигурации приложения:
array(
......
'preload'=>array('log'),
'components'=>array(
......
'log'=>array(
'class'=>'CLogRouter',
'routes'=>array(
array(
'class'=>'CFileLogRoute',
'levels'=>'trace, info',
'categories'=>'system.*',
),
array(
'class'=>'CEmailLogRoute',
'levels'=>'error, warning',
'emails'=>'admin@example.com',
),
),
),
),
)
В примере выше, у нас есть два маршрута сообщений. Первый - CFileLogRoute - сохраняет сообщения в
папке приложения для временных файлов runtime
. Сохраняются только сообщения с уровнем trace
или info
и чья
категория начинается с system.
. Второй маршрут - CEmailLogRoute - отправляет сообщения на указанный электронный адрес.
Отправляются только сообщения уровня error
или warning
.
В Yii доступны для использования следующие маршруты сообщений:
Информация: Маршрутизация сообщения происходит в конце каждого текущего цикла обработки запроса, в момент, когда вызывается событие onEndRequest. Для прерывания процесса обработки текущего запроса, используйте метод CApplication::end() вместо
die()
илиexit()
. CApplication::end() вызывает событие onEndRequest, что позволяет корректно запротоколировать сообщения.
Как уже упоминалось выше, сообщения можно отфильтровать по их уровню и типу до того, как они будут направлены тем или иным маршрутом. Это осуществляется путем настройки свойств levels и categories соответствующего маршрута. Если необходимо указать несколько уровней или типов, значения должны быть разделены запятыми.
Поскольку типы сообщений указываются в формате xxx.yyy.zzz
, мы можем воспринимать их как иерархию типов.
В частности, мы говорим, что xxx
является родителем xxx.yyy
, а последний в свою очередь является
родителем для xxx.yyy.zzz
. Поэтому для указания типа xxx
, а также всех его типов-потомков можно
использовать выражение xxx.*
.
Начиная с версии 1.0.6, мы можем сохранять дополнительную информацию, такую как
предопределённые переменные PHP ($_GET
, $_SERVER
), ID сессии, имя
пользователя и т.д. Для этого необходимо задать необходимый фильтр в
свойстве CLogRoute::filter.
В состав фреймворка входит удобный класс CLogFilter, который может быть использован
в качестве фильтра в большинстве случаев. По умолчанию, CLogFilter будет записывать
сообщение вместе с такими переменными, как $_GET
и $_SERVER
, которые обычно
содержат ценную системную информацию. Можно настроить CLogFilter таким образом,
чтобы перед каждым сообщением записывать ID сессии, имя пользователя и другие данные,
которые могут облегчить поиск по большому количеству сообщений.
Следующие настройки включают запись контекста сообщений. У каждого журнального маршрута может быть задан свой фильтр. По умолчанию никакого фильтра не задано.
array(
......
'preload'=>array('log'),
'components'=>array(
......
'log'=>array(
'class'=>'CLogRouter',
'routes'=>array(
array(
'class'=>'CFileLogRoute',
'levels'=>'error',
'filter'=>'CLogFilter',
),
...other log routes...
),
),
),
)
Начиная с версии 1.0.7, Yii поддерживает журналирование информации стека вызова
в сообщениях, протоколируемых путем вызова Yii::trace. По умолчанию, данная
особенность отключена, т.к. снижает производительность. Для ее использования,
необходимо просто определить константу YII_TRACE_LEVEL
в начале входного
скрипта (до включения файла yii.php
) целым числом большим нуля. Тогда
Yii будет добавлять в каждое трассирующее сообщение имя файла и номер строки
стека вызова, в которых был сделан вызов кода. Число YII_TRACE_LEVEL
определяет количество слоев каждого стека вызова, которое должно быть записано.
Эта информация особенно полезна на стадии разработки, так как может помочь нам
определить места, в которых вызываются трассирующие сообщения.
Для целей измерения производительности используется специальный тип сообщений. Его можно использовать для измерения времени исполнения некоторого блока кода и определения узких мест в производительности.
Для того, чтобы измерить производительность, необходимо указать ту часть кода, выполнение которой будет отслеживаться. Используя следующие методы, мы отмечаем начало и конец каждого измеряемого блока кода:
Yii::beginProfile('blockID');
...блок профилируемого кода...
Yii::endProfile('blockID');
где blockID
- это уникальный идентификатор блока кода.
Обратите внимание, что блоки кода должны иметь корректную вложенность, т.е. они не могут пересекаться друг с другом. Они либо идут параллельно, либо один блок полностью включает другой.
Для того, чтобы увидеть результат профилирования, нам потребуется установить компонент приложения CProfileLogRoute, отвечающий за соответствующий маршрут протоколирования. Здесь все аналогично работе с простыми маршрутами сообщений. Маршрут CProfileLogRoute отобразит результаты измерения производительности внизу текущей страницы.
Профилирование особенно полезно при работе с базой данных, так как SQL-запросы
часто являются самым узким местом производительности приложения. Несмотря на то,
что мы можем вставить в нужные места beginProfile
и endProfile
для того, чтобы
замерить время, затраченное на каждый SQL-запрос, начиная с версии 1.0.6 Yii предоставляет
более удобное решение данной проблемы.
Выставив в настройках приложения CDbConnection::enableProfiling в true, мы получим профилирование всех выполняемых SQL-запросов. Полученные результаты можно вывести при помощи вышеупомянутого CProfileLogRoute, показывающего, какой SQL-запрос сколько времени занял. Для вывода общего количества запросов и общего времени выполнения можно использовать CDbConnection::getStats().
Signup or Login in order to comment.