Как добавлять дополнительные данные в сообщения логов через процессор

Дата обновления перевода 2024-07-25

Как добавлять дополнительные данные в сообщения логов через процессор

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

Процессор - это вызываемое, которое получает запись в качестве первого аргумента. Процессоры конфигурируются с использованием DIC-тега monolog.processor. Смотрите справочник по нему .

Добавление токена сессии/запроса

Иногда сложно сказать, к какой сессии и/или запросу принадлежать записи в логе. Следующий пример добавить уникальный токен к каждому запросу, используя процессор:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// src/Logger/SessionRequestProcessor.php
namespace App\Logger;

use Monolog\LogRecord;
use Monolog\Processor\ProcessorInterface;
use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
use Symfony\Component\HttpFoundation\RequestStack;

class SessionRequestProcessor implements ProcessorInterface
{
    public function __construct(
        private RequestStack $requestStack
    ) {
    }

    // этот метод вызывается для каждой записи логов; оптимизируйте его, чтобы не навредить производительности
    public function __invoke(LogRecord $record): LogRecord
    {
        try {
            $session = $this->requestStack->getSession();
        } catch (SessionNotFoundException $e) {
            return $record;
        }
        if (!$session->isStarted()) {
            return $record;
        }

        $sessionId = substr($session->getId(), 0, 8) ?: '????????';

        $record->extra['token'] = $sessionId.'-'.substr(uniqid('', true), -8);

        return $record;
    }
}

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

1
2
3
4
5
6
7
8
9
10
# config/services.yaml
services:
    monolog.formatter.session_request:
        class: Monolog\Formatter\LineFormatter
        arguments:
            - "[%%datetime%%] [%%extra.token%%] %%channel%%.%%level_name%%: %%message%% %%context%% %%extra%%\n"

    App\Logger\SessionRequestProcessor:
        tags:
            - { name: monolog.processor }

Наконец, настройте форматировщик так, чтобы он был использован в любом желаемом вами обработчике:

1
2
3
4
5
6
7
8
# config/packages/prod/monolog.yaml
monolog:
    handlers:
        main:
            type: stream
            path: '%kernel.logs_dir%/%kernel.environment%.log'
            level: debug
            formatter: monolog.formatter.session_request

Если вы используете несколько обработчиков, вы также можете зарегистрировать процессор на уровне обработчика или канала, вместо того, чтобы регистрировать его глобально (см. следующие разделы).

При регистрации нового процессора, вместо того, чтобы добавлять тег вручную в ваши файлы конфигурации, вы можете использовать атрибут #[AsMonologProcessor], чтобы применить его к классу процессора:

1
2
3
4
5
6
7
8
9
10
// src/Logger/SessionRequestProcessor.php
namespace App\Logger;

use Monolog\Attribute\AsMonologProcessor;

#[AsMonologProcessor]
class SessionRequestProcessor
{
    // ...
}

Атрибут #[AsMonologProcessor] принимает такие необязательные аргументы:

  • channel: канал логирования, в который должен быть отправлен процессор;
  • handler: обработчик, в который должен быть отправлен процессор;
  • метод: метод, который обрабатывает записи (полезно, когда атрибут применяется
    ко всему классу, а не к одному методу).

3.8

Атрибут #[AsMonologProcessor] был представлен в MonologBundle 3.8.

MonologBridge Symfony предоставляет процессоры, которые могут быть зарегистрированы внутри вашего приложения.

DebugProcessor
Добавляет в запись дополнительную информацию, полезную для отладки, вроде временной отметки или сообщения об ошибке.
TokenProcessor
Добавляет в запись информацию из токена текущего пользователя, чтобы записать, а именно - имя пользователя, роли и является ли он аутентифицированным.
SwitchUserTokenProcessor
Добавляетинформацию о пользователе, который имитирует пользователя, выполнившего вход в систему, а именно - имя пользователя, роли и является ли он аутентифицированным.
WebProcessor
Переопределяет данные из запроса, используя данные внутри объекта запроса Symfony.
RouteProcessor
Добавляет информацию о текущем маршруте (контроллер, действие, параметры маршрута).
ConsoleCommandProcessor
Добавляет информацию о текущей команде консоли.

See also

Посмотрите на встроенные процессоры Monolog, чтобы узнать больше о том, как создавать такие процессоры.

Регистрация процессоров в обработчике

Вы можете зарегистрировать процессор в обработчике, используя опцию handler тега monolog.processor:

1
2
3
4
5
# config/services.yaml
services:
    App\Logger\SessionRequestProcessor:
        tags:
            - { name: monolog.processor, handler: main }

Регистрация процессоров в канале

Вы можете зарегистрировать процессор в канале, используя опцию channel тега monolog.processor:

1
2
3
4
5
# config/services.yaml
services:
    App\Logger\SessionRequestProcessor:
        tags:
            - { name: monolog.processor, channel: 'app' }