Подготовить skeleton лабораторной 6 по мессенджеру

This commit is contained in:
Mikhail Verkovykh
2026-09-10 18:01:36 +03:00
commit 470d9d6f1e
38 changed files with 5013 additions and 0 deletions
+105
View File
@@ -0,0 +1,105 @@
# Лабораторная 6. Наблюдаемость: OpenTelemetry и Grafana
Научиться находить причину деградации через метрики, логи и трассы всей системы, включая фоновую обработку.
Это **skeleton**, а не готовый сервер. Здесь есть задание, контракт и публичные проверки. Реализацию приложения, Dockerfile и требуемую инфраструктуру пишет студент. Язык и framework свободные; UI не обязателен.
[Карта курса](COURSE.md) · [Процесс fork/PR](CONTRIBUTING.md) · [OpenAPI](contracts/openapi.json) · [Семантика API](contracts/README.md) · [Проверки](tests/README.md) · [Отчёт](REPORT.md) · [Примеры JSON](contracts/examples.json) · [Памятка преподавателю](MAINTAINERS.md)
## Откуда начинаем
Перенесите минимум lab5. Бизнес-API не меняется. Должны оставаться API-реплики, БД, S3, broker и worker.
**Архитектура:** API/worker → OTLP → OTel Collector → хранилища metrics/logs/traces → Grafana; queue context связывает API и worker.
## Что сделать
1. Выберите хранилища: например Prometheus для метрик, Loki для логов, Tempo для трасс. Разрешена другая совместимая комбинация с Grafana; Grafana сама не хранит все три сигнала.
2. Добавьте SDK-инструментацию API и worker и отдельный Collector в общий Compose/Swarm; настройте receivers/processors/exporters и хранение данных.
3. Реализуйте набор сигналов contracts/observability.md и импортируемые dashboard/datasources. Не используйте user_id/chat_id/message_id как labels метрик.
4. Проверьте связь запроса, структурного лога и обработки задания. Секреты, тела сообщений и изображения не должны попадать в telemetry.
5. Создайте нагрузку, внедрите два ограниченных отказа и найдите их причину только с помощью сохранённых наблюдений; приложите доказательства.
## Оценка «3»: работающий минимум
- Весь минимум lab5 работает. Collector, хранилища трёх сигналов и Grafana включены в общий воспроизводимый стенд; конфиги и provisioning лежат в Git, persistent volumes сохраняют нужную историю.
- API и worker отдают OTLP в Collector. В Grafana видны: RPS/errors/duration API, успешные/ошибочные jobs и duration worker; доступны структурные логи и реальные трассы API и worker.
- Есть импортируемый dashboard, а не только screenshot. Сохраняются низкокардинальные атрибуты и идентификаторы trace/span в логах; содержимое сообщений, пароли/токены не экспортируются.
- На контролируемом запросе можно найти trace и связанный лог; на job — worker trace и лог. make test проходит при включённой телеметрии. Объяснено назначение каждого хранилища.
## Оценка «4»: уровень стажёра/джуна
Весь уровень 3 **и все** пункты ниже:
- W3C trace context переносится API → broker → worker; видны producer/consumer spans с корректной связью parent или link. По одному upload найдена цепочка до S3/DB результата, включая retry.
- Dashboard показывает p50/p95/p99, долю ошибок, queue depth/возраст старейшей job, DB pool и saturation worker. Приведены запросы и единицы измерения; percentile вычисляется из histogram, не средних.
- Задан проверяемый SLI/SLO и окно; сохранены alert rules минимум для высокого error rate и растущего queue lag. Alerts проверены искусственным отказом; доставка наружу не нужна, достаточно локального состояния firing/resolved.
- Collector имеет memory limiter/batch и ограниченную буферизацию/поведение при недоступном backend. Остановка telemetry-хранилища не ломает сообщения и не вызывает бесконечный рост RAM. Отчёт содержит разбор двух инцидентов и шаги диагностики.
## Оценка «5»: исследование и доказанный результат
Весь уровень 4 **и один законченный трек на выбор**. Приведите гипотезу, повторяемую методику, результаты и ограничения.
**Трек 1. Цена наблюдаемости.** Сравните telemetry off/on и ≥2 sampling/aggregation настройки при одинаковой нагрузке: latency, CPU/RAM, объём ingest, потери spans. Объясните, какие ошибки и редкие медленные запросы теряются; предложите и проверьте сбалансированную конфигурацию.
**Трек 2. SLO и обнаружение инцидентов.** Обоснуйте SLO для API и времени до ready, реализуйте burn-rate alerts с несколькими окнами, воспроизведите краткий всплеск и длительную деградацию. Измерьте время обнаружения/восстановления, ложные срабатывания и покажите runbook, по которому другой студент находит причину.
## Как начать и проверить
```sh
# Работает прямо в skeleton, Python 3.9+; приложение не запускается:
make check
# После реализации запустите свой сервер/стенд по REPORT.md.
# По умолчанию тест использует http://localhost:8080.
make test
```
`.env.example`, `compose.example.yaml` и `contracts/infrastructure.json` описывают настройки и роли компонентов. **compose.example.yaml — список ролей с пустым services, не запускаемый стенд.** Реализуйте свой `compose.yaml`/`stack.yaml`, закрепите версии образов, заполните локальный `.env` и опишите bootstrap/миграции. Все зависимости поднимаются из этого репозитория; ссылка «у меня БД уже установлена» не заменяет воспроизводимость.
```sh
# Compose-вариант после реализации:
docker compose --env-file .env config --quiet
docker compose --env-file .env up -d --build
# Дождитесь /health/ready; затем make test.
# Для Swarm укажите эквивалентные build/push/deploy-команды в REPORT.md.
```
Примеры запросов доступны в `examples/requests.http`, примеры JSON — в `contracts/examples.json`. Для полной проверки схемы (по желанию локально; CI делает её автоматически):
```sh
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements-dev.txt
make validate PYTHON=.venv/bin/python
```
Smoke не выставляет оценку автоматически. Проверку сохранности/отказов запускайте явно по [tests/README.md](tests/README.md), остальные доказательства приведите в отчёте.
## Сценарий защиты
1. С нуля поднять стенд, импортировать provisioning без ручного набора dashboard, запустить smoke и нагрузку.
2. Показать свежие метрики, одну трассу и соответствующий структурный лог API и worker; проверить, что это данные своего приложения.
3. Для 4: пройти от upload до worker в одном trace/связанных traces, остановить worker или ограничить DB, увидеть firing и затем resolved.
4. Остановить telemetry backend, проверить сохранение работы API и ограниченное поведение exporter. Для 5: повторить эксперимент.
## Что должно быть в PR
Collector configuration, конфиги backend, Grafana provisioning/dashboards, alert rules по уровню, схема сигналов и отчёт инцидентов.
Заполните `REPORT.md` и [шаблон PR](.github/pull_request_template.md), укажите целевую оценку/трек. Не меняйте обязательный контракт и публичные tests ради зелёного результата. Сохраняйте возможности предыдущих лабораторных в пределах [объявленных переходов](COURSE.md).
## Вопросы на защите
- Чем лог, метрика и trace отвечают на разные вопросы об одном инциденте?
- Почему chat_id в labels может исчерпать хранилище?
- Как очередь переносит причинную связь между процессами?
- Почему среднее latency не заменяет p99 и почему нельзя усреднять p99 реплик?
## Первичные материалы
- [OTel Collector configuration](https://opentelemetry.io/docs/collector/configuration/)
- [OTel propagation](https://opentelemetry.io/docs/concepts/context-propagation/)
- [W3C Trace Context](https://www.w3.org/TR/trace-context/)
- [Prometheus histograms](https://prometheus.io/docs/practices/histograms/)
- [Grafana provisioning](https://grafana.com/docs/grafana/latest/administration/provisioning/)