-
Notifications
You must be signed in to change notification settings - Fork 75
safe observability integrations #127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
vishalanandl177
merged 2 commits into
main
from
SCRUM-10-P0-Add-safe-observability-integrations
Jul 4, 2026
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| Safe Observability Integrations | ||
| =============================== | ||
|
|
||
| DRF API Logger can feed metrics, traces, and error context through signal | ||
| listeners. 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. | ||
|
|
||
| Prerequisites | ||
| ------------- | ||
|
|
||
| Enable signal logging and request correlation: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| 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: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| 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: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| 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: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| 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: | ||
|
|
||
| .. code-block:: python | ||
|
|
||
| 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. | ||
| - 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. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When users wire the Sentry helper exactly as this recipe shows, it will miss the errors it is supposed to annotate:
APILoggerMiddlewareemitsAPI_LOGGER_SIGNALonly afterself.get_response(request)returns, and an exception raised by the view either has already been captured by Sentry or prevents the signal from being emitted at all. In those error paths the tags/context fromconfigure_sentry_scopeare absent, so the recipe should use Sentry's request scope,before_send, or middleware before the view is invoked instead of the logger signal.Useful? React with 👍 / 👎.