Stage 9 · L41
Choose log destinations and distinguish health, metrics and traces
Core · original Session 9
Exception handling must respect whether a response has started. For an unhandled error before response start, the outer safe handler returns500 with a generic body and the generated ID stored on the ASGI scope. The request context may already have been reset; scope.request_id lets this outer handler preserve correlation.
A streaming response can start200 and then fail while producing its body. The server cannot honestly replace the already started status with a new500. RequestObservation records status200, response_complete=False and the exception class. The fixture proves that combination rather than claiming the stream completed successfully.
Health endpoints describe different evidence. /health/live says the app/lifespan is running. /health/ready executes SELECT1 through an owned session. Neither certifies every migration, provider dependency, stock rule or email delivery. The actual operations and their tests supply those narrower proofs.
Logs are individual events; metrics aggregate measurements; traces connect spans across work. This checkpoint implements structured application observations, not a production metric backend or distributed tracer. Useful metric designs would distinguish logical requests from provider attempts and avoid rental UUIDs or raw routes as labels.
Use a stated percentile method. For20 durations consisting of10–28ms and one2000ms outlier, nearest-rank p95 is the19th sorted value,28ms; mean is118.05ms and max2000ms. These describe different aspects of the sample. A production latency estimate needs enough representative observations and a defined window; a private fixture duration is not a public page-performance or provider-SLA claim.
A handler sends a record and a formatter shapes it. StreamHandler writes this app's stdout; FileHandler writes a selected file; rotating handlers manage bounded file rotation; QueueHandler/QueueListener can decouple producers from a managed consumer. File/queue lifetimes, permissions, rotation and shutdown need owners. Only the stdout handler is configured here; the alternatives are conceptual comparisons, not deployed collectors.
Follow the running code
Focused lesson example; see the end-of-stage capstone for the cumulative app · stage 09
Before response start: safe500 + generated ID
After streaming200 starts then fails: status200, complete=False
20 durations:10..28ms plus2000ms
Nearest-rank p95:19th sorted value =28ms
Mean=118.05ms; max=2000ms.Predict and observe this focused example using the concepts explained above. Its boundary is stated in the focused answer.
Guided lab
- Read the explanation and predict the focused example’s outcome.
- Classify the started-stream failure and select stdout/file/queue ownership. Calculate the stated p95 without claiming a deployed metric backend.
- Compare the observed outcome with the focused answer and state its boundary.
Expected: The committed status remains200 and completion isfalse; a replacement500 cannot be sent honestly. A StreamHandler outputs records and a formatter shapes them; file rotation/queue consumers need their own lifecycle. The19th sorted sample is28ms. Logs, aggregate metrics and connected trace spans answer different questions; only application stdout observations are configured.
- A successful liveness ping is not an end-to-end readiness certificate; mean is not p95.
Focused exercise and answer
Complete this focused exercise before reading its answer. The full native transfer is introduced only at the end of the stage.
Your transfer task: Classify the started-stream failure and select stdout/file/queue ownership. Calculate the stated p95 without claiming a deployed metric backend.
- Classify the started-stream failure and select stdout/file/queue ownership. Calculate the stated p95 without claiming a deployed metric backend.
Inspect the matching answer
This answer addresses the focused exercise above; the cumulative implementation is shown only after the stage prerequisites.
The committed status remains200 and completion isfalse; a replacement500 cannot be sent honestly. A StreamHandler outputs records and a formatter shapes them; file rotation/queue consumers need their own lifecycle. The19th sorted sample is28ms. Logs, aggregate metrics and connected trace spans answer different questions; only application stdout observations are configured.Check your reasoning
Can a stream that already started200 be relabeled500?
Show the explanation
No. Record the committed status and incomplete response honestly; handle pre-start errors separately.
Reading progress
54 lessons remain open to guests. Marking a lesson read records reading only; it does not award assessment credit or a certificate.
Device reading marks require browser storage. Reading is always available.
Sign in or create an account to save separate account progress. Your current page is kept.
Your earlier place on this device suggests these lessons. No new lesson is marked read.