Логи — это единственное, что остаётся после того, как что-то сломалось. Пользователь говорит «сайт не работает», сервер молчит, а вы смотрите в пустой экран и не понимаете, что произошло час назад. Знакомо? Значит, логирование у вас настроено плохо — или не настроено вовсе.

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

Зачем вообще нужны логи

Короткий ответ: чтобы понимать, что происходит внутри системы в реальном времени и восстанавливать картину событий после сбоя.

Длинный ответ: логи решают три задачи.

Дебаггинг. Когда ошибка воспроизводится раз в неделю и только у определённого пользователя — без логов вы никогда не узнаете, что именно пошло не так. С логами — нашли, исправили за 20 минут.

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

Аудит. Кто и когда изменил данные, с какого IP зашли в админку, что делал конкретный пользователь — всё это нужно для безопасности и соответствия требованиям.

Что писать в логи

Главная ошибка — логировать либо слишком мало, либо слишком много. «Слишком мало» — это когда у вас только console.log('error') без контекста. «Слишком много» — когда в лог пишется каждый шаг каждой функции, и найти нужное в потоке из 10 000 строк в минуту невозможно.

Оптимальный набор для большинства сервисов:

  • Все входящие HTTP-запросы: метод, путь, статус-код, время выполнения
  • Ошибки с полным стектрейсом
  • Важные бизнес-события: регистрация, оплата, смена пароля
  • Запросы к внешним сервисам и их результаты
  • Старт и остановка приложения

Чего не нужно писать в логи:

  • Пароли, токены, номера карт — никогда
  • Персональные данные без необходимости (и без соответствия 152-ФЗ)
  • Каждый SQL-запрос в продакшене — только если отлаживаете
  • Дебаг-информацию на боевом сервере

Уровни логирования

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

DEBUG — детальная информация для разработки. На продакшене обычно выключен.

INFO — нормальный ход работы приложения. Запрос пришёл, обработан, ответ отправлен.

WARN — что-то подозрительное, но приложение работает. Например, устаревший API-метод, к которому всё ещё обращаются клиенты.

ERROR — произошла ошибка, операция не выполнена. Но приложение живёт.

FATAL / CRITICAL — критическая ошибка, сервис упал или не может продолжать работу.

Правило простое: в продакшене включайте INFO и выше. DEBUG включайте только когда активно отлаживаете конкретную проблему — и потом выключайте обратно.

Формат логов: структурированный vs plain text

Plain text — это то, что пишут все по умолчанию:

2026-03-15 14:23:01 ERROR Failed to connect to database: timeout

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

Структурированный лог — это JSON:

{
  "timestamp": "2026-03-15T14:23:01Z",
  "level": "error",
  "message": "Failed to connect to database",
  "error": "timeout after 5000ms",
  "service": "api",
  "request_id": "a3f7b2c1",
  "user_id": 4821
}

Каждое поле отдельное, можно фильтровать по любому из них. Elasticsearch, Loki, Datadog — все они работают со структурированными логами значительно эффективнее.

Переходите на JSON-логи. Это не сложнее, большинство библиотек поддерживают это из коробки: winston для Node.js, logrus или zerolog для Go, structlog для Python.

Где хранить логи

Не на том же сервере, где работает приложение. Это первое и главное правило. Если сервер упал — логи должны остаться.

Варианты:

Централизованный сбор через агент. На каждом сервере стоит агент (Filebeat, Promtail, Fluentd), который читает файлы логов или слушает syslog и отправляет данные в центральное хранилище. Надёжно, проверено.

Прямая запись из приложения. Приложение само отправляет логи в хранилище — через HTTP или UDP. Проще в настройке, но если хранилище недоступно — логи теряются. Нужно буферизировать.

Облачные сервисы. Datadog, Logtail, Papertrail — подключаете, и логи уже в облаке с готовым интерфейсом для поиска. Платно, но экономит время на настройку.

ELK-стек

Классический вариант для самостоятельного развёртывания: Elasticsearch + Logstash + Kibana.

  • Logstash (или Filebeat) собирает логи
  • Elasticsearch хранит и индексирует
  • Kibana визуализирует

Мощно, гибко, но требовательно к ресурсам. Elasticsearch на реальных объёмах хочет от 4 GB RAM только для себя. Для небольшого проекта — избыточно.

Grafana Loki

Более лёгкая альтернатива. Loki не индексирует содержимое логов — только метки (labels). Поэтому потребляет значительно меньше ресурсов. Подходит, если вы уже используете Grafana для метрик — логи подключатся к тому же интерфейсу.

Стек: Promtail собирает → Loki хранит → Grafana показывает.

Для среднего проекта Loki — отличный выбор. Поднимается на VPS от 2 GB RAM.

Что выбрать

  • Маленький проект (1-3 сервера): Loki + Grafana или облачный сервис вроде Logtail
  • Средний (5-20 серверов): Loki или ELK в зависимости от бюджета на железо
  • Большой (20+ серверов, терабайты логов): ELK с настроенными hot-warm тирами хранения или управляемые решения (Elastic Cloud, Datadog)

Сколько хранить логи

Зависит от типа:

  • Дебаг-логи: 3-7 дней. Они нужны только пока вы активно разрабатываете.
  • Операционные логи (INFO, WARN, ERROR): 30-90 дней.
  • Аудит-логи (действия пользователей, изменения данных): 1-3 года. Иногда требует законодательство.
  • Логи безопасности: минимум 1 год.

Настройте автоматическую ротацию и удаление. В Elasticsearch это Index Lifecycle Management (ILM), в Loki — retention в конфигурации. Не забывайте об этом — логи растут быстро.

Как читать логи на практике

Умение быстро найти нужное в логах — отдельный навык. Несколько приёмов:

Используйте request_id. Генерируйте уникальный идентификатор для каждого запроса и пробрасывайте его через весь стек — в логи приложения, базы данных, внешних сервисов. Тогда по одному ID вы увидите полную цепочку событий для конкретного запроса. Это называется distributed tracing на минималках.

Фильтруйте по уровню и времени. Когда что-то сломалось в 15:47 — смотрите на ERROR-логи в диапазоне 15:44–15:50. Не листайте всё подряд.

Следите за паттернами. Одна ошибка — случайность. Сто одинаковых ошибок за минуту — инцидент. Настройте агрегацию: Kibana и Grafana умеют группировать одинаковые сообщения и показывать их количество.

Не читайте логи глазами в боевой ситуации. Когда всё горит — люди начинают листать tail -f и пытаться что-то увидеть в потоке. Это не работает. Используйте фильтры: grep ERROR app.log | tail -100 или запрос в Kibana/Grafana.

Алерты на основе логов

Логи без алертов — это как зеркало заднего вида, в которое вы смотрите только после аварии. Настройте уведомления:

  • Больше N ошибок в минуту — тревога
  • Появилась новая строка с FATAL — немедленное уведомление
  • Рост времени ответа выше порога — предупреждение

Где настроить: Grafana Alerting (работает с Loki), ElastAlert для ELK-стека, встроенные алерты в Datadog и других облачных решениях. Уведомления — в Telegram, Slack, PagerDuty.

Минимальный набор алертов для продакшена: ERROR rate > 10 в минуту, 5xx ответы > 1% от трафика, приложение не пишет логи дольше 2 минут (возможно, упало).

Типичные ошибки

Логи только на диске приложения. Сервер упал — логи потеряны. Централизуйте сбор.

Нет timestamps или они в локальном времени. Всегда используйте UTC и ISO 8601: 2026-03-15T14:23:01Z. Когда сравниваете логи с разных серверов в разных часовых поясах — спасёт.

Логируют успех, забывают про контекст ошибки. ERROR: failed — бесполезно. ERROR: failed to update order #4821, reason: duplicate key violation, table: orders — уже можно работать.

Синхронная запись в лог блокирует приложение. Если писать логи синхронно в медленное хранилище — это замедляет обработку запросов. Используйте асинхронную запись с буфером.

Нет ротации. Диск заполняется логами, сервер падает. Настройте logrotate или встроенную ротацию в вашем логгере.

Логирование в контексте DevOps

Логирование — это часть большой наблюдаемости (observability). Полная картина складывается из трёх составляющих:

  • Метрики — что происходит (CPU, память, RPS, latency)
  • Логи — почему это происходит
  • Трейсы — где именно в цепочке сервисов возникла проблема

Если вы только начинаете выстраивать мониторинг — начните с логов и метрик. Трейсинг (Jaeger, Tempo) добавляйте, когда у вас уже несколько микросервисов и вы теряетесь в том, какой из них виноват в медленном ответе.

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

С чего начать прямо сейчас

Если у вас уже есть работающий сервис без нормального логирования — план действий:

  1. Переведите логи в структурированный формат (JSON). Займёт час-два.
  2. Настройте ротацию файлов на сервере через logrotate.
  3. Поднимите Loki + Grafana на отдельном VPS (или возьмите любой облачный сервис).
  4. Установите Promtail или Filebeat на серверы приложений.
  5. Настройте минимальные алерты: FATAL, высокий ERROR rate.

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

Логи — это не скучная инфраструктура. Это то, что позволяет спать спокойно и не узнавать о проблемах от пользователей.