В этом посте я расскажу о простой утилите для просмотра журнала ошибок php (под apache) и nginx, написанной на php. В парсинге логов на php нет ничего сложного, и обычный разбор по регулярным выражениям позволяет решить задачу. Найденные готовые решения не удовлетворили меня либо по встраивомости, либо по коду, поэтому я написал свой велосипед с необходимым мне уровнем абстракции. Это позволило применить один и тот же код и для проекта на Zend Framework и для отдельного веб-сервера совсем без фреймворков. Исходный код выложен на github по ссылке - LogReader.
В этом примере мы создаём экземпляр парсера 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:
При использовании в некоторых случаях требуются дополнительные права на файл лога, даже если скрипт работает под тем же веб-сервером.
Использование
Самый простой код использования: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:
При использовании в некоторых случаях требуются дополнительные права на файл лога, даже если скрипт работает под тем же веб-сервером.
Спасибо за наводку! а по прыгать в консоль и обратно больно долго.
ОтветитьУдалить