Перейти к основному контенту
Tech Path Finder
КурсыИнтервьюКод-ревьюБлог
Tech Path Finder

Персонализированный путеводитель в IT. Квизы, мок-интервью, код ревью и аналитика прогресса.

@potapov_me

Платформа

  • Курсы
  • Прогресс
  • Мок-интервью
  • Код ревью
  • Живое ревью с ИИ
  • Тренажёр переговоров
  • Закладки

Контент

  • Блог
  • Главная
  • Обратная связь

Компания

  • О проекте
  • Тарифы
  • Условия использования
  • Конфиденциальность
  • Согласие на обработку данных
  • Cookie
  • Реквизиты

Аккаунт

  • Войти
  • Зарегистрироваться
  • Профиль

© 2026 Tech Path Finder. Все права защищены.

·ИП Потапов К.С.·Политика конфиденциальности·
Сделано с ❤️ в России
  1. Мониторинг и Логирование
monitoring_logging

Мониторинг и Логирование

Logging config, Sentry, Prometheus, Grafana, health checks, alerts

Наблюдаемость: логи, метрики и трассы

Статус: принципы актуальны для Django 5.2/6.0. Sentry, OpenTelemetry, Prometheus exporters и JSON formatters — отдельные продукты; их API и совместимость проверяют по зафиксированным версиям.

Мониторинг отвечает на заранее известные вопросы: доступен ли сервис, соблюдается ли latency SLO, растёт ли очередь. Observability шире: по данным системы можно исследовать новый, заранее не предусмотренный сбой.

Классические сигналы дополняют друг друга:

СигналХорошо отвечает на вопрос
ЛогКакое дискретное событие произошло?
МетрикаКак меняется агрегированное число во времени?
TraceГде запрос провёл время по пути через компоненты?

Error tracker группирует исключения и связывает их с release; APM часто объединяет трассы и метрики. Это полезные продукты, но ошибка не становится отдельным «столпом» вместо trace.

#Сначала SLO и пользовательский путь

Сбор всех доступных данных создаёт дорогой шум. Начните с критичных операций:

  • пользователь может войти;
  • checkout завершается без дубля платежа;
  • API списка отвечает быстрее целевого p95/p99;
  • отчёт из очереди готов не позднее установленного срока.

Для каждой определите SLI: долю успешных событий, распределение длительности и допустимое окно. SLO превращает «кажется медленно» в проверяемую цель и помогает алертить по расходу error budget, а не по случайному всплеску CPU.

#Структурированные логи

Django использует стандартный logging. В container приложение обычно пишет один JSON event на строку в stdout/stderr, а платформа доставляет его в централизованное хранилище.

# settings.py LOGGING = { "version": 1, "disable_existing_loggers": False, "formatters": { "json": { "()": "pythonjsonlogger.json.JsonFormatter", "fmt": "%(asctime)s %(levelname)s %(name)s %(message)s", }, }, "handlers": { "console": { "class": "logging.StreamHandler", "formatter": "json", }, }, "root": { "handlers": ["console"], "level": "INFO", }, }

Конкретный import path formatter зависит от версии python-json-logger; он должен быть зафиксирован в lock. Managed platform может принимать структурированные events другим formatter/handler.

При одном root handler дочерние loggers обычно используют propagation. Если одновременно назначить им тот же handler и оставить propagate=True, событие появится дважды.

#Событие, а не литературная строка

import logging logger = logging.getLogger(__name__) def checkout(*, order, actor): logger.info( "checkout_started", extra={ "order_id": str(order.pk), "actor_id": str(actor.pk), "order_total_minor": order.total_minor, }, ) try: return charge_order(order=order, actor=actor) except PaymentUnavailable: logger.exception( "checkout_payment_unavailable", extra={"order_id": str(order.pk)}, ) raise

Стабильное имя события удобно группировать, а поля — фильтровать. Не превращайте всё в ERROR: ожидаемый отказ карты может быть бизнес-результатом/метрикой, а недоступность payment provider — технической ошибкой.

Логируйте исключение там, где оно обрабатывается или получает полезный контекст. Если каждый слой вызывает logger.exception() и снова поднимает ту же ошибку, один сбой создаёт пять почти одинаковых stack traces.

#Correlation ID и trace context

Один request проходит proxy, Django, broker и worker. Связать события помогают:

  • trace_id/span_id OpenTelemetry;
  • request/correlation ID;
  • business ID заказа/job, если он не является secret.

Proxy может передать request ID, но приложение должно валидировать формат и длину либо генерировать свой; иначе клиент создаст log injection/high-cardinality мусор. Контекст храните в contextvars, а не в глобальной переменной, чтобы concurrent async requests не смешались.

Передавайте стандартный trace context во внешние HTTP-запросы и сообщения broker через instrumentation. Не делайте correlation ID Prometheus label: число уникальных значений разрушит metric storage.

#Что нельзя логировать

Запрещённый минимум:

  • пароль, session ID, CSRF token, API key и Authorization;
  • полные card/bank details;
  • необработанный request.body login/payment/webhook;
  • secret DSN и database URL;
  • лишние персональные поля и содержимое приватных документов.

Redaction должна работать в Django, third-party SDK, proxy и log collector. send_default_pii=False одного SDK не очищает собственные сообщения приложения.

Определите retention, доступ и удаление по политике данных. Application log не заменяет audit log. Audit trail для изменения прав/денег требует отдельной целостности, ограниченного доступа и стабильной схемы.

SQL logger django.db.backends на DEBUG полезен локально и в краткой целевой диагностике. Постоянное полное SQL-логирование в production создаёт overhead, объём и риск записи параметров. Для трендов используйте database metrics/APM и sampling slow queries.

#Метрики без cardinality explosion

Для HTTP полезна модель RED:

  • rate запросов;
  • errors по ограниченному классу/status group;
  • duration histogram.

Для ресурсов — saturation: CPU, memory, file descriptors, database pool, worker concurrency, broker queue age.

Label должен иметь небольшое ограниченное множество значений:

Хорошо: method=GET, route=/api/posts/{id}, status_group=2xx Плохо: user_id=..., order_id=..., raw_path=/api/posts/928374

Используйте нормализованное имя route, а не URL с ID. Не добавляйте exception message как label. High cardinality увеличивает память и может сделать Prometheus непригодным именно во время инцидента.

Latency измеряют histogram и смотрят p50/p95/p99. Среднее не «врёт», но скрывает распределение и хвост. Выбирайте buckets вокруг SLO и учитывайте, что клиентская latency включает proxy/network, а server span — нет.

Endpoint /metrics содержит внутренние имена, версии и объёмы. Ограничьте его private network, service identity или proxy authentication; не открывайте интернету и не защищайте обычной пользовательской session.

#Distributed tracing

Trace состоит из spans: proxy, Django request, SQL, cache, внешний HTTP, broker publish и worker task. Он помогает увидеть, что из 900 мс запроса 700 мс ушло на один upstream, а не на template.

OpenTelemetry задаёт vendor-neutral API/protocol, но требует exporter/collector и инструментирования. Автоинструментация экономит старт, однако пользовательские spans всё равно нужны вокруг бизнес-операций.

Sampling контролирует стоимость. Head sampling принимает решение в начале и может пропустить редкую ошибку; tail sampling в collector способен сохранить медленные/error traces после завершения, но требует больше инфраструктуры. Не ставьте 100% на высокий traffic без расчёта.

Trace attributes подчиняются тем же правилам secrets/PII/cardinality. SQL statement и HTTP body требуют осторожной настройки.

#Error tracking

Типовая инициализация Sentry связывает событие с окружением и immutable release:

import os import sentry_sdk sentry_sdk.init( dsn=os.environ["SENTRY_DSN"], environment=os.environ["DEPLOY_ENV"], release=os.environ["RELEASE_SHA"], send_default_pii=False, traces_sample_rate=float(os.environ.get("SENTRY_TRACES_SAMPLE_RATE", "0")), )

У актуального SDK Django integration может включаться автоматически; явная настройка нужна при кастомизации. Sample rate — эксплуатационное решение, а не универсальные 0.1.

Перед включением проверьте server-side scrubbing, attachments, breadcrumbs, request data и local variables. release позволяет увидеть regression после deployment, но correlation не доказывает причинность без сравнения stack/changes.

Не отправляйте ожидаемую ошибку валидации как exception. Настройте grouping, ownership и alert rules, иначе tracker станет вторым шумным inbox.

#Health endpoints без побочных эффектов

from django.db import connection from django.http import JsonResponse from django.views.decorators.cache import never_cache @never_cache def liveness(request): return JsonResponse({"status": "ok"}) @never_cache def readiness(request): try: with connection.cursor() as cursor: cursor.execute("SELECT 1") cursor.fetchone() except Exception: return JsonResponse({"status": "unavailable"}, status=503) return JsonResponse({"status": "ready"})

Liveness отвечает только «process request loop работает». Если включить database, общий краткий сбой запустит restart storm всех replicas.

Readiness включает только зависимости, без которых replica нельзя пускать в traffic. Cache или recommendation API могут быть необязательными при корректном fallback — тогда их сбой не должен снимать весь web fleet с балансировки.

Проверка:

  • не записывает общий ключ health и не мутирует бизнес-данные;
  • имеет короткие infrastructure timeouts;
  • возвращает общий статус, а не текст exception/host credentials;
  • недоступна как дорогой публичный amplification endpoint;
  • не выполняет полную проверку каждой таблицы.

Startup probe отделяет медленный запуск от liveness. Readiness после SIGTERM должна стать false до завершения grace period.

#Алерты, которые приводят к действию

Page нужен, когда требуется немедленное действие человека. Ticket/notification — когда проблему можно исправить в рабочее время.

Хороший alert содержит:

  • пользовательский симптом или быстрый расход SLO error budget;
  • достаточное окно, чтобы отсеять единичный шум;
  • owner и severity;
  • ссылки на dashboard, traces/log query и runbook;
  • понятное условие восстановления.

Примеры симптомов: доля неуспешных checkout, p95 выше SLO, возраст старейшей critical task, несколько недоступных replicas. CPU 90% может быть полезным диагностическим сигналом, но не всегда требует разбудить человека, если SLO соблюдается.

На низком traffic одна ошибка даст огромный процент, поэтому сочетайте ratio с минимальным числом событий. Multi-window burn-rate alert быстрее ловит сильную аварию и не шумит на короткой единичной ошибке.

Периодически проводите game day: намеренно выключите dependency в staging и проверьте, что сигнал дошёл, runbook верен, а alert действительно закрылся после восстановления.

#Что наблюдать в Django-системе

HTTP:

  • rate/status/duration по нормализованному route;
  • request/response size, timeout и cancelled requests;
  • active requests и saturation workers.

Database/cache:

  • query duration и slow query samples;
  • pool in-use/wait/timeout;
  • transaction/deadlock errors;
  • cache hit ratio, latency, eviction и fallback load.

Background jobs:

  • queue age, throughput, runtime и retries;
  • worker heartbeat/concurrency;
  • terminal failures и business completion latency.

Business:

  • успешные checkout/import/invite;
  • дубли/idempotency conflicts;
  • время прохождения ключевого workflow end-to-end.

Не ограничивайтесь host CPU: пользовательский путь часто ломается при здоровых машинах.

#Тесты и эксплуатация telemetry

Проверяйте, что:

  1. exception получает release, trace ID и безопасный business context;
  2. secret filtering удаляет реальные формы credentials;
  3. metrics route нормализует ID и не создаёт unbounded labels;
  4. readiness возвращает 503 при критической зависимости, liveness остаётся 200;
  5. trace context продолжается в worker;
  6. alert firing/recovery доставляется владельцу;
  7. collector outage не останавливает приложение из-за синхронной отправки telemetry.

Логирование само способно создать инцидент: заполнить диск, заблокировать stdout pipe или исчерпать бюджет SaaS. Ограничивайте объём, применяйте sampling для шумных событий и контролируйте dropped telemetry.

#Legacy и исправления

  • Три сигнала сформулированы как logs, metrics и traces; error tracker больше не подменяет trace.
  • Health check больше не пишет общий ключ в cache и не возвращает пользователю str(exception).
  • SQL DEBUG logging не рекомендуется как постоянный production monitoring.
  • User/order/request ID допустимы в logs/traces по политике данных, но не как unbounded metric labels.
  • «Алертить только на симптомы» уточнено: resource alerts полезны, если они предсказывают нарушение SLO и имеют действие.

#Документация

  • Django: logging
  • OpenTelemetry documentation
  • Prometheus: instrumentation practices
  • Google SRE: monitoring distributed systems

Далее: Базы Данных: Продвинутые темы