Skip to content

Commit 73db013

Browse files
Merge pull request #128 from vishalanandl177/SCRUM-11-P0-Implement-policy-and-logging-gate
feat: add logging policy controls
2 parents 2847d50 + 1286b50 commit 73db013

18 files changed

Lines changed: 1142 additions & 23 deletions

README.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ DRF API Logger automatically captures and stores comprehensive API information:
6767
- **🔬 API Profiling**: Per-request latency breakdown with auto-diagnosis (SQL, middleware, business logic)
6868
- **Request Correlation**: Opt-in request IDs, traceparent parsing, route metadata, logging context, and signal metadata without new database columns
6969
- **Safe Observability Integrations**: Optional helpers for Prometheus labels, OpenTelemetry span attributes, and Sentry context without hard dependencies
70+
- **Policy Controls**: Optional endpoint-specific rules for logging, masking, payload stripping, and signal/export gating
7071

7172
### 🌐 Community & Support
7273

@@ -229,6 +230,7 @@ API_LOGGER_SIGNAL.listen -= log_to_file
229230

230231
- [Copy-paste setup recipes](docs/quickstart.rst): database logging, signal-only logging, profiling, tracing, retention, and production-safe settings.
231232
- [Safe observability integrations](docs/observability_integrations.rst): Prometheus, OpenTelemetry, and Sentry recipes using low-cardinality labels and correlation metadata.
233+
- [Policy controls](docs/policy_controls.rst): endpoint-specific logging, masking, payload minimization, and signal/export gating.
232234
- [AI assistant guidance](docs/ai_readiness.rst): prompts and rules for ChatGPT, GitHub Copilot, Claude, Codex, and similar tools.
233235
- [Comparison and migration guide](docs/comparison_and_migration.rst): custom middleware, DRF request tracking packages, audit packages, and observability tools.
234236
- [Tutorials and community snippets](docs/tutorials.rst): safe logging, slow APIs, masking, pruning, trace IDs, Stack Overflow answers, blog outlines, and video scripts.
@@ -505,6 +507,26 @@ Only `actor_id`, `tenant_id`, `api_consumer_id`, and `client_id` are accepted
505507
from the callback. Use opaque IDs, not names, emails, tokens, or other
506508
identifying values.
507509

510+
### Policy Controls
511+
512+
Use endpoint-specific rules when an API needs different logging, masking,
513+
payload minimization, or signal/export behavior:
514+
515+
```python
516+
DRF_API_LOGGER_POLICY = {
517+
"rules": [
518+
{"url_name": "health_check", "log": False},
519+
{
520+
"route": "api/payments/",
521+
"request_body": False,
522+
"response_body": False,
523+
"mask_keys": ["card_number", "payment_token"],
524+
"signal": False,
525+
},
526+
],
527+
}
528+
```
529+
508530
### Safe Observability Integrations
509531

510532
Use DRF API Logger signal payloads to feed metrics, traces, and error context

TESTING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ make check-package
6464
- `tests/test_models.py`: model fields, admin display, filters, and CSV export.
6565
- `tests/test_signals.py`: event listeners, background queue behavior, app startup, and worker stats.
6666
- `tests/test_observability.py`: dependency-free Prometheus, OpenTelemetry, and Sentry helper behavior.
67+
- `tests/test_policy.py`: logging policy decisions, endpoint rules, callable overrides, extra mask keys, and safe failure behavior.
6768
- `tests/test_profiling.py`: profiling settings, SQL tracking, admin diagnosis, and nullable profiling fields.
6869
- `tests/test_backward_compat.py`: default behavior when profiling is disabled.
6970
- `tests/test_integration.py`: end-to-end middleware, signal, database, and workflow coverage.

docs/compliance.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,21 @@ When exporting DRF API Logger signal data to observability systems:
9393
- Use Sentry context for debugging metadata, not payload storage.
9494
- Keep external exporter credentials outside DRF API Logger settings.
9595

96+
Policy Controls
97+
---------------
98+
99+
Policy controls support data minimization by endpoint. Use them to skip
100+
logging, strip headers or bodies, add endpoint-specific mask keys, and prevent
101+
signal exports for sensitive routes.
102+
103+
For compliance-sensitive deployments:
104+
105+
- Configure ``log: False`` for endpoints that should not produce logs.
106+
- Configure ``headers: False`` and body stripping for regulated payloads.
107+
- Use ``mask_keys`` for tenant-specific or domain-specific identifiers.
108+
- Keep policy reasons generic and free of personal data.
109+
- Treat policy callables as request-path code and keep them deterministic.
110+
96111
Storage Controls
97112
----------------
98113

docs/developer_testing.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ Add or update tests for every behavior change. Cover the touched surface:
8686
- Observability helper behavior for Prometheus labels, OpenTelemetry span
8787
attributes, Sentry context, optional dependency safety, and high-cardinality
8888
label prevention.
89+
- Policy gate behavior for full log drops, metadata-only logging, extra mask
90+
keys, signal/export gating, safe failures, and default backward compatibility.
8991
- Background queue flushing, stats, shutdown, and database alias handling.
9092
- Admin display, filters, CSV export, and profiling diagnosis.
9193
- Management commands such as ``prune_api_logs``.

docs/index.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ profile SQL-heavy endpoints when enabled.
2424

2525
quickstart
2626
observability_integrations
27+
policy_controls
2728
ai_readiness
2829
comparison_and_migration
2930
tutorials
@@ -43,6 +44,8 @@ Key Features
4344
- Per-request API profiling with auto-diagnosis of bottlenecks
4445
- Request correlation through request attributes, logging context, and signals
4546
- Optional Prometheus, OpenTelemetry, and Sentry helper functions with safe defaults
47+
- Optional endpoint-specific policy controls for logging, masking, payload
48+
stripping, and signal/export gating
4649

4750

4851
Supported Versions

docs/operations.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,24 @@ Recommended operating pattern:
146146
- Skip health checks and metrics endpoints with ``DRF_API_LOGGER_SKIP_URL_NAME``
147147
or ``DRF_API_LOGGER_SKIP_NAMESPACE``.
148148

149+
Policy Control Operations
150+
-------------------------
151+
152+
Use ``DRF_API_LOGGER_POLICY`` to keep noisy, sensitive, or internal endpoints
153+
out of database logs or signal exports. Keep policy matching deterministic and
154+
bounded because policy evaluation runs on the request path.
155+
156+
Recommended operating pattern:
157+
158+
- Use ``log: False`` for health checks, metrics endpoints, and endpoints that
159+
should never produce API logger rows or signal exports.
160+
- Use ``headers: False``, ``request_body: False``, and ``response_body: False``
161+
for sensitive routes that still need timing and status metadata.
162+
- Use ``mask_keys`` for endpoint-specific identifiers that are not globally
163+
sensitive in the rest of the application.
164+
- Use ``signal: False`` when signal listeners export externally and a request
165+
should remain local to database logging.
166+
149167
Database Indexes
150168
----------------
151169

docs/policy_controls.rst

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
Policy Controls
2+
===============
3+
4+
Use policy controls when different endpoints need different logging, masking,
5+
persistence, or signal/export behavior. Policies are optional. When no policy
6+
is configured, DRF API Logger keeps its current defaults.
7+
8+
Endpoint Skip
9+
-------------
10+
11+
Skip noisy or sensitive endpoints before a log entry or signal export is
12+
produced:
13+
14+
.. code-block:: python
15+
16+
DRF_API_LOGGER_POLICY = {
17+
"rules": [
18+
{
19+
"url_name": "health_check",
20+
"log": False,
21+
"reason": "skip_health_check",
22+
},
23+
],
24+
}
25+
26+
When ``log`` is ``False``, the middleware still returns the normal API response
27+
but does not queue a database row and does not emit ``API_LOGGER_SIGNAL`` for
28+
that request.
29+
30+
Payload Minimization
31+
--------------------
32+
33+
Keep request metadata while removing headers and bodies for sensitive routes:
34+
35+
.. code-block:: python
36+
37+
DRF_API_LOGGER_POLICY = {
38+
"rules": [
39+
{
40+
"route": "api/payments/",
41+
"headers": False,
42+
"request_body": False,
43+
"response_body": False,
44+
"reason": "payment_metadata_only",
45+
},
46+
],
47+
}
48+
49+
This preserves method, URL, status code, client IP, execution time, and
50+
timestamp while storing empty header/body/response fields.
51+
52+
Endpoint-Specific Masking
53+
-------------------------
54+
55+
Add extra mask keys for one endpoint without changing global settings:
56+
57+
.. code-block:: python
58+
59+
DRF_API_LOGGER_POLICY = {
60+
"rules": [
61+
{
62+
"url_name": "payment_create",
63+
"mask_keys": ["card_number", "payment_token"],
64+
"reason": "payment_masking",
65+
},
66+
],
67+
}
68+
69+
Policy mask keys are applied before database persistence and before signal
70+
emission. They do not mutate ``DRF_API_LOGGER_EXCLUDE_KEYS``.
71+
72+
Signal And Export Gate
73+
----------------------
74+
75+
Signal listeners are commonly used as export hooks. Disable signal emission for
76+
events that should remain local to database logging:
77+
78+
.. code-block:: python
79+
80+
DRF_API_LOGGER_POLICY = {
81+
"rules": [
82+
{
83+
"namespace": "internal",
84+
"methods": ["POST"],
85+
"status_classes": ["2xx"],
86+
"signal": False,
87+
"reason": "do_not_export_internal_success",
88+
},
89+
],
90+
}
91+
92+
When ``signal`` is ``False``, ``API_LOGGER_SIGNAL.listen`` is not called for the
93+
matching request.
94+
95+
Callable Policy
96+
---------------
97+
98+
Use a callable when declarative rules are not enough:
99+
100+
.. code-block:: python
101+
102+
DRF_API_LOGGER_POLICY_FUNC = "myapp.logging.api_logger_policy"
103+
104+
def api_logger_policy(context):
105+
if context["url_name"] == "health_check":
106+
return {"log": False, "reason": "skip_health_check"}
107+
if context["status_class"] == "5xx":
108+
return {"signal": True, "reason": "export_errors"}
109+
return {"log": True}
110+
111+
The context includes ``path``, ``method``, ``status_code``, ``status_class``,
112+
``route``, ``url_name``, ``namespace``, ``app_name``, ``view_name``,
113+
``correlation``, and ``low_cardinality``.
114+
115+
Safe Failure Behavior
116+
---------------------
117+
118+
If policy evaluation raises an exception, DRF API Logger fails closed for
119+
payloads:
120+
121+
- Headers, request body, and response body are stripped.
122+
- The stored ``api`` value uses the request path instead of the full URL with
123+
query string.
124+
- Signal emission is disabled for that event.
125+
- Database logging may continue with safe metadata when database logging is
126+
enabled.
127+
- Exception text is not stored or emitted.
128+
129+
Safety Rules
130+
------------
131+
132+
- Do not put secrets, credentials, cookies, tokens, direct user identities, or
133+
regulated identifiers in policy reasons.
134+
- Prefer ``url_name``, ``route``, ``namespace``, ``method``, ``status_code``,
135+
and ``status_class`` for deterministic matching.
136+
- Use ``mask_keys`` for endpoint-specific identifiers that should not be stored
137+
or exported.
138+
- Use ``signal: False`` when signal listeners export to external systems and a
139+
request should remain local.
140+
- Keep policy callables bounded; they run on the request path.

docs/quickstart.rst

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,25 @@ Prometheus labels are limited to route, URL name, app name, namespace, status
196196
class, and method. Request IDs and trace IDs are available for logs, traces, and
197197
Sentry context, not metrics labels.
198198

199+
Policy Controls
200+
---------------
201+
202+
Use policy controls for endpoint-specific logging decisions:
203+
204+
.. code-block:: python
205+
206+
DRF_API_LOGGER_POLICY = {
207+
"rules": [
208+
{"url_name": "health_check", "log": False},
209+
{
210+
"route": "api/payments/",
211+
"request_body": False,
212+
"response_body": False,
213+
"mask_keys": ["card_number", "payment_token"],
214+
},
215+
],
216+
}
217+
199218
Retention and Pruning
200219
---------------------
201220

0 commit comments

Comments
 (0)