Ответ
В PHP-проектах я использую библиотеку Monolog как стандарт де-факто для структурированного логирования. Моя типичная настройка включает несколько обработчиков (handlers) для разных целей.
Базовый пример инициализации логгера:
use MonologLogger;
use MonologHandlerStreamHandler;
use MonologHandlerRotatingFileHandler;
$log = new Logger('my_app');
// Основной лог-файл с ротацией по дням
$log->pushHandler(new RotatingFileHandler('/var/log/app/app.log', 7, Logger::DEBUG));
// Отдельный лог для критических ошибок
$log->pushHandler(new StreamHandler('/var/log/app/critical.log', Logger::CRITICAL));
// Логирование в консоль для разработки
if (getenv('APP_ENV') === 'dev') {
$log->pushHandler(new StreamHandler('php://stdout', Logger::DEBUG));
}
Ключевые практики, которые я применяю:
- Контекстное логирование: Всегда добавляю контекст для событий, чтобы облегчить поиск причин.
$log->error('Failed to process payment', [ 'order_id' => $orderId, 'gateway' => $gatewayName, 'user_id' => $userId ]); - Разные уровни для разных сред: В development —
DEBUG, в production —INFOи выше, чтобы не засорять логи. - Централизованный сбор в продакшене: Для production-среды настраиваю отправку логов в Sentry (для ошибок) и ELK-стек (Graylog, Loki) для агрегации и анализа, вместо хранения в локальных файлах.
- Обработка PHP-ошибок: Перенаправляю все ошибки PHP в логгер через
set_error_handler()и фатальные ошибки/исключения черезset_exception_handler()иregister_shutdown_function().