Skip to content

Add opt-in application observability#19

Merged
michaelmeaney merged 3 commits into
mainfrom
feat/observability-upstream-main
Jul 22, 2026
Merged

Add opt-in application observability#19
michaelmeaney merged 3 commits into
mainfrom
feat/observability-upstream-main

Conversation

@michaelmeaney

Copy link
Copy Markdown

Summary

  • Add opt-in request/response logging and low-cardinality metrics.
  • Redact bodies, query strings, authorization material, cookies, tokens, API keys, and arbitrary headers.
  • Add request correlation IDs and safe-header allowlisting.
  • Keep deployment-specific exporters outside this repository.

Validation

  • Observability tests: 4 passed.
  • Changed observability files pass Ruff checks.

This PR is based on the synchronized upstream-main default branch.

michaelmeaney and others added 2 commits July 22, 2026 13:33
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces an opt-in, application-scoped observability layer for Guardette, centered on safe structured stdout events (request/response metadata + low-cardinality “metric” events) and a FastAPI middleware for request correlation IDs, while keeping exporter/deployment concerns out of this repo.

Changes:

  • Added guardette.observability package (env-driven config, safe header allowlist + bounding, event/metric emitters, and FastAPI middleware with request IDs).
  • Integrated observability into the proxy FastAPI wiring and tightened JSON logging to a safe allowlist of extra fields (plus dedicated observability_event payloads).
  • Added documentation and examples for new environment flags and included focused observability tests.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
tests/test_observability.py Adds tests for disabled-by-default behavior, env flag parsing, safe request/response logging, request-id correlation, and header sanitization.
src/guardette/proxy.py Removes ad-hoc request lifecycle logging, wires observability into FastAPI setup, and records auth/upstream metrics.
src/guardette/observability/middleware.py Implements request-boundary middleware for request IDs, safe event emission, and per-request metrics recording.
src/guardette/observability/headers.py Adds strict safe-header allowlist and value bounding for logged headers.
src/guardette/observability/events.py Defines structured event logging and low-cardinality metric-event emission helpers.
src/guardette/observability/config.py Adds explicit boolean env parsing and derived “active” flags for observability components.
src/guardette/observability/init.py Provides configure_observability() entrypoint to install middleware and initialize logging/recorders once per app.
src/guardette/logging.py Restricts serialized extra fields and supports structured observability events.
src/guardette/constants.py Adds X-Guardette-Request-Id header constant for correlation.
README.md Documents new observability env vars and the high-level safety/behavior contract.
.env.example Adds example observability environment variables.
.client/adr/observability-options.md Adds ADR documenting observability goals, constraints, and chosen approach.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/guardette/proxy.py Outdated
Comment on lines +144 to +148
logger.info(
"Guardette policy loaded",
extra={
"source_count": len(self.policy.sources),
"rule_count": sum(len(source.rules) for source in self.policy.sources),
Comment thread src/guardette/proxy.py
Comment on lines +299 to +303
def _record_auth_failure(request: Request) -> None:
observability = getattr(request.app.state, "observability", None)
if observability is not None:
observability.metrics.record_auth_failure("client")

Comment thread src/guardette/proxy.py
Comment on lines +305 to +308
def _record_upstream(request: Request, outcome: str, status_code: int | None) -> None:
observability = getattr(request.app.state, "observability", None)
if observability is not None:
observability.metrics.record_upstream(outcome, status_code)
@michaelmeaney
michaelmeaney changed the base branch from upstream-main to main July 22, 2026 12:43
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 22, 2026 13:09
@michaelmeaney
michaelmeaney added this pull request to the merge queue Jul 22, 2026
Merged via the queue into main with commit 59cdd2f Jul 22, 2026
2 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants