2 апреля 2014 г.

Log Reader - парсер логов ошибок веб-сервера

В этом посте я расскажу  о простой утилите для просмотра журнала ошибок php (под apache) и nginx, написанной на php. В парсинге логов на php нет ничего сложного, и обычный разбор по регулярным выражениям позволяет решить задачу. Найденные готовые решения не удовлетворили меня либо по встраивомости, либо по коду, поэтому я написал свой велосипед с необходимым мне уровнем абстракции. Это позволило применить один и тот же код и для проекта на Zend Framework и для отдельного веб-сервера совсем без фреймворков. Исходный код выложен на github по ссылке - LogReader.


Использование

Самый простой код использования:
require_once 'LogReader/ApachePhp.php';
require_once 'LogReader/Storage/Array.php';

$logReader = new LogReader_ApachePhp("/var/log/apache2/error.log", new LogReader_Storage_Array());
$logReader->read();

$logs = $logReader->getStorage()->load();
//or $logs = $logReader->getStorage()->loadUnique();
var_dump($logs);
 
В этом примере мы создаём экземпляр парсера LogReader_ApachePhp, первым аргументом указав путь до файла с логом, вторым - объект-хранилише распарсенных результатов.
В примере мы используем хранилище LogReader_Storage_Array - обычный массив элементов. Для хранилища создан интерфейс, реализовав который можно создать своё хранилище с обработкой ошибок, например, сохранять в базу, помечать новые ошибки, уведомлять разработчиков.

Метод $logReader->read(); распарсит файл, при этом для каждой строки создаётся LogReader_Item_ApachePhp - объект, содержащий данные ошибки. В случае php, если строка является частью stack trace, то новый Item не создается, а в сообщение приписывается весь stack trace.

Метод $logReader->getStorage()->load(); позволяет получить данные из хранилища. Если используем LogReader_Storage_Array, то результат будет массив из LogReader_Item_ApachePhp.

У хранилища есть дополнительные метод $logReader->getStorage()->loadUnique();, который позволяет получить только уникальные сообщения ошибок. Уникальность реализуется через метод getId() у Item. В простом случае достаточно хеш-суммы сообщения, чтобы отделить одну ошибку от другой.

Список записей можно выводить через обычный foreach. Для себя я сделал таблицу и добавил немного стилей для разного типа ошибок. В итоге получилось следующее:


И аналогичное для лога nginx:

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

1 комментарий:

  1. Спасибо за наводку! а по прыгать в консоль и обратно больно долго.

    ОтветитьУдалить