Як додавати додаткові дані у повідомлення логів через процесор

Дата оновлення перекладу 2024-05-29

Як додавати додаткові дані у повідомлення логів через процесор

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: обробник, на який має бути перенаправлено процесор;
  • method: метод, який обробляє записи (корисно при застосуванні атрибуту до всього класу, а не одного методу).

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' }