Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як не дати лавині однакових помилок заповнити лог і вичерпати ліміт Sentry?

Сценарій: зовнішній API ліг, і кожен запит, що до нього звертається, кидає той самий виняток. За хвилину - десятки тисяч однакових звітів: лог росте на гігабайти, Sentry вичерпує квоту за годину, а справжні нові помилки тонуть у шумі.

throttle() у bootstrap/app.php - вибіркове звітування:

use Illuminate\Support\Lottery;
use Illuminate\Cache\RateLimiting\Limit;

->withExceptions(function (Exceptions $exceptions): void {
    $exceptions->throttle(function (Throwable $e) {
        // кожен 1000-й звіт про часті помилки
        if ($e instanceof ApiMonitoringException) {
            return Lottery::odds(1, 1000);
        }

        // не більше 300 звітів на хвилину для збоїв зовнішніх сервісів
        if ($e instanceof BroadcastException) {
            return Limit::perMinute(300);
        }

        // ліміт окремо для кожного типу винятку
        return Limit::perMinute(300)->by($e::class);
    });
})

Два режими:

Lottery Limit
що робить звітує випадкову частку звітує не більше N за період
стан не потрібен лічильник у кеші (потрібен спільний драйвер, наприклад Redis)
для чого дуже часті, неважливі за кількістю сплески, при яких важливо бачити кожен перший випадок

by() визначає, що вважається «тим самим»: за класом винятку, за повідомленням, за ідентифікатором тенанта. Без by() усі винятки ділять один спільний ліміт.

Чого throttle не замінює:

  • circuit breaker - якщо сервіс лежить, не варто взагалі звертатися до нього тисячі разів: це і зайве навантаження, і повільні запити користувачів;
  • агрегацію в Sentry чи Flare: вони групують однакові помилки, але кожна подія все одно рахується в квоту - тому обмеження на боці застосунку економить гроші;
  • сповіщення: про те, що помилка стала частою, мають сповіщати метрики й моніторинг, а не кількість записів у лозі.

Ще кілька захистів від шуму:

  • dontReportDuplicates() - один виняток, переданий у report() кілька разів, звітується раз;
  • рівні: level(ConnectException::class, LogLevel::WARNING) - збій зовнішнього сервісу не повинен виглядати як error застосунку;
  • ротація логів (канал daily з days) і збір логів у централізоване сховище замість файлу на диску.

Перевірка: зробити штучний сплеск у staging і подивитися, скільки записів реально пішло в лог і в Sentry.

Докладніше в документації: Помилки: обмеження частоти звітів

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання