Postmortem (Постмортем)
Postmortem — это детальный анализ инцидента после его завершения, включающий описание причин, последствий и выработку конкретных решений для предотвращения повторения подобных проблем. Культура postmortem является основой Blameless Culture в SRE.
Принципы Blameless Postmortem
- Без обвинений — фокус на процессах, а не на людях
- Обучение — извлечение уроков из инцидентов
- Прозрачность — открытое обсуждение проблем
- Системное мышление — анализ системы в целом
Структура Postmortem
- Краткое описание — что произошло
- Временная линия — хронология событий
- Root cause analysis — анализ корневых причин
- Воздействие — влияние на пользователей и бизнес
- Что сработало хорошо — положительные моменты
- Что можно улучшить — области для развития
- Action items — конкретные шаги для улучшения
Пример шаблона Postmortem
1# Postmortem: Database Outage - 2025-01-27
2
3## Краткое описание
427 января 2025 года в 14:30 UTC произошел полный отказ основной базы данных,
5что привело к недоступности API в течение 45 минут.
6
7## Воздействие
8- Полная недоступность API для всех пользователей
9- 100% error rate на критических эндпоинтах
10- Потеря ~1000 запросов пользователей
11- Нарушение SLO (99.9% → 98.9% за месяц)
12
13## Временная линия (UTC)
14- 14:30 - Первые алерты о высокой задержке DB
15- 14:32 - Полный отказ подключений к базе
16- 14:35 - Incident Commander назначен
17- 14:40 - Переключение на резервную базу начато
18- 14:50 - Восстановление трафика на standby
19- 15:15 - Полное восстановление сервиса
20
21## Root Cause Analysis
22### Основная причина
23Исчерпание дискового пространства на основном сервере БД
24из-за неконтролируемого роста логов.
25
26### Способствующие факторы
27- Отсутствие алертов на дисковое пространство
28- Отключенная автоматическая ротация логов
29- Недостаточный мониторинг роста данных
30
31## Что сработало хорошо
32- Быстрое обнаружение проблемы (2 минуты)
33- Эффективная коммуникация в команде
34- Резервная база была готова к переключению
35
36## Action Items
37| Действие | Ответственный | Срок | Статус |
38|----------|---------------|------|--------|
39| Настроить алерт на дисковое пространство | @sre-team | 2025-02-03 | В работе |
40| Включить автоматическую ротацию логов | @db-team | 2025-02-01 | Выполнено |
41| Автоматизировать failover процедуру | @sre-team | 2025-02-15 | Запланировано |
42
43## Извлеченные уроки
44- Важность мониторинга всех ресурсов, не только производительности
45- Необходимость регулярного тестирования disaster recovery процедур
46- Ценность автоматизации рутинных операций
Процесс проведения Postmortem
- Сразу после инцидента — собрать первичные данные
- В течение 24-48 часов — провести встречу команды
- Через неделю — финализировать документ
- Через месяц — проверить выполнение action items
Инструменты для Postmortem
1# Автоматизация сбора данных для postmortem
2import json
3from datetime import datetime, timedelta
4import requests
5
6class PostmortemDataCollector:
7 def __init__(self, prometheus_url, grafana_url):
8 self.prometheus_url = prometheus_url
9 self.grafana_url = grafana_url
10
11 def collect_incident_metrics(self, start_time, end_time):
12 """Сбор метрик за период инцидента"""
13 metrics = {}
14
15 # Запрос метрик из Prometheus
16 queries = {
17 'error_rate': 'rate(http_requests_total{status=~"5.."}[5m])',
18 'latency_p95': 'histogram_quantile(0.95, rate(http_request_duration_seconds_bucket[5m]))',
19 'cpu_usage': 'avg(cpu_usage_percent)',
20 'memory_usage': 'avg(memory_usage_percent)'
21 }
22
23 for metric_name, query in queries.items():
24 try:
25 response = requests.get(
26 f"{self.prometheus_url}/api/v1/query_range",
27 params={
28 'query': query,
29 'start': start_time.timestamp(),
30 'end': end_time.timestamp(),
31 'step': '1m'
32 }
33 )
34 metrics[metric_name] = response.json()
35 except Exception as e:
36 print(f"Error collecting {metric_name}: {e}")
37
38 return metrics
39
40 def generate_timeline(self, log_entries):
41 """Генерация временной линии из логов"""
42 timeline = []
43 for entry in log_entries:
44 timeline.append({
45 'timestamp': entry['timestamp'],
46 'event': entry['message'],
47 'source': entry.get('source', 'unknown')
48 })
49 return sorted(timeline, key=lambda x: x['timestamp'])
50
51 def create_postmortem_template(self, incident_data):
52 """Создание шаблона postmortem"""
53 template = {
54 'title': f"Postmortem: {incident_data['title']}",
55 'date': incident_data['date'],
56 'duration': incident_data['duration'],
57 'impact': incident_data['impact'],
58 'timeline': incident_data['timeline'],
59 'root_cause': '', # Заполняется вручную
60 'action_items': [], # Заполняется вручную
61 'lessons_learned': [] # Заполняется вручную
62 }
63 return template
64
65# Установка через pip
66pip install requests jinja2
67
68# Установка через poetry
69poetry add requests jinja2
FAQ
Зачем нужен постмортем?
Постмортем помогает команде учиться на ошибках, улучшать процессы и инфраструктуру, а также предотвращать повторение аналогичных инцидентов в будущем.
Кто должен участвовать в постмортеме?
Все участники реагирования на инцидент: инженеры, менеджеры, представители бизнеса. Важно включить разные точки зрения для полного понимания проблемы.