awesome-everything EN
↑ Обратно к восхождению

Наблюдаемость

Зачем нужны структурные логи: дневник против таблицы

Суть Free-text-логи выглядят читаемо и становятся незапрашиваемыми на масштабе. Структурные логи — это таблица, в которой каждая строка — запись с адресуемыми полями.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на junior-высоте — поверхность
◷ 8 min

Пейджер срабатывает в 02:00. У тебя 10 миллионов log-строк и пять минут. Если логи free-text — пишешь regex и надеешься. Если логи структурные — пишешь один запрос и знаешь.

Дневник против таблицы

Free-text-логи — это дневник. Структурные логи — таблица. Оба фиксируют, что произошло, но только одна позволяет спросить «покажи каждый payment-fail за прошлую неделю с группировкой по upstream-провайдеру» без чтения каждой записи руками.

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

У таблицы есть правила: у каждой строки одинаковые колонки, у каждой колонки тип, каждое значение в нужной ячейке.

ФорматПримерЗапрос «status 503 от payment»
Free-text[ERROR] checkout: gateway timeout (payment, status 503)Regex, substring-match, пропускает варианты
Структурный JSON{“level”:“error”,“upstream”:“payment”,“status”:503}Один индексированный запрос, миллисекунды

Почему стоимость накапливается

Цена log-строки платится в трёх местах: на write-time (CPU + RAM на сериализацию), в транспорте (egress), и на backend’е (ingest-GB + indexed-event-count + retention-байты). Структурные логи не бесплатны — JSON-сериализация стоит CPU — но они окупаются на query-time.

Free-text-строка «user 42 failed checkout because gateway returned 503» требует regex- и substring-поиска. Те же данные в JSON {"level":"error","user_id":42,"route":"/checkout","upstream":"payment-gateway","upstream_status":503,"trace_id":"abc..."} — это один запрос по индексированному полю с миллисекундным ответом на неделях данных.

Дисциплина: выбрать схему, заполнять её консистентно и трактовать log-строку как API, который твоё будущее on-call-«я» прочитает в 03:00 без контекста.

Сценарий триажа

Антон · Браузер получает пейджер: error rate на checkout. Запрашивает service:checkout AND level:error AND @timestamp:[now-15m TO now] — получает 240 матчевых событий, каждое — JSON-запись. Фасетит по полю upstream: 220 из 240 ошибок — от payment-gateway. Фасетит по upstream_status: все 220 — HTTP 503. Диагноз за 30 секунд.

Дима · Origin-сервер тянет один trace_id из упавшей log-строки и открывает трейс, чтобы увидеть, что вызов gateway отваливается по timeout. Будь логи free-text — Bea написала бы regex, упустила бы случаи с другой формулировкой и потеряла бы 10 минут.

Почему это работает

JSON — де-факто кодировка структурных логов в 2026, не XML, не protobuf, не custom binary. JSON — наименьший общий знаменатель: его всё ещё может прочитать человек в терминале, его умеет парсить любой logging-backend из коробки, и стандартная библиотека любого языка сериализует его дёшево. JSON Lines (один JSON-объект на строку, разделённый newline) — каноничный формат: append-friendly, streamable, parseable построчно, удобен для grep + jq.

Викторина

Какая log-строка — структурная?

Расставь шаги по порядку

Расставь поля, которые должны быть в каждой продакшн-log-строке, примерно по приоритету:

  1. 1 timestamp (ISO-8601 UTC, самое базовое)
  2. 2 level (DEBUG / INFO / WARN / ERROR)
  3. 3 service.name (какой сервис эмитировал)
  4. 4 trace_id и span_id (join-ключ к трейсам)
  5. 5 message (читаемое резюме)
  6. 6 event-specific поля (route, status_code, user_segment, ...)
  7. 7 resource-атрибуты (host, region, version — обычно ставятся один раз)
Закончи аналогию

Заполни пропуск: структурный лог — это _______, где у каждой строки одинаковые колонки, у каждой колонки тип, и каждое значение в нужной ячейке.

Вспомните перед уходом
  1. 01
    В двух предложениях — почему JSON — де-факто кодировка структурных логов в 2026?
  2. 02
    В чём цена бесструктурности и когда она проявляется?
  3. 03
    Почему trace_id — обязательное поле log-строки, а не опциональное?
Итог

Структурные логи — JSON-события со стабильной схемой: каждая строка — запись одинаковой формы с timestamp, level, service.name, trace_id, message и event-specific полями. Free-text-логи фиксируют те же данные предложениями — читаемо на малом масштабе и незапрашиваемо на миллионах строк, потому что каждый запрос требует regex. Главная отдача — на query-time: индексированные JSON-поля отвечают «покажи все 503 от payment-gateway за последние 15 минут» за один запрос с миллисекундной задержкой. Цена — на write-time (CPU для сериализации) и на backend’е (indexed-события биллятся за миллион). Дисциплина — трактовать log-схему как API-контракт: консистентный между сервисами, заполняемый в каждой строке.

Связанные уроки
встречается в268
Продолжить восхождение ↑Схема продакшн-лога: поля, которые несёт каждая строка
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.