Лабораторная 6. Наблюдаемость: OpenTelemetry и Grafana

Научиться находить причину деградации через метрики, логи и трассы всей системы, включая фоновую обработку.

Это skeleton, а не готовый сервер. Здесь есть задание, контракт и публичные проверки. Реализацию приложения, Dockerfile и требуемую инфраструктуру пишет студент. Язык и framework свободные; UI не обязателен.

Карта курса · Процесс fork/PR · OpenAPI · Семантика API · Проверки · Отчёт · Примеры JSON · Памятка преподавателю

Откуда начинаем

Перенесите минимум 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, по которому другой студент находит причину.

Как начать и проверить

# Работает прямо в 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/миграции. Все зависимости поднимаются из этого репозитория; ссылка «у меня БД уже установлена» не заменяет воспроизводимость.

# 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 делает её автоматически):

python3 -m venv .venv
.venv/bin/python -m pip install -r requirements-dev.txt
make validate PYTHON=.venv/bin/python

Smoke не выставляет оценку автоматически. Проверку сохранности/отказов запускайте явно по 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, укажите целевую оценку/трек. Не меняйте обязательный контракт и публичные tests ради зелёного результата. Сохраняйте возможности предыдущих лабораторных в пределах объявленных переходов.

Вопросы на защите

  • Чем лог, метрика и trace отвечают на разные вопросы об одном инциденте?
  • Почему chat_id в labels может исчерпать хранилище?
  • Как очередь переносит причинную связь между процессами?
  • Почему среднее latency не заменяет p99 и почему нельзя усреднять p99 реплик?

Первичные материалы

S
Description
No description provided
Readme
187 KiB
Languages
Python 93.8%
Makefile 3.3%
Shell 2.9%