💡 Совет

Рассылка error.log

19.11.2019 1 минута чтения

Не все ошибки может отследить разработчик, многие появляются в процессе использования ПО, в зависимости от окружения и т.д. Для меня очень важно отслеживать такие возможные баги, особенно на этапе запуска проекта. Я сильно не ухищрялся, просто периодически просматривал содержимое error.log файлов. Но проектов, которые приходится поддерживать, становится всё больше, на многих из них развернуто по несколько серверов. В итоге для меня эта операция стала довольно трудоемкой. Естественно, это дело нужно автоматизировать.

В интернете есть серьезные решения для Enterprise-проектов, но мне хотелось чего-то простого, что с легкостью можно было бы установить на любой сервер. Итак, я описал необходимые мне задачи:

  1. Скрипт должен запускаться с какой-то периодичностью
  2. Должен выбирать ошибки за последний период, фильтровать их
  3. Отправлять на email
  4. Очищать error.log файл

С первым пунктом легко справится CRON. Скрипт нашей рассылки будет обычным php-файлом, который будет вызываться планировщиком задач. Я его запускаю каждый час, чтобы быть всегда готовым быстро что-то исправить:

0 * * * * php /var/www/alm/alm.php

Потом на практике я увидел, что везде формат error.log файла разный. Это зависит или от версии Apache, или от PHP, или от сборки. Поэтому парсить строки для фильтрации было трудно. Заметил я только одно общее место, которого мне и было достаточно, а фильтрация мне была нужна для того, чтобы настроить отправляемые мне типы ошибок. Так вот, во всех PHP-ошибках будет присутствовать «PHP Warning», «PHP Notice» и т.д. Я и сделал фильтр по этим ключам. Пример конфига (config.php):

//php
return array(
    // ApacheLM will send log to this email
    'email'           => 'alexander.plutov@gmail.com',
    // Full path to the error log file
    'errorLogFile'    => '/var/log/apache2/error.log',
    // Fetch only these error types. Comment or remove if you don't need to get some types in mail.
    'errorTypes'      => array('Warning', 'Notice', 'Fatal')
);

Сам мэйлер alm.php после себя очищает файл error.log. Не знаю, правильно это или нет, но меня напрягают эти здоровые файлы. Отправка реализована при помощи функции mail. Пока с ней проблем не было, но не исключаю, что, возможно, когда-нибудь заменю эту часть на работу с SMTP.

//php
// Don't log possible errors in this script
error_reporting(0);

$conf = include_once 'config.php';

$records = getLogRecords($conf);
if (count($records)) {
    sendEmail($conf, $records);
}
resetErrorLog($conf);

function getLogRecords($conf) {
    $lines = array_reverse(file($conf['errorLogFile']));

    $recordsMatch = array();

    foreach ($lines as $line) {
        $line = trim($line);
        if (matchLine($conf, $line) && $line) {
            $recordsMatch[] = $line;
        }
    }

    return $recordsMatch;
}

function matchLine($conf, $line) {
    foreach ($conf['errorTypes'] as $errorType) {
        if (false !== mb_strpos($line, 'PHP ' . $errorType)) {
            return true;
        }
    }

    return false;
}

function sendEmail($conf, $records) {
    $subject = count($records) . ' errors at ' . date('Y-m-d H:i:s');
    $body    = '';
    foreach ($records as $record) {
        $body .= $record . "\n\n";
    }
    mail($conf['email'], $subject, $body);
}

function resetErrorLog($conf) {
    file_put_contents($conf['errorLogFile'], '');
}

Когда я запустил это на всех серверах, то мне в день приходило по ~50 писем, это был хороший стимул для баг фиксинга. Теперь приходит 2-3 письма в день.

Экспертное мнение Алексей

В веб-разработке с 2012 года. Специализируюсь на PHP, JavaScript и архитектуре высоконагруженных проектов. Автор статей по оптимизации, API и базам данных.

Все статьи автора →
Telegram VK Twitter
Читайте также
FULL OUTER JOIN
FULL OUTER JOIN
На практике я столкнулся с ситуацией, когда нужно было выбрать данные из двух связанных сущностей при помощи полного соединения. К...
Senior PHP Developer. Упрощенный T9 алгоритм
Senior PHP Developer. Упрощенный T9 алгоритм
Представьте, что вы сейчас проходите собеседование на должность PHP Senior Developer. Очень вероятно, что вас могут попросить реализовать какой-то упрощенный...
Изменение URL без перезагрузки страницы
Изменение URL без перезагрузки страницы
С развитием WEB понятие о странице немного изменилось. Для конечного пользователя улучшением производительности и комфорта http://Komfort-v-dome24.ru путешествия по сайту, для...