Ваше PHP-приложение не говорит, ему кричат
Представьте, что вы — капитан космического корабля. Ваша задача — долететь до Марса. Но на корабле нет приборов, нет датчиков, нет даже кнопки "аварийная сигнализация". Вы просто летите, надеясь на лучшее. Примерно так чувствует себя разработчик, который запускает PHP-приложение в production без мониторинга и логирования.
Пользователи видят "500 Internal Server Error", а вы — только пустой экран логов. Знакомо? Если нет — вы либо гений, либо просто еще не столкнулись с падением боевого сервера в 3 часа ночи.
В этой статье мы разберем, как превратить ваше PHP-приложение из "черного ящика" в прозрачную систему, которая сама расскажет, где и почему упала. Я покажу реальный код, лучшие практики и инструменты, которые используют в продакшене крупные проекты. Поехали.
Почему логирование в PHP — это не просто "echo"
Многие новички думают, что логирование — это:
echo "Тут ошибка: " . $error;
Спойлер: это не работает в production. Пользователь увидит эту "красоту" на экране. А если ошибка фатальная — вы вообще ничего не узнаете.
Настоящее логирование — это структурированный сбор данных, которые можно анализировать, искать по ним и реагировать в реальном времени. PHP предоставляет базовые функции (error_log(), syslog()), но в современном мире этого недостаточно.
Что должно быть в хорошем логе?
- Уровень серьезности — DEBUG, INFO, WARNING, ERROR, CRITICAL
- Временная метка — точное время события (желательно в UTC)
- Контекст — ID пользователя, IP, URL, данные запроса
- Стек вызовов — trace ошибки
- Уникальный идентификатор запроса — чтобы связать все логи одного действия
Monolog — стандарт логирования в PHP
Если вы пишете на PHP и не используете Monolog — вы теряете время. Это де-факто стандарт для логирования, который поддерживается Symfony, Laravel и большинством современных фреймворков.
Почему Monolog крут?
- Гибкие "обработчики" (handlers) — можно писать в файл, БД, Telegram, Slack, email
- Форматеры — JSON, HTML, Syslog
- Процессоры — добавляют контекст автоматически
Установка и базовый пример
composer require monolog/monolog
А теперь напишем простой логгер:
<?php
require 'vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Handler\TelegramBotHandler;
use Monolog\Level;
// Создаем логгер с именем канала
$log = new Logger('my_app');
// Пишем в файл
$log->pushHandler(
new StreamHandler(__DIR__ . '/logs/app.log', Level::Debug)
);
// Критические ошибки — в Telegram
$log->pushHandler(
new TelegramBotHandler(
'YOUR_BOT_TOKEN',
'YOUR_CHAT_ID',
Level::Critical
)
);
// Используем
$log->info('Пользователь залогинился', ['user_id' => 123]);
$log->error('База данных недоступна', ['db_host' => 'localhost']);
Обратите внимание: мы используем разные обработчики для разных уровней. В файл пишется всё (отладка), а в Telegram — только критическое. Это позволяет не спамить уведомлениями, но не пропустить реальную проблему.
Мониторинг PHP: как увидеть то, что скрыто
Логирование — это пассивный сбор данных. Мониторинг — активное наблюдение и оповещение. Если пользователь сообщает вам об ошибке — вы уже опоздали. Хороший мониторинг предупредит вас до того, как проблема затронет пользователей.
Sentry — must have для PHP разработчика
Sentry — это система отслеживания ошибок в реальном времени. Она ловит исключения, собирает контекст, стек вызовов и даже данные сессии. Установка занимает 5 минут.
composer require sentry/sdk
Пример интеграции:
<?php
require 'vendor/autoload.php';
Sentry\init([
'dsn' => 'https://your-dsn@sentry.io/123456',
'environment' => 'production',
'release' => '1.0.0',
]);
// Теперь все необработанные исключения будут отправлены в Sentry
set_exception_handler(function (\Throwable $e) {
Sentry\captureException($e);
// Ваша стандартная обработка
http_response_code(500);
echo 'Что-то пошло не так. Мы уже знаем об этом.';
});
Sentry показывает не просто ошибку, а полную картину: сколько пользователей затронуто, на каких браузерах, какие действия предшествовали сбою. Это бесценно для отладки production-среды.
Структурированное логирование: JSON — ваш друг
Текстовые логи — это прошлый век. Когда у вас 10 серверов и миллионы запросов в день, читать логи глазами невозможно. Нужна структура.
Лучший формат для логов — JSON. Он легко парсится, индексируется Elasticsearch и анализируется Kibana (стек ELK).
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Monolog\Formatter\JsonFormatter;
$log = new Logger('json_app');
$handler = new StreamHandler('php://stdout', Level::Debug);
$handler->setFormatter(new JsonFormatter());
$log->pushHandler($handler);
$log->info('Запрос обработан', [
'method' => $_SERVER['REQUEST_METHOD'],
'uri' => $_SERVER['REQUEST_URI'],
'duration_ms' => 145,
]);
Результат в логе будет выглядеть так:
{"message":"Запрос обработан","context":{"method":"GET","uri":"/api/users","duration_ms":145},"level":200,"level_name":"INFO","channel":"json_app","datetime":"2025-01-15T10:30:00.123456+00:00"}
Такой лог можно отправить в Graylog, ELK или Loki и строить дашборды в реальном времени.
Мониторинг производительности PHP-приложений
Ошибки — это плохо. Но медленное приложение — иногда еще хуже. Пользователь уйдет, если страница грузится дольше 3 секунд. Как отслеживать производительность?
XHProf и XHProf.io
XHProf — это профайлер от Facebook. Он показывает, какие функции сколько времени занимают. Установка:
pecl install xhprof
Но для production лучше использовать Tideways или Blackfire.io — они менее требовательны к ресурсам.
Самописный мониторинг времени выполнения
Ин