Логирование в PHP приложениях: лучшие практики для начинающих
Логирование — это процесс записи информации о работе приложения в специальные файлы (логи). Для начинающих PHP-разработчиков умение правильно настраивать логирование так же важно, как знание синтаксиса языка. Логи помогают:
- Отлавливать ошибки, которые не видны на экране (например, в production-среде).
- Отслеживать поведение пользователей и работу системы.
- Проводить аудит безопасности.
- Ускорять отладку сложных багов.
В этой статье мы разберем лучшие практики логирования в PHP: от встроенной функции error_log() до использования профессиональных библиотек, таких как Monolog. Вы узнаете, как не засорять код, правильно выбирать уровни логирования и избегать типичных ошибок новичков.
1. Основы: встроенное логирование в PHP
Самый простой способ записать что-то в лог — использовать функцию error_log(). Она может отправлять сообщения в системный лог сервера, в указанный файл или на email.
Пример базового логирования
<?php
// Запись в системный лог (syslog)
error_log('Это сообщение об ошибке');
// Запись в конкретный файл
error_log('Ошибка подключения к БД', 3, '/var/log/my_app_errors.log');
?>
Плюсы: не требует установки библиотек, работает «из коробки».
Минусы:
- Нет гибкости (нельзя легко менять формат вывода).
- Сложно фильтровать по уровню важности.
- Неудобно при работе с несколькими каналами (файл, база данных, Slack).
Для простых скриптов и обучения этого достаточно, но для серьезных проектов стоит использовать более продвинутые решения.
2. Уровни логирования: когда и что писать
Чтобы логи были полезными, а не «шумом», важно классифицировать сообщения по уровню серьезности. Стандарт PSR-3 (который мы разберем ниже) предлагает 8 уровней:
- DEBUG — отладочная информация (значения переменных, время выполнения). Используется только на этапе разработки.
- INFO — информационные сообщения (пользователь зарегистрирован, запрос обработан).
- NOTICE — нормальные, но важные события (использование устаревшего API).
- WARNING — предупреждения (что-то пошло не так, но приложение продолжает работу, например, неверный формат ввода).
- ERROR — ошибки, требующие вмешательства (не удалось сохранить файл).
- CRITICAL — критические ошибки (основной компонент системы недоступен).
- ALERT — требует немедленного действия (взлом, отказ базы данных).
- EMERGENCY — система неработоспособна.
Пример использования уровней (без библиотек)
<?php
function logMessage($level, $message) {
$logFile = __DIR__ . '/app.log';
$timestamp = date('Y-m-d H:i:s');
$formatted = "[{$timestamp}] [{$level}] {$message}" . PHP_EOL;
file_put_contents($logFile, $formatted, FILE_APPEND);
}
logMessage('INFO', 'Пользователь вошел в систему');
logMessage('ERROR', 'Не удалось подключиться к базе данных');
?>
Совет: Никогда не пишите в лог пароли, токены или полные SQL-запросы с данными пользователей — это угроза безопасности.
3. PSR-3 и Monolog: профессиональный подход
PSR-3 — это рекомендация PHP-FIG, которая описывает единый интерфейс для библиотек логирования. Самая популярная реализация PSR-3 — Monolog. Она используется в Laravel, Symfony и многих других фреймворках.
Установка Monolog через Composer
composer require monolog/monolog
Простой пример с Monolog
<?php
require 'vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\FirePHPHandler;
// Создаем логгер
$log = new Logger('my_app');
// Добавляем обработчики (handlers)
$log->pushHandler(new StreamHandler(__DIR__ . '/app.log', Logger::DEBUG));
$log->pushHandler(new FirePHPHandler());
// Теперь можно логировать с разными уровнями
$log->info('Приложение запущено');
$log->warning('Подозрительная активность', ['ip' => '192.168.1.1']);
$log->error('Ошибка в модуле загрузки', ['file' => 'upload.php']);
?>
Что дает Monolog?
- Гибкость: вы можете одновременно писать логи в файл, отправлять в Telegram или Slack, сохранять в базу данных.
- Форматирование: легко настроить JSON, HTML или кастомный формат.
- Фильтрация: можно задать минимальный уровень (например, только WARNING и выше).
- Процессоры: автоматически добавлять в лог IP-адрес, время выполнения, имя пользователя.
Пример с несколькими каналами:
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\SwiftMailerHandler;
$log = new Logger('app');
// Все ошибки пишем в файл
$log->pushHandler(new StreamHandler('debug.log', Logger::DEBUG));
// Критические ошибки отправляем на email
$log->pushHandler(new SwiftMailerHandler($mailer, 'admin@example.com', Logger::CRITICAL));
?>
4. Лучшие практики и типичные ошибки
Чтобы логи приносили пользу, а не хаос, следуйте этим правилам:
Что нужно делать
- Используйте структурированные логи. В production лучше всего писать логи в формате JSON — их легко парсить и анализировать (ELK, Graylog).
- Ротация логов. Если не ограничивать размер файла, лог займет весь диск. Настройте ротацию (например, через
logrotateв Linux или встроенные средства Monolog).
<