Журналирование ошибок и лучшие практики
Записывайте ошибки в файлы и следуйте шаблонам обработки ошибок в рабочей среде
«Журналирование ошибок и лучшие практики» — бесплатный урок PHP Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения PHP Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс PHP Academy содержит 4 уроков всего.
Зачем нужно журналирование
В рабочей среде нельзя показывать ошибки пользователям, но необходимо знать, когда что-то пошло не так. Журналирование сохраняет сведения об ошибках в файлах или службах, чтобы позднее можно было провести расследование.
error_log()
Самая простая функция журналирования — записывает сообщение в журнал ошибок PHP:
<?php
error_log('User login failed for: ' . $email);
error_log('DB query took: ' . $duration . 'ms');
// Send to email (not recommended for high traffic)
error_log('Critical: server out of memory', 1, 'admin@example.com');Структурированное журналирование
Записывайте структурированные данные в формате JSON, чтобы упростить их разбор и поиск:
<?php
function logEvent(string $level, string $message, array $context = []): void {
$entry = array_merge([
'ts' => date('c'),
'level' => $level,
'message' => $message,
], $context);
error_log(json_encode($entry));
}
logEvent('ERROR', 'Payment failed', [
'order_id' => 123,
'amount' => 99.99,
'user_id' => 45,
]);Уровни журнала (PSR-3)
PSR-3 определяет стандартные уровни журнала:
- emergency — система не работает
- alert — необходимо принять меры
- critical — критические условия
- error — ошибки во время выполнения
- warning — исключительные ситуации, которые не являются ошибками
- notice — обычные, но значимые события
- info — информационные сообщения
- debug — подробные сведения для отладки
Регистратор Monolog
Monolog — стандартная библиотека журналирования PHP, совместимая с PSR-3:
<?php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$log = new Logger('app');
$log->pushHandler(new StreamHandler('/var/log/app.log', Logger::DEBUG));
$log->info('User logged in', ['user_id' => 42]);
$log->error('Payment failed', ['order' => 99, 'reason' => 'card_declined']);
$log->warning('Slow query', ['duration_ms' => 3200]);Обработка исключений в рабочей среде
Обработчик исключений для рабочей среды: он записывает сведения в журнал и возвращает безопасный ответ:
<?php
set_exception_handler(function(\Throwable $e) {
$id = uniqid('err_');
error_log(json_encode([
'error_id' => $id,
'class' => get_class($e),
'message' => $e->getMessage(),
'file' => $e->getFile(),
'line' => $e->getLine(),
'trace' => $e->getTraceAsString(),
]));
http_response_code(500);
echo json_encode(['error' => 'Server error', 'id' => $id]);
exit(1);
});Ротация журналов
Файлы журналов растут бесконечно — ротируйте их с помощью logrotate в Linux или обработчиков Monolog, работающих по времени:
<?php
use Monolog\Handler\RotatingFileHandler;
$handler = new RotatingFileHandler(
'/var/log/app.log',
30, // keep 30 days
Logger::DEBUG
);
// Creates dated files: app-2024-05-27.log
$log = new Logger('app');
$log->pushHandler($handler);Журналирование с подробным контекстом
Добавляйте контекст запроса в каждую запись журнала для упрощения отладки:
<?php
function getRequestContext(): array {
return [
'url' => $_SERVER['REQUEST_URI'] ?? '',
'method' => $_SERVER['REQUEST_METHOD'] ?? '',
'ip' => $_SERVER['REMOTE_ADDR'] ?? '',
'user_id' => $_SESSION['user_id'] ?? null,
];
}
// Add to every log call:
$log->error('Order failed', array_merge(
getRequestContext(),
['order_id' => $orderId]
));Как не допустить попадания конфиденциальных данных в журналы
Никогда не записывайте в журнал конфиденциальную информацию:
- Пароли и токены
- Номера банковских карт
- Персональные данные (для соблюдения требований GDPR)
- Полные трассировки стека исключений в ответах, видимых пользователям
<?php
// Bad:
error_log('Login attempt: ' . $email . ' / ' . $password);
// Good:
error_log('Login failed for user: ' . substr($email, 0, 3) . '***');Sentry и внешнее отслеживание ошибок
В рабочей среде используйте службы отслеживания ошибок, например Sentry, чтобы централизовать ошибки и получать уведомления о них:
<?php
// After composer require sentry/sdk
\Sentry\init(['dsn' => getenv('SENTRY_DSN')]);
// Automatic capture of unhandled exceptions
// Manual capture:
try {
processOrder();
} catch (\Throwable $e) {
\Sentry\captureException($e);
throw $e;
}Предварительные условия на основе утверждений
Используйте утверждения, чтобы обнаруживать ошибки программирования при разработке:
<?php
// assert() throws AssertionError when false (dev mode)
assert(is_int($userId), 'userId must be an integer');
assert($amount > 0, 'amount must be positive');
// Or throw explicitly:
if (!is_int($userId)) {
throw new \InvalidArgumentException('userId must be int');
}Быстрая проверка
Согласно PSR-3, какой уровень журнала указывает на ситуацию, требующую немедленного внимания?
Итоги: журналирование ошибок
Лучшие практики журналирования:
- Используйте структурированное журналирование в формате JSON с временной меткой, уровнем, сообщением и контекстом
- Следуйте уровням журнала PSR-3
- Используйте Monolog в рабочих приложениях
- Ротируйте журналы, чтобы не допустить заполнения диска
- Никогда не записывайте в журнал пароли и конфиденциальные данные
- Используйте Sentry или аналогичный инструмент для отслеживания ошибок в реальном времени
Часто задаваемые вопросы
Урок «Журналирование ошибок и лучшие практики» бесплатный?
Да — полный текст урока «Журналирование ошибок и лучшие практики» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс PHP Academy, подпишись на CoddyKit PRO. Курс PHP Academy содержит 4 уроков всего.
Чему я научусь в уроке «Журналирование ошибок и лучшие практики»?
Записывайте ошибки в файлы и следуйте шаблонам обработки ошибок в рабочей среде Ты практикуешь PHP Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать PHP Academy?
Предыдущий опыт не требуется. PHP Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Журналирование ошибок и лучшие практики»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке PHP Academy?
Да. Каждый урок PHP Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Типы ошибок PHP и их отчётность
- Try, Catch и Finally
- Создание пользовательских исключений
- Журналирование ошибок и лучшие практики