Documents the exact hook point chosen for each of the 3 dead observability primitives (access log, request-duration histogram, tracer provider) and the 11 named business-health metrics, verified against the real current code rather than assumed — including a pre-existing SLA-run status data quality gap surfaced along the way (documented, not fixed here). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
4.0 KiB
4.0 KiB
Quickstart: Full Observability
Manual verification steps for each user story, against a running instance backed by real Postgres/Redis (the throwaway Docker containers already used throughout this project's test suite work equally well for a manual run).
Scenario 1 — Per-request access log (User Story 1)
- Start the API. Send any request (e.g.
GET /health). - Expected: exactly one log line appears with
event: "http_request_completed", the request's method, route, status code, and arequestId. - Send a request to a route that triggers additional internal logging (e.g. a login attempt).
- Expected: every log line produced while handling that request — the access-log line and
any domain log lines — carries the same
requestId/correlationId. - Send a request to a route that doesn't exist.
- Expected: a 404 access-log line is still emitted (not silently dropped).
Scenario 2 — Live request-health metrics (User Story 2)
- Send a mix of successful and failing requests (e.g. a valid login, then three wrong-password logins).
- Scrape
GET /metrics. - Expected:
supporthub_http_request_duration_seconds_counthas observations labeledroute="/auth/login"with bothstatus_code="200"andstatus_code="401"present, letting an operator compute the error rate for that route from these two series alone.
Scenario 3 — Cross-module trace (User Story 3)
- With the API running in a mode where tracing exports to the console (no
OTEL_EXPORTER_OTLP_ENDPOINTconfigured), drive a request that escalates a ticket to a human and triggers automatic orchestration/assignment. - Expected: console output shows a
ticket.create-or-ai.escalationroot span and anorchestration.assignmentchild span sharing the same trace ID, with the child's start time at or after the parent's. - Stop the (nonexistent) collector / leave
OTEL_EXPORTER_OTLP_ENDPOINTpointed at an unreachable address. - Expected: the API still starts and serves requests normally; only a logged export-failure warning appears, nothing surfaces to any HTTP response.
Scenario 4 — Business-health metrics (User Story 4)
For each metric, scrape /metrics, note the current value, drive the real event, scrape again,
and confirm the expected series moved by exactly one (or by the expected duration observation):
- Complete an AI session without escalating →
supporthub_ai_session_outcomes_total{outcome="resolved"}+1. - Complete an AI session that escalates, then have a human agent resolve the ticket →
supporthub_ai_session_outcomes_total{outcome="escalated"}+1, and once resolved,supporthub_ticket_resolutions_total{resolved_by="human"}+1. - Resolve any ticket →
supporthub_ticket_resolution_duration_secondsgains one new observation. - Post the first agent reply on a ticket →
supporthub_ticket_first_response_duration_secondsgains one new observation. - Let an SLA run complete on time, and separately let one breach (via the existing breach-sweep
test helper) →
supporthub_sla_run_outcomes_total{outcome="met"}and{outcome="breached"}each +1 respectively. - Trigger an escalation →
supporthub_escalations_total{reason="<the actual reason>"}+1. - Create a ticket for a categorized problem →
supporthub_problems_created_total{category_id="<id>"}+1. - Look up a valid error code's known issues →
supporthub_known_error_lookups_total{code="<code>"}+1. - Have the AI's
searchProductKnowledgetool return zero results, then results →supporthub_knowledge_retrieval_outcomes_total{matched="false"}then{matched="true"}, each +1 in turn. - Have any AI tool invocation fail →
supporthub_tool_invocations_total{tool="<name>", outcome="failed"}+1.
What "done" looks like
All four scenarios pass against a real Postgres/Redis, /health* and the existing
supporthub_http_request_duration_seconds metric's shape are unchanged for any existing
consumer, and the API starts and serves traffic normally with no tracing collector configured.