Implement frontend and backend observability alignment

Align frontend and backend error observability with correlation IDs and
structured telemetry for distributed tracing across systems.

Backend changes:
- Add CorrelationIdMiddleware to generate/extract correlation IDs
- Include correlation_id in all ErrorResponse objects
- Store correlation ID in structlog contextvars for automatic inclusion in logs
- Add correlation ID to response headers (X-Correlation-ID)

Frontend changes:
- API client automatically generates session-scoped UUID4 and includes
  X-Correlation-ID header in all requests
- Extract correlation ID from API error responses
- Update error handlers to use telemetry with correlation IDs
- Add telemetry logging to ErrorBoundary, PageErrorBoundary, SectionErrorBoundary
- Implement redaction utilities for privacy-safe logging of sensitive data

Documentation:
- Add observability guidelines to Web-Development.md
  * Correlation ID usage patterns
  * Privacy & security best practices
  * Telemetry event structure
  * Redaction utilities for sensitive data
- Add distributed tracing architecture section to Architecture.md
  * Correlation ID flow across frontend/backend
  * Example troubleshooting scenario
  * Implementation details for future enhancements

Testing:
- Add comprehensive tests for correlation middleware
- Update error boundary tests to verify telemetry integration
- Verify TypeScript and ESLint pass with no warnings

Fixes: Issue #40 - Frontend and backend observability are not aligned

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
2026-04-30 18:32:19 +02:00
parent 9a43123b3a
commit 3d1a6f5538
16 changed files with 916 additions and 54 deletions

View File

@@ -214,10 +214,14 @@ class ErrorResponse(BanGuiBaseModel):
The error code enables machine-readable branching, while detail provides
human-readable context. Metadata offers optional structured context.
The correlation_id field enables tracing this error back through logs on both
frontend and backend, enabling correlation across distributed systems.
Fields:
code: Machine-readable error code (e.g., "jail_not_found", "invalid_input").
detail: Human-readable error description for display to users.
metadata: Optional structured context (e.g., field names, constraint violations).
correlation_id: Unique ID for correlating this error with request logs.
Example:
```python
@@ -225,21 +229,24 @@ class ErrorResponse(BanGuiBaseModel):
{
"code": "jail_not_found",
"detail": "Jail 'sshd' not found",
"metadata": {"jail_name": "sshd"}
"metadata": {"jail_name": "sshd"},
"correlation_id": "550e8400-e29b-41d4-a716-446655440000"
}
# 400 Bad Request - Validation Error
{
"code": "invalid_input",
"detail": "Invalid IP address format",
"metadata": {"field": "ip", "value": "999.999.999.999"}
"metadata": {"field": "ip", "value": "999.999.999.999"},
"correlation_id": "550e8400-e29b-41d4-a716-446655440000"
}
# 409 Conflict
{
"code": "jail_already_active",
"detail": "Jail is already active: 'sshd'",
"metadata": {"jail_name": "sshd", "current_status": "active"}
"metadata": {"jail_name": "sshd", "current_status": "active"},
"correlation_id": "550e8400-e29b-41d4-a716-446655440000"
}
```
"""
@@ -250,3 +257,7 @@ class ErrorResponse(BanGuiBaseModel):
default_factory=dict,
description="Optional structured context for the error.",
)
correlation_id: str | None = Field(
default=None,
description="Unique ID for correlating this error with request logs on both frontend and backend.",
)