Postmortem: почему 90% разборов инцидентов — это зря потраченное время?
Большинство Postmortem (постов), которые я видел, — это красиво оформленное ничто. Хронология на три страницы, «команда приняла все меры», root cause — «ошибка в коде». Закрыли, забыли, через полгода повторили тот же факап, только в три раза дороже.
Пост — это не бумажка для галочки. Это инструмент, который либо чинит систему, либо имитирует бурную деятельность. Разница — в нескольких простых вещах, про которые почему-то постоянно забывают.
Главное правило: мы не ищем виноватых, мы чиним систему. Если хотя бы раз превратить разбор в охоту на ведьм — всё, команда вам больше ни одного честного факапа не отдаст. Будут приносить отполированные сказки, где всё «случайно совпало». А вы будете чинить ветряные мельницы.
Это, кстати, парадокс постов. Чем безопаснее среда для честного разбора, тем жёстче и точнее выходит root cause. Люди сами признают, где свернул не туда, если знают, что за это не уволят.
Хороший POST начинается с неприятного вопроса: почему наша система позволила этому случиться?
Допустим, в коде был баг. Окей. А почему его не поймали тесты? Почему мониторинг не поднял тревогу? Почему релиз с таким изменением вообще можно было выкатить? Почему сценарий не был учтён при проектировании? А если всё это уже было известно команде, почему задача на исправление спокойно лежала в бэклоге?
Вот тогда начинает проявляться настоящая причина. И она очень часто оказывается скучнее, чем «разработчик ошибся».
QA не проверил редкий сценарий. Релизный процесс пропустил опасное изменение. Не было нужного алерта. Две команды по-разному понимали контракт. В архитектуре оказался костыль, который когда-то поставили «временно», а потом забыли.
Классика. Временный костыль в проде почему-то обладает удивительной живучестью.
Поэтому нормальный разбор для меня выглядит примерно так.
Сначала восстанавливаем хронологию.
Что должно было происходить? Что произошло на самом деле? Когда появилась первая проблема? Как мы её обнаружили? Что сделали для восстановления?
Потом считаем ущерб.
Не «сервис немного полежал». А сколько пользователей пострадало, сколько операций не прошло, какой был финансовый эффект, что происходило с задержками и RPS.
Потом задаём неприятные вопросы.
И самое важное — превращаем ответы в конкретные изменения.
Не «улучшить мониторинг». А поставить конкретный алерт.
Не «усилить тестирование». А добавить конкретный сценарий.
Не «быть внимательнее на релизах». А изменить процесс так, чтобы человеческая ошибка перестала быть единственной линией защиты.
У каждой такой задачи должен быть владелец и срок. И если задача критична для устранения причины, она должна блокировать закрытие POST. Иначе POST превращается в кладбище хороших намерений.
Есть ещё одна ловушка.
Иногда команда находит баг и останавливается на нём. Формально root cause есть. Артефакт заполнен. Все довольны.
А потом через полгода происходит похожий инцидент.
Потому что мы исправили конкретный баг, но не исправили условие, при котором такие баги спокойно доезжают до прода.
Смысл поста в том, чтобы следующий похожий инцидент стало сложнее повторить.
Меньше ручных действий. Больше автоматических проверок. Лучше телеметрия. Понятнее ответственность между командами. Меньше мест, где один человек может случайно уронить всё.
И да, иногда выясняется, что причиной был AI-сгенерированный код.
Это тоже не ответ.
Вопрос всё тот же: почему код с проблемой смог пройти весь наш процесс и попасть в прод?
Если ответ — «ну, разработчик не заметил», значит, мы просто нашли крайнего.
А система осталась такой же.