Многоуровневое логирование: Руководство по структурированному и последовательному ведению логов

Моя цель - предложение широкого ассортимента товаров и услуг на постоянно высоком качестве обслуживания по самым выгодным ценам.

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

Loggings
Логи

Важность структуры логов

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

Рассмотрим пример логирования IP-адреса клиента. Мы по сути не ограничены в вариантах представления этой информации, например:

  • src: 10.42.42.42

  • client_ip: 10.42.42.42

  • apache2.access.remote_ip: 10.42.42.42

  • context.user.ip: 10.42.42.42

  • src_ip: 10.42.42.42

Нет однозначного правильного или неправильного ответа; главное — создать стандартизированный и лаконичный способ логирования данных на всех платформах, например, client.ip: 10.42.42.42.

Задача и решение

Если цель вполне ясна и прямолинейна, то почему достижение последовательности в этом процессе все еще остается сложной задачей? Ключ лежит в подготовке документированной структуры и обеспечении ее повсеместного принятия в команде. Именование переменных, как было с юмором отмечено в одной бородатой шутке о программировании, действительно является сложным аспектом программирования. Это трудоемкий процесс, требующий разносторонних знаний для выработки стандартного подхода в различных архитектурных областях.

Чтобы решить эту проблему, известная компания Elastic представила Elastic Common Schema (ECS) — спецификацию с открытым исходным кодом, разработанную при поддержке сообщества разработчиков. ECS определяет имена полей, типы данных и примеры использования, представляя собой хорошо документированное руководство.

ECS Fields Documentation
Документация по полям ECS

ECS в PHP

Хотя ECS и предлагает готовое решение, его реализация с нуля на PHP требует определенных усилий. Доступный PHP SDK для ECS охватывает лишь ограниченный набор полей.

ECS fields covered by the SDK
Поля ECS, покрываемые SDK

В результате осознания этого пробела была создана PECS (PHP Elastic Common Schema), которая привнесла полную поддержку ECS в мир PHP.

Абстракция и соглашение

Прежде чем погрузиться в пакет, давайте сначала определим, что является хорошей абстракцией. Черпая вдохновение из книги "Справочник эффективного инженера" (The Effective Engineer) Эдмонда Лау (Edmond Lau), хорошая абстракция должна быть:

  • Легкой в освоении

  • Простой в использовании без подробной документации

  • Трудной для использования не по назначению

  • Достаточно мощной для удовлетворения поставленных требований

  • Легко расширяемой

  • Подходить для целевой аудитории

PECS стремится соответствовать этим критериям. В этом пакете спецификации ECS полностью преобразованы в конфигурации JSON, что позволяет встроенному генератору создавать ECS PHP классы. Классы полностью аннотированны как нативными типами, так и определяемыми типами классов и перечислений, что сводит к минимуму риск некорректного использования. Пакет спроектирован таким образом, чтобы его можно было легко расширять, позволяя инстанцировать поля и отображать их в ожидаемом формате ECS.

Ниже приведен пример создания ECS-полей в коллекции:

(new EcsFieldsCollection([
    new Log(
        filePath: 'app/Http/Controllers/Controller.php',
        level: 'info',
        logger: 'name',
        originFileLine: 42,
        originFileName: 'Controller.php',
        originFunction: 'index',
    ),
    new Client(
        ip: '10.42.42.42',
        geo: new Geo(
            cityName: 'Amsterdam',
            continentCode: 'EU',
            continentName: 'Europe',
            countryIsoCode: 'NL',
            countryName: 'Netherlands',
            location: new GeoPoint(52.37403, 4.88969),
        ),
        user: new User(
            id: 'e125a612-899e-11ee-b9d1-0242ac120002',
            name: 'hamid',
            roles: (new ValueList())->push('admin')->push('user'),
        )
    ),
    new Os(
        kernel: '4.19.0-6-amd64',
        name: 'Arch',
        platform: 'x86_64',
        type: OsType::LINUX
    ),
]))->render();

и вывод, иллюстрирующий результат генерации указанных полей:

{
    "log": {
        "file": {
            "path": "app\/Http\/Controllers\/Controller.php"
        },
        "level": "info",
        "logger": "name",
        "origin": {
            "file": {
                "line": 42,
                "name": "Controller.php"
            },
            "function": "index"
        }
    },
    "client": {
        "ip": "10.42.42.42",
        "geo": {
            "city_name": "Amsterdam",
            "continent_code": "EU",
            "continent_name": "Europe",
            "country_iso_code": "NL",
            "country_name": "Netherlands",
            "location": {
                "lat": 52.37403,
                "lon": 4.88969
            }
        },
        "user": {
            "id": "e125a612-899e-11ee-b9d1-0242ac120002",
            "name": "hamid",
            "roles": [
                "admin",
                "user"
            ]
        }
    }
}

Интеграция

Понимая, что чистый PHP в наши дни нормой не является, PECS включен в список сторонних пакетов для Monolog, самого популярного пакета для логирования на PHP.

$log->pushHandler($handler->setFormatter(new EcsFormatter()));

$log->info('message', [
    new Event(action: 'test event'),
]);

Эта интеграция позволяет без проблем работать с Symfony и Laravel, которые под капотом используют Monolog.

Заключение

В заключение можно сказать, что PECS представляет собой комплексное решение для реализации Elastic Common Schema в PHP, обеспечивая структурированное и последовательное протоколирование на различных платформах. В этой статье вашему вниманию был представлен краткий обзор, а в следующей мы рассмотрим настройку PECS на практических примерах. Пока же рекомендую вам почитать документацию, чтобы получить общее представление о структуре PECS.

Приглашаем всех, кому интересна тема искусственного интеллекта в разработке на PHP, на открытый урок 10 января. Обсудим, какие есть инструменты и возможности, а также посмотрим примеры настройки и работы ИИ на примере Github Copilot в PhpStorm. Записаться можно по ссылке.

Источник: https://habr.com/ru/companies/otus/articles/783738/


Интересные статьи

Интересные статьи

Продвижение молодого сайта может быть сложной задачей, особенно если конкуренция в нише высокая. Одним из способов ускорить процесс и повысить видимость сайта является использование старых дроп домено...
Публикуем девятую, заключительную часть (1, 2, 3, 4, 5, 6, 7, 8) перевода руководства по модулю asyncio в Python. Здесь вы найдёте разделы исходного матери...
В предыдущей статье я рассказывал, как построить простой кластер Kubernetes с одним мастер-узлом. Прошло время, опали листья... и мне захотелось большего, поэтому решил позариться на высокодоступные к...
Привет, друзья! В этой серии из 3 статей я расскажу вам о Nest (NestJS) — фреймворке для разработки эффективных и масштабируемых серверных приложений на Node.js. Данный фреймворк использует прогресси...
Примечание от переводчика: это первая часть монументальной (на самом деле монументальной) статьи о Vim и его возможностях от разработчика из Миннеаполиса и автора проекта PostgREST Джо begriffs Н...