Перейти к основному содержанию
Разработка3 мин чтения

Мониторинг и алерты: узнавать о проблеме раньше клиента

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

Панель мониторинга с графиками ошибок и времени ответа

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

Мониторинг — это не панель с красивыми графиками. Это ответ на два вопроса: работает ли сейчас и что именно сломалось. Всё остальное — детали реализации.

Четыре сигнала, которые нужны всегда

Базовый набор наблюдаемых показателей
СигналЧто показываетТипичный порог
Доля ошибокЧасть запросов, завершившихся сбоемвыше 1% за 5 минут
Время ответа, 95-й процентильСкорость для самых медленных запросоввыше 2 секунд
Насыщение ресурсовПамять, соединения к базе, очередьвыше 80% лимита
Поток запросовРезкий обвал или всплеск трафикаотклонение вдвое от обычного

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

Структурные логи

Строка «Ошибка при сохранении» бесполезна: непонятно, у какого пользователя, в каком запросе и что именно не сохранилось. Логи должны быть машиночитаемыми, с одинаковым набором полей и идентификатором запроса, по которому можно собрать всю цепочку.

Логи в формате JSON с идентификатором запроса
type LogFields = {
  requestId: string
  userId?: string
  route: string
  durationMs?: number
  [key: string]: unknown
}

export function logEvent(level: "info" | "warn" | "error", message: string, fields: LogFields) {
  // Одна строка — один объект JSON: так его разберёт любой сборщик логов
  console.log(JSON.stringify({
    level,
    message,
    ts: new Date().toISOString(),
    ...fields,
  }))
}

// Использование: по requestId собирается вся история одного запроса
logEvent("error", "Не удалось создать заказ", {
  requestId,
  userId: session.user.id,
  route: "/api/orders",
  reason: "insufficient_stock",
  productId,
})

Алерты, которые не игнорируют

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

  • Оповещение срабатывает на симптом для пользователя, а не на технический факт: важна доля ошибок, а не перезапуск процесса
  • У каждого алерта есть порог по времени: скачок на 30 секунд не повод будить человека
  • В тексте — ссылка на график и на логи по нужному фильтру
  • Есть дежурный, а не рассылка на всех: рассылка на всех означает, что не реагирует никто
  • Раз в месяц алерты пересматриваются: сработавшие ни о чём отключаются
Правило с окном по времени, чтобы не реагировать на единичные всплески
groups:
  - name: web
    rules:
      - alert: HighErrorRate
        # Условие должно держаться 5 минут — иначе это шум
        expr: |
          sum(rate(http_requests_total{status=~"5.."}[5m]))
            / sum(rate(http_requests_total[5m])) > 0.01
        for: 5m
        labels:
          severity: page
        annotations:
          summary: "Более 1% запросов с ошибкой"
          runbook: "https://wiki.example.com/runbooks/high-error-rate"

Что мы настраиваем на старте

  1. Сбор необработанных исключений с трассировкой и контекстом запроса
  2. Структурные логи с идентификатором запроса и сроком хранения 30 дней
  3. Проверка доступности снаружи с оповещением при двух неудачах подряд
  4. Метрики по времени ответа и доле ошибок с разбивкой по маршрутам
  5. Наблюдение за фоновыми задачами: возраст старейшей и число проваленных

Этот набор занимает один-два дня работы и закрывает большую часть аварий, о которых иначе узнают из письма клиента. Дальше набор расширяется под конкретный продукт: платежи, интеграции, отдельные бизнес-показатели вроде числа оформленных заказов в час.

Частые вопросы

Сколько стоит настроить мониторинг
Базовый набор — сбор ошибок, структурные логи, проверка доступности и несколько алертов — это 8–16 часов работы. Сервисы для небольшого проекта укладываются в бесплатные тарифы или несколько тысяч рублей в месяц.
Какие сервисы вы используете
Для ошибок обычно Sentry, для метрик и логов — встроенные средства платформы, где развёрнут проект, либо Grafana с Loki при своей инфраструктуре. Выбор менее важен, чем сам факт наличия и разумные пороги оповещений.
Нужен ли мониторинг небольшому сайту
В минимальном виде да: проверка доступности и сбор ошибок. Это дешевле любого простоя и снимает главную проблему — узнавать о поломке последним.
поддержкамониторингнадёжностьэксплуатация

Похожая задача в вашем проекте?

Разберём вашу ситуацию и пришлём оценку по этапам — без обязательств и общих слов.

Обсудить задачу

Вопрос по статье
или по своему проекту

Отвечаем на заявки в течение одного рабочего дня. Если задача не наша — скажем прямо и подскажем, к кому обратиться.

Написать нам

Поля со звёздочкой обязательны для заполнения.