Как в библиотеке Monolog версии 2.8 для PHP можно настроить отправку похожих писем с интервалом в один час?

Как в Monolog версии 2.8 с использованием SymfonyMailerHandler настроить отправку писем об ошибках так, чтобы похожие ошибки не отправлялись чаще, чем раз в час?
  • 4 апреля 2025 г. 14:05
Ответы на вопрос 2
Чтобы настроить отправку похожих писем с использованием библиотеки Monolog и SymfonyMailerHandler, вы можете воспользоваться механизмом фильтрации для подавления повторяющихся сообщений в течение заданного интервала. Для этого в Monolog можно создать свой собственный процессор или использовать существующие решения.

Вот пример, как это можно реализовать, используя Monolog версии 2.8 и SymfonyMailerHandler. Мы создадим свой собственный процессор, который будет отслеживать последние ошибки и обрабатывать их так, чтобы они не отправлялись чаще, чем раз в час.

1. **Установите зависимости** (если они еще не установлены):

```bash
composer require monolog/monolog symfony/mailer
```

2. **Создайте кастомный процессор**:

```php
namespace App\Logger;

use Monolog\Processor\ProcessorInterface;

class ThrottleErrorsProcessor implements ProcessorInterface
{
    private $lastErrorTimestamps = [];
    private $threshold; // Время в секундах, например, 3600 для одного часа

    public function __construct(int $threshold)
    {
        $this->threshold = $threshold;
    }

    public function __invoke(array $record): array
    {
        $errorMessage = $record['message'];
        $now = time();

        // Удаляем устаревшие ошибки
        $this->lastErrorTimestamps = array_filter(
            $this->lastErrorTimestamps,
            fn($timestamp) => $now - $timestamp <= $this->threshold
        );

        // Проверяем, есть ли такая ошибка в списке
        if (in_array($errorMessage, array_keys($this->lastErrorTimestamps))) {
            // Похожая ошибка уже была отправлена, мы подавляем логи
            $record['level'] = null; // или можно задать другой уровень, например, INFO
        } else {
            // Запоминаем время ошибки
            $this->lastErrorTimestamps[$errorMessage] = $now;
        }

        return $record;
    }
}
```

3. **Настройте Monolog с использованием нового процессора**:

```php
use Monolog\Logger;
use Monolog\Handler\SymfonyMailerHandler;
use Monolog\Processor\ProcessorInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Mailer\Messenger\Envelope;
use Symfony\Component\Mime\Email;

// Создать свой обработчик для отправки email
$mailerHandler = new SymfonyMailerHandler($mailer, new Email(), Logger::ERROR);
$mailerHandler->setFormatter(new SomeFormatter()); // Установите свой форматтер, если нужно

// Создаем объект логгера
$logger = new Logger('error_logger');
$logger->pushHandler($mailerHandler);

// Добавляем кастомный процессор подавления ошибок
$logger->pushProcessor(new ThrottleErrorsProcessor(3600)); // 3600 секунд = 1 час

// Теперь вы можете логировать ошибки, и похожие ошибки будут подавляться
$logger->error('Some error message');
```

Этот код включает в себя кастомный процессор, который отслеживает отправленные сообщения об ошибках, и не позволяет повторно отправить аналогичные сообщения чаще, чем раз в час. Не забудьте заменить `SomeFormatter` на свой форматтер, если вы его используете.
пускать через обработчик deduplicated 
https://symfony.ru/logging/monolog_email.html
Похожие вопросы