From 06faaf3c4a91e10597f7a0fc3a32c53a22063ec1 Mon Sep 17 00:00:00 2001 From: Aleksandr Date: Mon, 26 Oct 2015 17:30:20 +0600 Subject: [PATCH] Update translation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Есть 2 проблемы: 1. "Log Targets" перевел как "Цели логов". Так было в первой версии перевода, ничего лучше не смог придумать, 2. Подраздел "Log Targets", первое примечание "Note: The log component must be loaded during bootstrapping time so that it can dispatch log messages to targets promptly. That is why it is listed in the bootstrap array as shown above." перевел как "Примечание: Компонент `log` должен быть загружен в процессе [предзагрузки](runtime-bootstrapping.md), тогда он сможет оперативно передавать сообщения целям логов. Поэтому он указан в массиве `bootstrap`." Смысл первого предложения не переврал? --- docs/guide-ru/runtime-logging.md | 325 +++++++++++++++++++++++++------ 1 file changed, 261 insertions(+), 64 deletions(-) diff --git a/docs/guide-ru/runtime-logging.md b/docs/guide-ru/runtime-logging.md index 434eb21f5d..7cabd90976 100644 --- a/docs/guide-ru/runtime-logging.md +++ b/docs/guide-ru/runtime-logging.md @@ -1,116 +1,313 @@ Логгирование ============ -> Раздел находится в разработке +Yii предоставляет мощную, гибко настраиваемую и легко расширяемую систему логгирования. Эта система логгирования позволяет удобным способом сохранять сообщения разных типов и фильтровать их. Сообщения могут быть сохранены в файлы, базы данных или отправлены на email. -В Yii встроен гибкий и расширяемый логгер, который способен обрабатывать сообщения в соответствии с их уровнем важности и типом. -С его помощью также можно фильтровать сообщения по разными критериям и пересылать их в файлы, email, в дебаггер и т.п. +Использование Системы логгирования Yii включает следующие шаги: +* Запись [сообщений лога](#log-messages) в различных частях кода приложения; +* Настройка [целей лога](#log-targets) в конфигурации приложения; +* Изучение отфильтрованных сообщений лога, например, при помощи [Отладчика Yii](tool-debugger.md). -Основы логгирования -------------------- +В данном разделе, будем рассматривать первые два шага. -В самом простом виде логгирование - это просто вызов метода, как в примере ниже: +## Сообщения лога + +Запись сообщений лога осуществляется вызовом одного из следующих методов: + +* [[Yii::trace()]]: записывает сообщения для отслеживания выполнения кода приложения. Используется, в основном, при разработке. +* [[Yii::info()]]: записывает сообщение, содержащее какую-либо полезную информацию. +* [[Yii::warning()]]: записывает *тревожное* сообщение при возникновении неожиданного события. +* [[Yii::error()]]: записывает критическую ошибку, на которую нужно, как можно скорее, обратить внимаение. + +Эти методы позволяют записывать сообщения разных *уровней важности* и *категорий*. Они имеют одинаковое описание функции `function ($message, $category = 'application')`, где `$message` передает сообщение для записи, а `$category` - категорию сообщения. В следующем примере будет записано *trace* сообщение с категорией по умолчанию `application`: ```php -\Yii::info('Привет, я - тестовое сообщение лога'); +Yii::trace('start calculating average revenue'); ``` -Вы можете логгировать как данные строкового типа, так и более сложные структуры данных, такие как массивы и объекты. -Если логгируемые данные - не строка, обработчики логов по умолчанию сериализуют значение, используя [[yii\helpers\Vardumper::export()]]. +> Примечание: Сообщение может быть как строкой так и объектом или массивом. За корректную работу с содержимым сообщения отвечают [цели лога](#log-targets). По умолчанию, если сообщение не является строкой, оно будет приведено к строковому типу при помощи [[yii\helpers\VarDumper::export()]]. -### Категории сообщений - -Вы можете указать категорию сообщения, чтобы разделить сообщения разного типа в дальнейшем, и по разному их обработать. -Категория сообщения передается вторым аргументом методов логгирования. По умолчанию присваивается категория `application`. - -### Уровни важности - -Доступно несколько уровней важности и соответствующим им методов логгирования: - -- [[Yii::trace]] в основном используется в разработке, чтобы логгировать прогресс выполнения кода. Заметьте, что он работает только в -режиме разработки, когда константа `YII_DEBUG` имеет значение `true`. -- [[Yii::error]] используется в случае невосстановимой ошибки. -- [[Yii::warning]] используется, когда произошла ошибка, но исполнение может быть продолжено. -- [[Yii::info]] используется, чтобы фиксировать информацию о важных событиях, таких как логин администратора. - -Цели сообщений ------------------- - -Когда вызывается один из логгирующих методов, сообщение передается компоненту [[yii\log\Logger]], доступному через -`Yii::getLogger()`. Логгер хранит сообщения в памяти, и когда сообщений достаточно для отправки, или когда -заканчивается текущий запрос, отправляет сообщения по целям назначения, таким как файл или email. - - -Вы можете конфигурировать цели сообщений таким образом: +Для упрощения работы с сообщениями лога и их фильтрации, рекомендуется явно указывать подходящую категорию для каждого сообщения. Возможно использование иерархической системы именования категорий, что значительно упростит [целям лога](#log-targets) фильтрацию сообщений по категориям. Простым и эффективным способом именования категорий является использование магической PHP константы `__METHOD__`. Такой подход используется в ядре фреймворка Yii. Например, ```php -[ - 'bootstrap' => ['log'], // убеждаемся, что логгер загружается до запуска приложения +Yii::trace('начало вычисления среднего дохода', __METHOD__); +``` + +Константа `__METHOD__` вычисляется как имя метода (включая полное имя класса), в котором она использована. Например, её значение будет вычислено как `'app\controllers\RevenueController::calculate'`, если показанный выше код вызывается в соответствующем методе. + +> Информация: методы логгирования, описанные выше являются, на самом деле, ярлыками для метода [[yii\log\Logger::log()|log()]] [[yii\log\Logger|объекта логгера]], который доступен как синглтон `Yii::getLogger()`. +При определенном количестве записанных сообщений или завершении приложения, объект логгера вызывает [[yii\log\Dispatcher|message dispatcher]] для отправки записанных сообщений зарегистрированным [целям логов](#log-targets). + + +## Цели логов + +Цель логов - это экземпляр класса [[yii\log\Target]] или класса, унаследованного от него. Цель фильтрует сообщения логов по уровню важности и категории, а затем выгружает их в соответствующее хранилище. Например, [[yii\log\DbTarget|database target]] выгружает отфильтрованные сообщения логов в таблицу базы данных, а [[yii\log\EmailTarget|email target]] отправляет сообщения логов на заданные адреса email. + +При помощи компонента приложения `log` возможна регистрация нескольких целей логов. Пример конфигурации приложения: + +```php +return [ + // Компонент "log" должен быть загружен на этапе предзагрузки + 'bootstrap' => ['log'], + 'components' => [ 'log' => [ 'targets' => [ - 'file' => [ - 'class' => 'yii\log\FileTarget', - 'levels' => ['trace', 'info'], - 'categories' => ['yii\*'], - ], - 'email' => [ - 'class' => 'yii\log\EmailTarget', + [ + 'class' => 'yii\log\DbTarget', 'levels' => ['error', 'warning'], + ], + [ + 'class' => 'yii\log\EmailTarget', + 'levels' => ['error'], + 'categories' => ['yii\db\*'], 'message' => [ - 'to' => ['admin@example.com', 'developer@example.com'], - 'subject' => 'Новое сообщение логгера example.com', + 'from' => ['log@example.com'], + 'to' => ['admin@example.com', 'developer@example.com'], + 'subject' => 'Ошибки базы данных на сайте example.com', ], ], ], ], ], +]; +``` + +> Примечание: Компонент `log` должен быть загружен в процессе [предзагрузки](runtime-bootstrapping.md), тогда он сможет оперативно передавать сообщения целям логов. Поэтому он указан в массиве `bootstrap`. + +В приведенном выше коде в свойстве [[yii\log\Dispatcher::targets]] зарегистрированы две цели логов: + +* первая цель выбирает ошибки и предупреждения и сохраняет их в базу данных; +* вторая цель выбирает ошибки с категорией, имя которой начинается с `yii\db\` и шлет сразу на два адреса email `admin@example.com` и `developer@example.com`. + +На данный момент, Yii содержит следующие встроенные цели логов. В документации по API подробно описана настройка и использование этих классов. + +* [[yii\log\DbTarget]]: сохраняет сообщения логов в таблицу базы данных. +* [[yii\log\EmailTarget]]: шлет сообщения логов на заранее указанный email. +* [[yii\log\FileTarget]]: сохраняет сообщения логов в файлы. +* [[yii\log\SyslogTarget]]: сохраняет сообщения логов в системный лог используя функцию PHP `syslog()`. + +Дальше рассмотрим общие для этих четырех классов возможности. + + +### Фильтрация сообщений + +Для каждой цели можно настроить свойства [[yii\log\Target::levels|levels]] и [[yii\log\Target::categories|categories]], которые указывают уровни важности и категории сообщений логов, которые цель должна обрабатывать. + +Свойство [[yii\log\Target::levels|levels]] принимает массив, содержащий одно или несколько следующих значений: + +* `error`: соответствует сообщениям, сохраненным методом [[Yii::error()]]. +* `warning`: соответствует сообщениям, сохраненным методом [[Yii::warning()]]. +* `info`: соответствует сообщениям, сохраненным методом [[Yii::info()]]. +* `trace`: соответствует сообщениям, сохраненным методом [[Yii::trace()]]. +* `profile`: соответствует сообщениям, сохраненным методами [[Yii::beginProfile()]] и [[Yii::endProfile()]], подробнее о которых написано в подразделе [Профилирование производительности](#performance-profiling). + +Если свойство [[yii\log\Target::levels|levels]] не задано, цель логов будет обрабатывать сообщения с *любым* уровнем важности. + +Свойство [[yii\log\Target::categories|categories]] принимает массив, содержащий имена категорий или шаблоны. +Цель будет обрабатывать только те сообщения, категория которых совпадает с одним из значений или шаблонов этого массива. Шаблон категории должен состоять из префикса имени категории и звездочки `*` на конце. Имя категории совпадает с шаблоном, если оно начинается с префикса шаблона. Например, `yii\db\Command::execute` и `yii\db\Command::query` используются в качестве имен категорий сообщений, записанных в классе [[yii\db\Command]]. Оба они совпадают с шаблоном `yii\db\*`. + +Если свойство [[yii\log\Target::categories|categories]] не задано, цель будет обрабатывать сообщения любой категории. + +Кроме списка включаемый категорий, заданного свойством [[yii\log\Target::categories|categories]], при помощи свойства [[yii\log\Target::except|except]] возможно задать список исключаемых категорий. Если категория сообщения совпадает со значением или шаблоном из списка исключаемых категорий, такое сообщение не будет обработано. + +В следующем примере показан вариант конфигурации цели логов, которая должна обрабатывать только сообщения об ошибках и предупреждениях в категориях `yii\db\*` и `yii\web\HttpException:*`, за исключением `yii\web\HttpException:404`. + +```php +[ + 'class' => 'yii\log\FileTarget', + 'levels' => ['error', 'warning'], + 'categories' => [ + 'yii\db\*', + 'yii\web\HttpException:*', + ], + 'except' => [ + 'yii\web\HttpException:404', + ], ] ``` -В конфигурации выше мы назначает две цели: [[yii\log\FileTarget|file]] и [[yii\log\EmailTarget|email]]. В обоих случаях -мы фильтруем сообщения по важности, а в случае с записью в файл еще и по категории. `yii\*` значит все категории, начинающиеся с `yii\`. +> Примечание: При обработке HTTP исключения [обработчиком ошибок](runtime-handling-errors.md), сообщение будет сохранено с категорией вида `yii\web\HttpException:ErrorCode`. Например, исключение [[yii\web\NotFoundHttpException]] вызовет сообщение об ошибке с категорией `yii\web\HttpException:404`. -Каждая цель может иметь имя, и к ней можно обращаться через [[yii\log\Logger::targets|targets]] следующим образом: + +### Форматирование сообщений + +Цели логов выгружают отфильтрованные сообщения в определенном формате. Например, цель классна [[yii\log\FileTarget]] сохранит сообщение следующего формата в файле `runtime/log/app.log`: + +``` +2014-10-04 18:10:15 [::1][][-][trace][yii\base\Module::getModule] Loading module: debug +``` + +По умолчанию сообщения логов форматируются методом [[yii\log\Target::formatMessage()]]: + +``` +Временная метка [IP адрес][ID пользователя][ID сессии][Уровень важности][Категория] Текст сообщения +``` + +Этот формат может быть изменен при помощи свойства [[yii\log\Target::prefix]], которое получает анонимную функцию, возвращающую нужный префикс сообщения. Например, следующий код позволяет настроить вывод идентификатор текущего пользователя в качестве префикса для всех сообщений. + +```php +[ + 'class' => 'yii\log\FileTarget', + 'prefix' => function ($message) { + $user = Yii::$app->has('user', true) ? Yii::$app->get('user') : null; + $userID = $user ? $user->getId(false) : '-'; + return "[$userID]"; + } +] +``` + +Кроме префиксов сообщений, также возможно добавление общей информации для каждого набора сообщений лога. +По умолчанию, включаются значения следующих глобальных PHP переменных: `$_GET`, `$_POST`, `$_FILES`, `$_COOKIE`, +`$_SESSION` и `$_SERVER`. Эта возможность настраивается при помощи свойства [[yii\log\Target::logVars]], содержащего массив имен переменных, которые необходимо включить в лог. Например, следующий код позволяет настроить цель логов так, чтобы к сообщениям присоединялось только содержимое переменной `$_SERVER`. + +```php +[ + 'class' => 'yii\log\FileTarget', + 'logVars' => ['_SERVER'], +] +``` + +При задании значением свойства `logVars` пустого массива, общая информация не будет выводиться. +Для определения собственного алгоритма подключения общей информации, следует переопределить метод [[yii\log\Target::getContextMessage()]]. + + +### Уровень отслеживания выполнения кода + +В процессе разработки, часто бывает необходимость видеть источники сообщений. Для этого нужно использовать свойство [[yii\log\Dispatcher::traceLevel|traceLevel]] компонента `log`. Например, + +```php +return [ + 'bootstrap' => ['log'], + 'components' => [ + 'log' => [ + 'traceLevel' => YII_DEBUG ? 3 : 0, + 'targets' => [...], + ], + ], +]; +``` + +При такой настройке свойство [[yii\log\Dispatcher::traceLevel|traceLevel]] будет равно 3 при `YII_DEBUG` равном `true` и 0 при `YII_DEBUG` равном `false`. Это означает, что при включенном `YII_DEBUG`, каждое сообщение лога будет содержать до трех уровней стека вызовов, а при выключенном `YII_DEBUG` информация о стеке вызовов не будет включаться в лог. + +> Информация: Получение информации стека вызовов является не простым процессом. Поэтому такую возможность следует использовать только при разработке или отладке приложения. + + +### Передача на обработку и выгрузка сообщений + +Как упоминалось выше, сообщения логов обрабатываются в массиве [[yii\log\Logger|объектом логгера]]. Для ограничения объема памяти, занятого этим массивом, при накоплении определенного числа сообщений, логгер передает их на обработку [целям логов](#log-targets). Максимальное количество сообщений определяется свойством [[yii\log\Dispatcher::flushInterval|flushInterval]] компонента `log`: + +```php +return [ + 'bootstrap' => ['log'], + 'components' => [ + 'log' => [ + 'flushInterval' => 100, // по умолчанию 1000 + 'targets' => [...], + ], + ], +]; +``` + +> Информация: При завершении приложения, так же происходит передача сообщений на обработку. + +После передачи сообщений [[yii\log\Logger|объектом логгера]] в [цели логов](#log-targets), сообщения не выгружаются немедленно. Вместо этого, выгрузка сообщений происходит когда цель логов накопит определенное количество фильтрованных сообщений. Максимальное количество сообщений определяется свойством [[yii\log\Target::exportInterval|exportInterval]] [цели логов](#log-targets). Например, + +```php +[ + 'class' => 'yii\log\FileTarget', + 'exportInterval' => 100, // по умолчанию 1000 +] +``` + +Из-за того, что значения максимального количества сообщений для передачи и выгрузки по умолчанию достаточно велико, при вызове метода `Yii::trace()`, или любого другого метода логгирования, сообщение не появится сразу в файле или таблице базы данных. Такое поведение может стать проблемой, например, в консольных приложениях с большим временем исполнения. Для того, чтобы все сообщения логов сразу же попадали в лог, необходимо установить значения свойств [[yii\log\Dispatcher::flushInterval|flushInterval]] и [[yii\log\Target::exportInterval|exportInterval]] равными 1, например так: + +```php +return [ + 'bootstrap' => ['log'], + 'components' => [ + 'log' => [ + 'flushInterval' => 1, + 'targets' => [ + [ + 'class' => 'yii\log\FileTarget', + 'exportInterval' => 1, + ], + ], + ], + ], +]; +``` + +> Примечание: Частая передача и выгрузка сообщений может сильно снизить производительность приложения. + + +### Переключение целей логов + +Свойство [[yii\log\Target::enabled|enabled]] отвечает за включение или отключение цели логов. Возможно управлением этим свойством как в конфигурации приложения, так и при помощи следующего PHP кода: ```php Yii::$app->log->targets['file']->enabled = false; ``` -Когда приложение заканчивает работу, или когда достигнут предел количества сообщений [[yii\log\Logger::flushInterval|flushInterval]], логгер -вызовет метод [[yii\log\Logger::flush()|flush()]] для отправки сообщений по маршрутам. +В данном примере используется цель логов `file`, которая может быть настроена в конфигурации приложения следующим образом: -> Обратите внимание, что в примере выше мы добавили компонент `log` в список [автозагрузки](runtime-bootstrapping.md) компонентов, чтобы -он инициализировался в самом начале жизненного цикла приложения, чтобы, в свою очередь, убедиться, что логгирование будет происходить с самого начала -приложения. +```php +return [ + 'bootstrap' => ['log'], + 'components' => [ + 'log' => [ + 'targets' => [ + 'file' => [ + 'class' => 'yii\log\FileTarget', + ], + 'db' => [ + 'class' => 'yii\log\DbTarget', + ], + ], + ], + ], +]; +``` -Профилирование --------------- +### Создание новых целей -Профилирование - особый тип сообщений, который может быть использован для замера времени, необходимого определенным -блокам кода для отработки, чтобы выяснить, где можно улучшить производительность. +Создание новой цели логов не является сложной задачей. В общем случае, нужно реализовать метод [[yii\log\Target::export()]], выгружающий массив [[yii\log\Target::messages]] в место хранения логов. Возможно использование метода [[yii\log\Target::formatMessage()]] для форматирования сообщения. Детали реализации можно подсмотреть в исходном коде любого из классов целей логов, включенных в состав Yii. -Чтобы пользоваться профилированием нужно понять, какие блоки кода нужно профилировать. Затем нужно отметить начало и конец каждого блока, вызывая -нижеследующие методы: + +## Профилирование производительности + +Профилирование производительности - это специальный тип сообщений логов, используемый для измерения времени выполнения определенных участков кода и определения проблем производительности. Например, класс [[yii\db\Command]] использует профилирование производительности для определения времени исполнения каждого запроса базы данных. + +Для использования профилирования производительности нужно определить участок кода для измерения и *обернуть* его вызовами методов [[Yii::beginProfile()]] и [[Yii::endProfile()]]. Например, ```php \Yii::beginProfile('myBenchmark'); -...блок кода для профилирования... + +...участок кода для профилирования... + \Yii::endProfile('myBenchmark'); ``` -где `myBenchmark` - уникальный идентификатор блока кода. +где `myBenchmark` является уникальным идентификатором данного измеряемого участка кода. +В дальнейшем, при изучении результатов профилирования, уникальный идентификатор поможет определить время выполнения соответствующего участка кода. -Заметьте, что блоки кода должны быть правильно вложены друг в друга. Посмотрите пример ниже: +Очень важно соблюдать уровни вложенности пар `beginProfile` и `endProfile`. Например, ```php \Yii::beginProfile('block1'); - // код блока 1 + + // код для профилирования + \Yii::beginProfile('block2'); - // код блока два, который входит в блок один + // другой код для профилирования \Yii::endProfile('block2'); + \Yii::endProfile('block1'); ``` -Результаты профилирования [можно отображать в дебаггере](module-debug.md). +Если пропустить `\Yii::endProfile('block1')` или поменять местами `\Yii::endProfile('block1')` и +`\Yii::endProfile('block2')`, профилирование производительности не будет работать. + +Для каждого участка кода, будет записано сообщение лога с уровнем важности `profile`. Для сбора таких сообщений можно настроить [цель логов](#log-targets) или воспользоваться [Отладчиком Yii](tool-debugger.md), который имеет встроенную панель профилирования производительности, отображающую результаты измерений.