Логирование (логи)

8 сентября 2026 · ~17 мин чтения

концепция devops наблюдаемость отладка основы

Логирование (логи)

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

История

Слово пришло с моря. В XVI–XVII веках скорость корабля измеряли лагом (англ. log — «полено»): деревяшку на верёвке с узлами бросали за борт и считали, сколько узлов уйдёт за полминуты. Отсюда «узлы» как единица скорости. Результаты замеров, курс, погоду и происшествия записывали в log-book — судовой журнал. Слово закрепилось за самим журналом: log — это «хронологическая запись того, что было».

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

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

  1. syslog, начало 1980-х. Эрик Оллман (Eric Allman) в Университете Беркли написал для своего почтового сервера Sendmail службу, которая принимает сообщения от любых программ и складывает их в общий файл. Он ввёл две вещи, живущие до сих пор: уровни важности (от emerg до debug, восемь штук) и источник (facility: ядро, почта, авторизация и так далее). Протокол много лет жил без формального описания и был задокументирован задним числом в RFC 3164 (2001). Актуальный стандарт — RFC 5424 (2009), автор Райнер Герхардс (Rainer Gerhards), он же автор rsyslog.

  2. log4j, 1996–2001. Чеки Гюлькю (Ceki Gülcü) начал библиотеку в IBM, в 2001-м она стала проектом Apache. Log4j сделал стандартом иерархию логгеров (по именам пакетов), уровни TRACE / DEBUG / INFO / WARN / ERROR / FATAL и разделение на «кто пишет» (logger), «куда» (appender) и «в каком виде» (layout). Эту модель потом скопировали почти все языки: модуль logging в Python (PEP 282, Винай Саджип, Python 2.3, 2003), NLog и Serilog в .NET, winston в Node.js.

  3. Централизованный сбор, 2003–2011. Splunk (2003) первым продал идею «залей все логи в одно место и ищи как в Google». Открытая альтернатива сложилась из трёх проектов: Elasticsearch (Шай Банон, 2010), Logstash (Джордан Сиссел, 2009) и Kibana (Рашид Хан, 2011) — стек ELK.

  4. Логи как поток и как структура данных, 2011–2013. Манифест Twelve-Factor App (Адам Уиггинс, Heroku, 2011) в пункте XI сказал: приложение не должно управлять файлами логов, оно пишет в stdout, а окружение решает, куда это девать. А Джей Крепс (Jay Kreps) из LinkedIn в 2013-м в эссе «The Log» показал, что лог — не только для отладки: это фундаментальная структура данных, на которой стоят репликация баз, Kafka и потоковая обработка.

  5. Бинарный журнал и структурные логи, 2011–наши дни. systemd-journald (Леннарт Пёттеринг, 2011) заменил текстовые файлы индексированным бинарным журналом. Apple в macOS 10.12 (2016) сделала то же самое (unified logging). Параллельно распространились структурные логи в JSON, а в 2019-м появился OpenTelemetry, где логи — один из трёх «сигналов наблюдаемости» вместе с метриками и трассами.

Отдельная веха со знаком минус: в декабре 2021-го уязвимость Log4Shell (CVE-2021-44228) в log4j 2 позволила выполнять чужой код на сервере, просто отправив специальную строку, которую сервер залогирует. Оценка опасности — максимальные 10,0 из 10. Индустрия впервые массово осознала, что лог — тоже поверхность атаки.

Что это такое

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

Три свойства делают лог логом:

Полезно различать соседние вещи:

Аналогии из жизни

Судовой журнал. Вахтенный каждые несколько часов записывает курс, скорость, погоду, происшествия. Через месяц по журналу можно восстановить весь рейс, а в случае аварии он становится главным документом расследования. Так работает: хронология, автор каждой записи, невозможность вырвать страницу.
Где ломается: в судовой журнал пишет человек, который решает, что важно. Программа не решает — она пишет то, что ей приказал разработчик, и с той частотой, с какой приказал. Поэтому лог бывает одновременно огромным и бесполезным: тысяча строк «запрос обработан» и ни одной о том, почему он обработан неправильно. И судовой журнал — это ещё и «почему»: капитан пишет мотивы решений. Машина мотивов не знает.

Контрольная лента кассы. Каждая пробитая покупка печатается на второй ленте внутри аппарата. Продавец не может её отредактировать, налоговая может запросить. Так работает: полнота, только дописывание, доказательство того, что операция была.
Где ломается: кассовая лента обязана быть полной по закону, и аппарат не работает, если лента кончилась. Лог приложения так не устроен: если диск переполнен, буфер не сброшен, процесс убит — записи молча теряются, а программа продолжает работать. Лог не гарантирует, что в нём есть всё, что случилось. Есть только то, что успели записать.

Медицинская карта. Разные врачи в разное время дописывают в одну карту: терапевт, хирург, лаборатория. Каждая запись — дата, кто, что обнаружил, что назначил. Чтобы понять, откуда взялась аллергия, нужно прочитать всю историю. Так работает: несколько источников пишут в одну хронологию по общему ключу (пациент), и именно склейка даёт картину.
Где ломается: у пациента одна карта, а у распределённой системы лог каждого сервиса лежит на своём сервере. Если не завести общий идентификатор запроса и не свозить всё в одно место, получится десять карт разных больниц про одного человека, и никто не сложит их вместе. Плюс в карту пишут по регламенту, с обязательными полями. В логи пишут как придётся, и «дата» в одном сервисе окажется в UTC, а в другом — в местном времени.

Как это работает

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

Шаг 1. Событие в коде. Разработчик в нужном месте вызывает логгер и назначает уровень:

log = logging.getLogger("collector")
log.info("виток %d завершён, собрано %d записей", n, count)
log.warning("проект %s не ответил, попытка %d", slug, attempt)
log.error("не удалось записать файл %s", path, exc_info=True)

Уровень — это не «насколько громко», а «кому это нужно». DEBUG — разработчику при отладке. INFO — оператору, чтобы видеть ход дел. WARNING — что-то странное, но справились. ERROR — не справились, но живём. CRITICAL (в syslog — emerg/alert) — всё, дальше нельзя.

Шаг 2. Фильтр по порогу. У логгера есть настроенный минимальный уровень. Если в проде стоит INFO, все DEBUG отбрасываются ещё до форматирования. Это главный рычаг управления объёмом: тот же код в тестах пишет всё, в проде — только существенное.

Шаг 3. Форматирование записи. Логгер собирает из события запись. Классический вид — одна строка текста:

2026-09-07 17:56:03,412 INFO collector: виток 96 завершён, собрано 37 записей

Современный вид — одна JSON-строка на событие (структурный лог):

{"ts":"2026-09-07T14:56:03.412Z","level":"info","logger":"collector",
 "msg":"виток завершён","round":96,"count":37,"pid":50771}

Разница принципиальна. Текстовую строку человек читает глазами, а машина парсит регулярками и ошибается. JSON машина разбирает надёжно, зато человеку без инструмента читать тяжело. Это тот самый формат JSONL (по одной JSON-записи на строку), в котором Claude Code хранит свои сессии.

Минимальный набор полей хорошей записи: время (лучше в UTC с явной зоной), уровень, источник (имя логгера, PID, хост), сообщение и контекст (идентификатор запроса, пользователя, задачи).

Шаг 4. Обработчик (handler, appender) — куда писать. Вариантов несколько, и их можно комбинировать:

Шаг 5. Сбор и доставка. На каждом сервере стоит агент (Filebeat, Fluent Bit, Vector, promtail), который читает файлы или journald, дописывает метаданные (хост, контейнер, окружение) и отправляет в центральное хранилище. Здесь же часто фильтруют и сэмплируют: если однотипных ошибок 100 000 в минуту, оставить каждую сотую.

Шаг 6. Хранение и индекс. Elasticsearch индексирует полный текст каждой записи (дорого, но ищет по любому слову). Loki индексирует только метки (хост, сервис), а тексты хранит сжатыми (дёшево, ищет медленнее). ClickHouse хранит колонками и хорош, когда логи структурные и по ним считают агрегаты.

Шаг 7. Чтение. Простейший инструмент — tail -f (следить за хвостом файла в реальном времени) и grep. В центральной системе — Kibana или Grafana с запросами вроде «все ERROR сервиса X за последний час с этим request_id». Поверх строятся алерты: «если за 5 минут больше 50 ошибок — сообщение в Telegram».

Вся цепочка одной схемой:

код --> logger --> [порог] --> formatter --> handler
                                              |-- stderr --> systemd/launchd --> journald
                                              |-- файл  --> logrotate
                                              `-- сеть  --> агент --> хранилище --> поиск/алерты

Лог — это то, что программа о себе думает, а не то, что есть

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

Где встречается в обычной жизни

Где встречается в IT и бизнесе

Кто пользуется

Логи пишут все программы без исключения, поэтому интереснее посмотреть на масштаб тех, кто на логах строит бизнес:

Альтернативы и конкуренты

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

Альтернативы внутри мира логов — что выбрать для хранения:

Когда НЕ стоит использовать

Секреты в логах

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

Связанные понятия

Литература и источники

Где встретилось у меня

Вчера логи были главным каналом связи с работой, которая шла без меня: сутки на mac mini крутился сборщик подменных номеров, и о его состоянии я узнавал только через лог сборщика и лог процесса-сторожа, которые по расписанию читали дешёвые агенты. В другой задаче лог агента Росреестра честно рапортовал об успешной выгрузке, а файлов на диске не оказалось — и это стало правилом «успешный лог не равен результату». Ещё один журнал (звонков) выдал «тихий ноль», потому что скрипт, не залогинившись, получил страницу авторизации и молча счёл её пустой. Ну и сам этот блог — производная от лога: статью ты читаешь потому, что Claude Code пишет JSONL каждой сессии.

Краткое резюме