Производительность

Раздел «Производительность» показывает не отдельные ошибки, а то, как быстро работает приложение: транзакции (обработанные запросы или фоновые операции), из которых состоят спаны (запросы к БД, HTTP-вызовы к другим сервисам, рендер шаблона и т. п.), и трейсы — сквозные цепочки таких транзакций/спанов одного запроса.

Как отправлять данные

Транзакции и спаны присылает SDK вашего приложения — тот же официальный Sentry SDK, что и для ошибок (см. SDK и интеграции), только с включённым трейсингом. Ключевая настройка при инициализации — tracesSampleRate (доля запросов, которые SDK трассирует и отправляет, от 0 до 1):

Sentry.init({
  dsn: "<ВАШ_DSN>",
  tracesSampleRate: 1.0, // на старте — 100%, на проде обычно снижают
});

Аналогичный параметр есть у SDK любого языка (Go/PHP/Python и т. д.) — конкретное имя опции и способ включить автоинструментацию фреймворка смотрите в документации вашего Sentry SDK. Пока tracesSampleRate равен нулю или не задан, раздел «Производительность» остаётся пустым — данные появляются только после того, как SDK начинает реально отправлять трассировку.

Список эндпойнтов

Раздел открывается по ссылке «Производительность» в левом рельсе — URL /projects/<id>/performance (в меню подраздел называется «Транзакции»). Фильтры сверху — окружение и окно времени (пресеты или произвольный диапазон). У каждого заголовка колонки — подсказка о метрике: наведите на пунктирное подчёркивание. Таблица эндпойнтов:

КолонкаСмысл
Эндпойнтимя транзакции (клик — на страницу эндпойнта)
Трафиктранзакций в минуту
p50 / p75 / p95 / p99перцентили длительности
Ошибкидоля транзакций со статусом, отличным от ok
Apdexиндекс удовлетворённости, 0..1
p95 (период)спарклайн p95 во времени

Заголовки колонок — ссылки, клик сортирует список по этой колонке. Список эндпойнтов ограничен по размеру; если реальных эндпойнтов больше, над таблицей появляется пометка «показаны первые N из M».

Apdex. Под фильтрами показывается используемый порог T (например, «Apdex T = 300ms», настраивается в настройках проекта). Запрос длительностью до T считается «удовлетворённым», от T до 4T — «терпимым», дольше — «неудовлетворённым»; Apdex = (удовлетворённые + терпимые/2) / всего. Резкий рост p95/p99 при стабильном трафике — типичный признак деградации, а не просто увеличения нагрузки: трафик не растёт, значит дело не в объёме запросов.

Деталь эндпойнта

Клик по имени эндпойнта открывает /projects/<id>/performance/<transaction>: окно времени / окружение / порог Apdex в шапке, панель Web Vitals (если это транзакция загрузки страницы — подробнее ниже), график латентности (p50/p95 во времени), график трафика, гистограмма распределения длительностей, таблица самых медленных трейсов за окно (ссылка на waterfall каждого) и список связанных узких мест. Как и в списке, подписи метрик (p50/p95, Apdex и Web Vitals) снабжены всплывающими подсказками.

Узкие места

Узкие места — N+1-запросы, медленные запросы к БД и HTTP-флуд — это отдельная, автоматически обнаруживаемая категория находок внутри транзакций (не то же самое, что регрессии ниже). Полный список — раздел «Узкие места» (/projects/<id>/perf-issues), доступный из раздела «Проблемы», с фильтром статуса «Не решено / Решено / Игнорируется / Все». Каждая строка — обнаруженная проблема: её вид, эндпойнт, где она найдена, сколько раз встречалась и когда.

Открытие проблемы объясняет суть, а не только числа:

  • Что происходит / Как чинить — разбор простым языком по виду (почему N+1 медленный, что такое медленный запрос или HTTP-флуд) и конкретное направление, как чинить.
  • Запрос — текст запроса из виновного спана целиком (до 2000 символов; при приёме очень длинные запросы обрезаются до этого предела), с операцией, СУБД и длительностью. Это реальный текст запроса, а не сокращённый параметризованный заголовок выше.
  • Где в коде — файл, строка и функция за запросом, если их прислал SDK в data спана (code.filepath / code.lineno / code.function). Это оппортунистично: если SDK не шлёт привязку к коду, секции просто нет.
  • Детали — счётчики по виду (число повторов, суммарное или максимальное время, доля последовательных, примеры URL).
  • Пример трейса — ссылка на реальный трейс, где проблема была обнаружена, чтобы увидеть её в waterfall в контексте.

Пометить проблему Решено или Игнорируется может любой, у кого есть доступ к проекту, — то же правило, что и для обычных issue (см. Роли и права); она переоткроется автоматически, если паттерн обнаружится снова.

Waterfall трейса

Ссылка «Трейс» из таблицы медленных трейсов или из детали события в Проблемах открывает /traces/<trace_id>: id трейса, общая длительность, время, и ниже — waterfall дерева спанов (каждый спан — полоса, смещённая и растянутая по времени относительно начала трейса; спаны с ошибкой отмечены красным). Если у трейса есть привязанный профиль (см. Профилирование), над waterfall появляется ссылка на его флеймграф — так можно перейти от «какой спан долгий» к «что именно внутри него выполнялось».

Web Vitals

Web Vitals — метрики скорости страницы, измеренные в браузере реального пользователя (RUM), а не синтетическим тестом на сервере. Раздел открывается вкладкой «Web Vitals» в подменю «Производительность» — URL /projects/<id>/web-vitals.

МетрикаЧто измеряет
LCP (Largest Contentful Paint)когда отрисовался самый крупный видимый элемент — ощущение «страница загрузилась»
INP (Interaction to Next Paint)задержка отклика на действия пользователя (клик, тап, ввод) за всё время жизни страницы
CLS (Cumulative Layout Shift)суммарное «дёргание» вёрстки — насколько элементы неожиданно сдвигаются
FCP (First Contentful Paint)когда отрисовался первый контент
TTFB (Time to First Byte)время до первого байта ответа сервера

Пороги (Google, фиксированные)

Рейтинг good / needs-improvement / poor считается по 75-му перцентилю (p75) значения за выбранный период — это официальные пороги Google для Core Web Vitals. Они не настраиваются по проектам: одни и те же числа для всех, потому что это внешний, общепринятый стандарт, а не собственная метрика Gotcha.

МетрикаGood (p75 ≤)Poor (p75 >)Needs improvement
LCP2500 мс4000 мсмежду
INP200 мс500 мсмежду
CLS0.100.25между
FCP1800 мс3000 мсмежду
TTFB800 мс1800 мсмежду

Граница good включительна (p75, равный порогу, — ещё «good»), значение выше poor-порога — «poor», всё между — «needs-improvement».

Как считается p75

Для каждой страницы (транзакции загрузки страницы) и метрики Gotcha берёт 75-й перцентиль значений, собранных за выбранное окно времени, и присваивает рейтинг по таблице выше. Если замеров для метрики за период нет, вместо значения показывается «—» без бейджа.

Как читать страницу

Таблица — по одной строке на страницу (транзакцию), колонки p75 LCP/INP/CLS с цветным бейджем рейтинга и число замеров; сортировка по клику на заголовок, фильтры окружения и периода те же, что на списке эндпойнтов. На странице конкретного эндпойнта (если это pageload-транзакция) те же три метрики показаны в виде панели с мини-графиком p75 во времени — удобно увидеть, ухудшилось значение недавно или это стабильный уровень.

Данные приходят из браузерного SDK (@sentry/browser) с включённым трейсингом — без него Web Vitals собирать некому, серверные SDK этого не делают. Установка описана в SDK и интеграции.

Регрессии

Регрессия производительности — это статистически значимое ухудшение p95 длительности эндпойнта или p75 web vital’а относительно скользящей базовой линии, обнаруженное автоматически, без ручной настройки порогов «на глаз» под каждый эндпойнт. Список — в подразделе «Регрессии» (/projects/<id>/regressions), с вкладками «Открыто / Решено / Все». Таблица: цель (эндпойнт или ссылка на Web Vitals), метрика, рост в процентах, диапазон «база → пик», статус, когда началась, длительность (или «идёт», пока регрессия открыта).

Как работает детекция (порог + гистерезис)

Фоновый оценщик периодически сравнивает свежее окно (по умолчанию 60 минут) с базой — медианой дневных значений за последние 7 дней — для самых нагруженных эндпойнтов и страниц с web vitals проекта:

  • Открытие происходит, только если выполнены сразу два условия: относительный рост (свежее > база × (1 + порог)) и абсолютный «пол» (свежее > база + Floor). Порог по умолчанию — 25%. Пол нужен, чтобы рост с 20 мс до 40 мс (формально +100%) на почти неощутимых цифрах не поднимал ложную тревогу.
  • Закрытие использует более мягкий порог восстановления — по умолчанию 10% (свежее ≤ база × 1.10), а не тот же 25%, что и открытие. Это гистерезис: без разрыва между порогом открытия и закрытия регрессия «мигала» бы туда-сюда на границе.
  • Решение принимается только при достаточной статистике: и в свежем окне, и в базе должно быть не меньше минимального числа замеров (по умолчанию 100), иначе оценщик ничего не решает в этот тик.

Дефолтные абсолютные полы: 100 мс для длительности эндпойнта, 200 мс для LCP/FCP/TTFB, 50 мс для INP, 0.05 для CLS.

Все эти пороги (проценты открытия/закрытия, размер окна, минимум замеров, полы по каждой метрике, а также полный выключатель детектора) настраиваются отдельно для каждого проекта — карточка «Регрессии» на странице «Настройки проекта».

Сезонная база (день недели × час)

По умолчанию база — скользящая: медиана дневных значений за последние 7 дней. Она не учитывает суточную и недельную сезонность, поэтому у сервисов с выраженным профилем нагрузки ведёт себя неудобно. Ночью, когда трафик естественно проседает и латентность иная, детектор может молчать на реальном ухудшении; утром, на входе в пик, та же скользящая база задним числом занижена — и обычный дневной подъём читается как регрессия. Скользящее среднее по суткам просто смешивает «три часа ночи» и «полдень вторника» в одно число.

Сезонный режим сравнивает свежее окно не со среднесуточным, а с тем же окном того же дня недели за прошлые недели. Для «утра вторника» базой становится «утро вторника» неделю, две, три назад — то есть ожидание берётся из сопоставимого по нагрузке момента, а не размазывается по всем суткам. Медиана берётся по этим недельным срезам, так что единичный выброс одной недели базу не сдвигает.

Когда включать. Режим полезен сервисам с выраженной суточной или недельной сезонностью: бизнес-часы против ночи, будни против выходных, регулярные утренние или вечерние пики. Если нагрузка ровная круглые сутки, скользящей базы достаточно и включать сезонный режим смысла нет.

Как настроить. В карточке «Регрессии» настроек проекта — тумблер «Сезонный baseline» и поле «Недель истории» (от 2 до 12, по умолчанию 4): сколько прошлых недель того же дня и часа брать в базу. Когда режим включён, список регрессий помечается бейджем «Сезонный режим», чтобы было видно, по какой базе принято решение.

Пока истории мало. Если для конкретной цели сезонной истории ещё недостаточно — новый проект или редкий час-слот, где за прошлые недели не набралось минимума замеров, — детектор для этой цели автоматически откатывается на обычную скользящую базу. Так он продолжает работать и в период накопления истории, а по мере её появления сам переходит на сезонное сравнение; переключать ничего не нужно.

Семантика прежняя, только «вверх»: алерт открывается на ухудшение относительно сезонного ожидания. Аномально низкая латентность (быстрее ожидаемого) регрессией не считается. Сезонность считается по UTC-часу — проекты живут в одной таймзоне, и слоты дня недели × часа определяются по UTC.