Skip to content

Latest commit

 

History

History
133 lines (96 loc) · 4.45 KB

File metadata and controls

133 lines (96 loc) · 4.45 KB

Safe Observability Integrations

DRF API Logger can feed metrics, traces, and error context through signal listeners. By default, the package does not start exporters, expose a metrics endpoint, or send data to external systems by itself. Applications own their Prometheus, OpenTelemetry, Sentry, Loki, Elasticsearch, or hosted monitoring setup.

For teams that want package-owned logger health and pipeline metrics, DRF API Logger also includes an optional first-party Prometheus recorder and internal metrics endpoint. See :doc:`metrics` for that opt-in path.

Prerequisites

Enable signal logging and request correlation:

DRF_API_LOGGER_SIGNAL = True
DRF_API_LOGGER_ENABLE_CORRELATION = True
DRF_API_LOGGER_ENABLE_LOGGING_CONTEXT = True
DRF_API_LOGGER_CORRELATION_REQUEST_ID_HEADERS = ["X-Request-ID", "X-Correlation-ID"]
DRF_API_LOGGER_CORRELATION_TRACE_ID_HEADERS = ["traceparent", "X-Trace-ID"]

The signal payload can include:

  • correlation: high-cardinality request IDs, trace IDs, and allowlisted opaque context.
  • low_cardinality: route, URL name, app name, namespace, and status class values safe for metrics labels.

Prometheus Metrics

Install and configure Prometheus in the application, then use DRF API Logger's helper from a signal listener:

from prometheus_client import Counter, Histogram

from drf_api_logger import API_LOGGER_SIGNAL
from drf_api_logger.observability import record_prometheus_metrics

API_REQUESTS = Counter(
    "drf_api_logger_requests_total",
    "DRF API Logger observed requests",
    ["route", "url_name", "app_name", "namespace", "status_class", "method"],
)
API_DURATION = Histogram(
    "drf_api_logger_request_duration_seconds",
    "DRF API Logger observed request duration",
    ["route", "url_name", "app_name", "namespace", "status_class", "method"],
    buckets=[0.01, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10],
)

def export_api_metrics(**kwargs):
    record_prometheus_metrics(kwargs, API_REQUESTS, API_DURATION)

API_LOGGER_SIGNAL.listen += export_api_metrics

The helper only uses low-cardinality labels. It does not place request_id, trace_id, actor_id, tenant_id, api_consumer_id, or client_id in Prometheus labels. Treat those IDs as debugging context, not metrics labels.

OpenTelemetry Span Attributes

When the application already has OpenTelemetry configured, annotate the current span from a signal listener:

from opentelemetry import trace

from drf_api_logger import API_LOGGER_SIGNAL
from drf_api_logger.observability import annotate_opentelemetry_span

def annotate_current_span(**kwargs):
    span = trace.get_current_span()
    annotate_opentelemetry_span(span, kwargs)

API_LOGGER_SIGNAL.listen += annotate_current_span

By default, high-cardinality request and trace IDs are not added as span attributes. If the application's trace policy allows those values, pass include_high_cardinality=True explicitly:

annotate_opentelemetry_span(
    span,
    kwargs,
    include_high_cardinality=True,
)

Sentry Error Context

For Sentry SDK 2.x, enrich the current scope with safe tags and context:

import sentry_sdk

from drf_api_logger import API_LOGGER_SIGNAL
from drf_api_logger.observability import configure_sentry_scope

def enrich_sentry_scope(**kwargs):
    scope = sentry_sdk.Scope.get_current_scope()
    configure_sentry_scope(scope, kwargs)

API_LOGGER_SIGNAL.listen += enrich_sentry_scope

Sentry tags receive only low-cardinality values. Sentry context can include request IDs, trace IDs, and opaque IDs for debugging, but it never includes request headers, request body, or response body.

Safety Rules

  • Keep high-cardinality values out of metrics labels.
  • Keep payloads, headers, cookies, authorization values, and direct identities out of observability exports.
  • Keep exporter ownership in the application, not in DRF API Logger.
  • If using the first-party metrics endpoint, expose it only on an internal protected path.
  • Prefer route patterns and URL names over raw URLs.
  • Use DRF_API_LOGGER_SKIP_URL_NAME or DRF_API_LOGGER_SKIP_NAMESPACE to avoid recording health checks, metrics endpoints, admin paths, and noisy internal endpoints.