Можно ли в Laravel задать «область видимости» для собственного обработчика журнала (логгера)?

Как решить проблему, когда кастомная обработка логов не работает после начала использования очередей?
  • 13 ноября 2023 г. 8:52
Ответы на вопрос 1
Да, в Laravel можно задать "область видимости" для собственного обработчика журнала (логгера) с помощью метода `setScopes` в классе обработчика журнала.

Например, если у вас есть собственный обработчик журнала, вы можете определить его область видимости в методе `register`:

```php
use Illuminate\Support\Facades\Log;
use Monolog\Handler\AbstractProcessingHandler;

class MyCustomHandler extends AbstractProcessingHandler
{
    public function __construct()
    {
        // Установите область видимости по умолчанию
        $this->setScopes(['default']);
    }

    public function handle(array $record): bool
    {
        // Произведите обработку журнала здесь
        // ...

        // Возвращайте true, чтобы сообщить, что журнал был обработан успешно
        return true;
    }

    public function register()
    {
        // Задайте желаемую область видимости для обработчика
        $this->setScopes(['custom-logs']);

        // Зарегистрируйте обработчик в логгере
        Log::extend('my-custom-handler', function ($app, array $config) {
            return new MyCustomHandler();
        });
    }
}
```

В коде выше мы устанавливаем область видимости обработчика по умолчанию в `register`, а затем переопределяем ее в методе `handle`, где производим собственную обработку журнала. Также мы регистрируем наш обработчик в логгере с помощью `Log::extend`.

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

Для решения этой проблемы вы можете зарегистрировать свой обработчик журнала в контексте выполнения очереди.

Вы можете создать отдельный провайдер служб для регистрации обработчика журнала в контексте очереди:

```php
use Illuminate\Support\ServiceProvider;
use Illuminate\Contracts\Foundation\Application;
use Monolog\Logger;
use Monolog\Handler\AbstractProcessingHandler;

class QueueLogServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->resolving(Application::class, function ($app) {
            $logger = $app->make(Logger::class);

            // Зарегистрируйте обработчик журнала только для контекста очереди
            if ($app->runningInConsole() && $app->runningUnitTests()) {
                $logger->pushHandler(new MyCustomHandler());
            }
        });
    }
}
```

В коде выше мы определяем провайдер служб `QueueLogServiceProvider` и регистрируем его в файле `config/app.php`. В методе `register` мы использовали метод `resolving` для получения экземпляра приложения и зарегистрировали обработчик журнала только для контекста очереди (как проверка в данном случае). Вы можете изменить эту проверку на основе своих требований.

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