Как писать разбор инцидента, чтобы из него учились
Сервис упал в три часа ночи, дежурный поднял его за двадцать минут, все выдохнули — и разбор инцидента так и остался незаписанным, потому что «ну починили же, что тут обсуждать». Через два месяца всё повторяется один в один, только теперь падает днём при полной нагрузке. Разбор инцидента — не бюрократическая отписка после ЧП и не поиск, кого уволить, а механизм, который превращает пережитую боль в реальное знание о том, как устроена ваша система.
Содержание
- Зачем нужен разбор инцидента и чем он не является
- Blameless-принцип: почему нельзя искать виноватого
- Хронология событий: факты без интерпретации
- Реальное воздействие на пользователей и бизнес
- Корневая причина: копаем до технического механизма
- Конкретные action items: кто, что, когда
- Разбирайте не только крупные инциденты
Зачем нужен разбор инцидента и чем он не является
Разбор инцидента (postmortem, incident review) — документ, который команда пишет после устранения проблемы с одной целью: понять, что именно в процессах, инструментах и архитектуре позволило проблеме случиться и остаться незамеченной, и изменить это так, чтобы похожая ситуация либо не повторилась, либо была обнаружена и устранена быстрее в следующий раз. Разбор не предотвращает вообще любые будущие сбои — он закрывает конкретный класс проблем, с которым команда только что столкнулась.
Это не то же самое, что два часто встречающихся суррогата. Первый — формальная отписка для галочки: строчка «сервер упал, перезапустили, работает», закрытый тикет, все забыли. Через такой документ ничему нельзя научиться — в нём нет ни настоящей причины, ни следующего шага. Второй суррогат — охота на виноватого: разбор превращается в выяснение, кто из инженеров нажал не ту кнопку. Он может выглядеть содержательным, но систематически разрушает главный ресурс, нужный для понимания причины, — честность людей, участвовавших в инциденте.
Хороший разбор смотрит и в прошлое, и в будущее: фиксирует, что произошло на самом деле, и превращает это знание в конкретное изменение. Без первого не будет второго — если хронология и причина размыты, action items окажутся либо лозунгами вроде «повысить внимательность», либо промахнутся мимо настоящей проблемы.
Blameless-принцип: почему нельзя искать виноватого
Это центральный принцип культуры разбора инцидентов: если его нарушить, документ выйдет технически правильным по форме и бесполезным по сути.
Механизм простой и жестокий. Как только в компании закрепляется практика, что разбор заканчивается наказанием конкретного человека — выговором, депремированием, разбором «кто накосячил» перед начальством, — люди рационально начинают вести себя иначе. Инженер, который сам по ошибке отключил алертинг на час, в blame-культуре промолчит об этом или сформулирует расплывчато: «мониторинг не сработал» вместо «я вручную отключил алерт на время техработ и забыл включить обратно». Формально это тоже правда, но она не даёт понять реальный механизм отказа — и та же причина может повториться незамеченной.
Это не гипотетическая проблема, а динамика, знакомая по авиации и медицине задолго до IT: там, где ошибка означает наказание, свидетели перестают о ней сообщать, и система становится менее безопасной, а не более — она теряет доступ к информации, нужной для исправления. Именно поэтому в авиации действует культура добровольных отчётов без наказания за сам факт отчёта — эту логику индустрия ПО и заимствовала под названием blameless postmortem.
Практически это означает: в тексте разбора не должно быть формулировок, которые называют человека причиной проблемы, даже завуалированно.
Плохо (обвинительная формулировка):
- «Иван выкатил миграцию без ревью и уронил базу»
- «Дежурный проспал алерт и продлил простой на 40 минут»
- «Разработчик не протестировал код перед деплоем»
Хорошо (системная формулировка того же факта):
- «Процесс деплоя миграций на тот момент не требовал обязательного ревью для изменений схемы БД — это позволило потенциально опасному запросу попасть в прод»
- «Алерт по этому каналу не эскалируется повторно и не дублируется на второй канал, если дежурный не отреагировал за 5 минут — из-за этого сработавшее уведомление осталось непрочитанным 40 минут»
- «В pipeline деплоя нет обязательного шага автотестов для этого сервиса — изменение попало в прод без прогона регрессионных тестов»
Во втором варианте каждый раз называется система — процесс, конфигурация алертинга, состав pipeline, — а не человек, при этом факт не искажается. Суть blameless-подхода не в том, чтобы никого не обвинять и всё замять, а в том, чтобы задавать правильный вопрос: не «кто это сделал», а «что в системе позволило этому случиться и не быть замеченным раньше». Если один инженер одним действием уронил прод-базу, значит, в системе нет защиты от такого действия — а защита нужна именно потому, что люди ошибаются, это рабочая гипотеза, вокруг которой строится инженерия надёжности. Похожий взгляд — не искать «крайнего», а чинить процесс — разбирался в статье про почему мониторинг есть, а инцидент всё равно никто не заметил.
Важная оговорка: blameless не означает «безответственность» — это про то, чтобы разбор был безопасным пространством для честного изложения фактов. Дисциплинарные вопросы, если они действительно нужны, решаются отдельно от документа и не его языком.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPSХронология событий: факты без интерпретации
Первый раздел разбора — точная хронология: что и когда произошло, как последовательность объективных фактов, без оценочных слов и предположений о причинах на этом этапе. Хронология отвечает на вопрос «что случилось», а не «почему» — это специально разделено, потому что смешение факта и интерпретации на раннем этапе обычно и приводит к поспешным, часто обвинительным выводам.
Что обязательно попадает в хронологию:
- момент, когда проблема реально началась технически (если известен — часто выясняется только в процессе расследования);
- момент обнаружения — кто или что заметило проблему и в какое время;
- ключевые действия по диагностике и купированию — что проверяли, что сработало и что нет;
- момент, когда воздействие на пользователей прекратилось (mitigated) — не всегда совпадает с полным разрешением;
- момент полного разрешения (resolved) — когда причина устранена и риск повтора снят.
Формат — простая таблица времени в UTC или в едином часовом поясе команды (важно указать явно, иначе при разборе через месяц никто не вспомнит, в каком поясе были отметки):
| Время (UTC) | Событие |
|---|---|
| 02:14 | Начались 502 от API согласно логам nginx (обнаружено post-factum) |
| 02:31 | Алерт в Telegram: доля 5xx > 5% на /api/orders |
| 02:33 | Дежурный инженер увидел алерт, начал диагностику |
| 02:41 | Обнаружено: под БД достиг лимита max_connections (200/200) |
| 02:47 | Перезапущен pgbouncer, соединения освобождены — 5xx прекратились |
| 02:50 | Подтверждено восстановление по метрикам, простой закрыт как mitigated |
| 10:20 | Найдена причина исчерпания пула — см. корневую причину ниже, resolved |
Mitigated (02:50) и resolved (10:20) — разные моменты, и это нормально: проблему часто быстро купируют, не понимая ещё до конца, почему она возникла, а расследование корневой причины занимает часы или дни уже без давления «пользователи страдают прямо сейчас». Указывать оба момента честно — часть хорошей хронологии.
Хронология собирается из объективных источников — логов, метрик, истории алертов, команд в терминале дежурного, — а не по памяти через неделю. Если в команде уже настроен единый сбор логов с нескольких серверов, восстановить точную последовательность на порядок проще, чем вручную сверять время на нескольких машинах с несинхронизированными часами.
Реальное воздействие на пользователей и бизнес
Второй раздел — честная оценка того, насколько серьёзной была проблема на самом деле, без преуменьшения и без драматизации. Воздействие определяет приоритет action items из раздела ниже: проблема, задевшая 0.1% запросов на 3 минуты, и проблема, положившая checkout на час, заслуживают разного объёма работы над предотвращением повтора. Заниженная оценка «да несерьёзно, пара минут» обычно оказывается способом избежать неприятного разговора, а не отражением реальности.
Что стоит включить:
- сколько времени длилось воздействие на пользователей (до момента mitigated, а не resolved);
- какая доля пользователей/запросов была затронута — числом из метрик («28% запросов к /checkout получили 500 в течение 16 минут»), а не словами «многие» или «часть»;
- что именно пользователь видел или не мог сделать — конкретное действие («не могли оформить заказ», «получали письма с задержкой до 40 минут»);
- была ли потеря данных, и если да — какого рода и в каком объёме;
- есть ли измеримые бизнес-последствия — упущенные заказы, обращения в поддержку; здесь уместно оговорить, что цифра ориентировочная, если это оценка.
Если у сервиса есть публичная status-страница, запись из неё с точными метками — хороший объективный якорь, независимый от внутренних логов. Стоит также писать «SEV-уровень» инцидента (SEV1 — критично, весь сервис недоступен; SEV2 — деградация ключевой функции; SEV3 — незначительное воздействие) — это помогает быстро оценивать серьёзность по списку прошлых разборов.
Корневая причина: копаем до технического механизма
Здесь чаще всего разбор проваливается по качеству, даже без всякой охоты на виноватых — просто потому что первая правдоподобная причина, приходящая в голову во время тушения пожара, обычно неполная. «Сервер упал» — не корневая причина, а симптом. Хорошая корневая причина отвечает на вопрос «почему» столько раз, сколько нужно, чтобы дойти до механизма, который действительно можно исправить.
Плохо (симптом вместо причины):
- «Сервер упал из-за нехватки памяти»
- «База данных стала недоступна»
- «Диск заполнился, сервис перестал писать логи и упал»
Хорошо (доведено до технического механизма):
- «Процесс упал по OOM, потому что фоновая задача экспорта отчётов грузила весь датасет в память вместо постраничной обработки; лимит памяти контейнера не был выставлен, поэтому OOM убил весь под целиком»
- «БД стала недоступна, потому что пул соединений pgbouncer был исчерпан долгими запросами от новой аналитической выгрузки, не использовавшей read-replica и не имевшей таймаута на клиенте»
- «Диск заполнился логами из-за отсутствия ротации на новом сервисе (см. типичную грабля «логи без ротации») — при 100% диска systemd не смог создать файл блокировки, и сервис ушёл в краш-луп»
Практический метод — простое «5 почему»: берёте первый ответ и спрашиваете «почему» ещё раз, пока не упрётесь в механизм, который можно изменить. «Сервер упал» → почему? «Кончилась память» → почему? «Процесс экспорта грузил весь датасет разом» → почему? «Не было лимита памяти на контейнер» → почему не было лимита? «В шаблоне деплоя новых сервисов лимиты не заданы по умолчанию» — вот это уже action item.
Часто причин у одного инцидента несколько — стоит перечислить и техническую (что сломалось), и организационную (почему это не поймали раньше — не было теста, не было алерта, не было ревью). Хороший пример такой двойной причины разбирался в статье про диск в RAID, который сыпался месяц, пока мониторинг молчал: техническая причина — деградация диска, организационная — отсутствие алерта именно на этот класс событий.
Конкретные action items: кто, что, когда
Разбор без раздела действий на будущее — просто рассказ о прошлом, каким бы честным он ни был. Смысл всей предыдущей работы — превратить понимание причины в измеримое изменение системы. Здесь тоже легко скатиться в бесполезную формулировку, только не обвинительную, а расплывчатую.
Плохо (не действие, а лозунг):
- «Быть внимательнее при деплое миграций»
- «Улучшить мониторинг»
- «Повысить качество ревью кода»
Хорошо (конкретное, проверяемое, с владельцем и сроком):
| Действие | Ответственный | Срок |
|---|---|---|
| Добавить обязательный лимит memory/cpu в шаблон Helm-чарта для новых сервисов | Петров (платформа) | до 12.09 |
| Настроить алерт на % использования пула pgbouncer > 80% | Сидорова (SRE) | до 08.09 |
| Вынести аналитические выгрузки на read-replica, запретить прямые запросы к мастеру из BI-инструмента | Козлов (данные) | до 20.09 |
| Добавить в CI обязательный шаг: миграции схемы требуют approve от второго инженера | Иванов (бэкенд) | до 10.09 |
| Добавить кейс «пул соединений исчерпан долгими BI-запросами» в регрессионные проверки перед релизом инфраструктуры | Сидорова (SRE) | до 15.09 |
Каждый пункт можно однозначно проверить — «сделано» или «не сделано» — в отличие от «быть внимательнее», которое нельзя ни выполнить, ни провалить формально. Тот же принцип — конкретный случай идёт в постоянную проверку, а не в разовое обещание быть внимательнее — разбирался применительно к качеству ответов ИИ-моделей в статье про батарею тестов для своей LLM: нашли провал — добавили его тест-кейсом в регрессионный набор. С инфраструктурой логика та же: нашли failure mode — превратили в алерт, тест, лимит или обязательный шаг процесса.
Владелец должен быть конкретным человеком, а не отделом целиком («SRE-команда») — иначе ответственность размазана и её нет ни у кого. Срок должен быть реалистичным, но не бесконечным — важная задача попадает в ближайший спринт, а не в бэклог «когда-нибудь». Имеет смысл назначить отдельного человека ответственным за проверку статуса всех пунктов через оговорённый срок: без этого action items имеют тенденцию тихо забываться.
Разбирайте не только крупные инциденты
Самая частая практическая ошибка — писать разборы только для по-настоящему серьёзных, «пожарных» инцидентов, а мелкие сбои (пятиминутный всплеск 500-х, разовый деплой с откатом, ложный алерт) оставлять без документа вовсе, потому что «несерьёзно, не стоит бюрократии». Это ошибка сразу по двум причинам.
Во-первых, мелкий сбой — дешёвый источник того же системного знания, что и крупный, но без цены крупного простоя. Разобрав пятиминутный всплеск 500-х по той же методике, часто находишь ровно ту же уязвимость, которая через два месяца при более высокой нагрузке превратится в часовой простой.
Во-вторых, регулярная практика коротких разборов делает разбор по-настоящему крупного инцидента гораздо менее пугающим для команды. Если разбор — редкое событие раз в год после кризиса, он воспринимается как нечто тревожное само по себе, почти вызов на ковёр, даже при формально blameless-культуре. Если же команда пишет короткий разбор после каждого сбоя, формат становится рутинной частью работы — как код-ревью или ретроспектива. Когда случается крупный инцидент, команда просто применяет уже привычный формат, а не изобретает процесс на ходу в стрессе.
Практический ориентир: для мелких инцидентов документ можно сократить до одной страницы — короткая хронология, строка воздействия, пара строк причины, один-два action item. Полный формат с таблицей по часам стоит держать для инцидентов выше определённого порога серьёзности (SEV1/SEV2), иначе именно избыточная бюрократия для мелочей и убьёт саму привычку писать разборы.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать VPSНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Через сколько времени после инцидента нужно писать разбор?
Пока хронология свежа в памяти — обычно в течение 24–48 часов после resolved. Если тянуть неделями, детали стираются, а разбор рискует не состояться вовсе.
Кто должен писать разбор — тот, кто чинил инцидент?
Обычно да, но полезно, чтобы черновик проверил кто-то не участвовавший напрямую — свежий взгляд быстрее замечает, где формулировка скатывается в обвинительную.
Нужно ли показывать разбор всей компании, а не только команде?
Для значимых инцидентов — да, системные уроки одной команды часто применимы к другим; для мелких разборов достаточно видимости внутри команды.
Что делать, если причина — реальная ошибка одного человека, например случайно набранная не та команда?
Формулировать системно всё равно: не «Иван набрал не ту команду», а «в проде остаётся возможность выполнить разрушительное действие одной командой без подтверждения» — и решение искать в защите (dry-run, ограничение прав), а не в осуждении человека.
Как понять, что разбор написан хорошо?
Покажите документ человеку, не участвовавшему в инциденте. Если он может объяснить, что случилось, насколько серьёзно, из-за какого механизма и что теперь изменится — разбор состоялся.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →