Files
fuel-price/docs/superpowers/specs/2026-04-04-apilog-design.md
2026-04-04 08:34:56 +01:00

2.3 KiB

API Log Design

Date: 2026-04-04 Scope: Outbound HTTP request logging only. Inbound request logging is out of scope (separate table request_logs when needed).

Purpose

Log every outbound HTTP request made by this application to external APIs. Provides an audit trail for debugging failed polls, tracking latency, and monitoring API health over time.

Table: api_logs

Column Type Nullable Notes
id BIGINT UNSIGNED no Auto-increment PK
service VARCHAR(32) no Identifies the external service: fuel_finder, fred, postcodes_io, vonage, onesignal
method VARCHAR(8) no HTTP method: GET, POST
url VARCHAR(512) no Full URL including query string
status_code SMALLINT UNSIGNED yes HTTP response status code; null if request threw an exception
duration_ms SMALLINT UNSIGNED no Round-trip response time in milliseconds
error TEXT yes Exception message if the request failed; null on success
created_at DATETIME no When the request was made

No updated_at — rows are write-once.

ApiLogger Service

A thin ApiLogger service wraps Laravel's Http:: facade. It:

  1. Records start time
  2. Makes the HTTP request inside a try/catch
  3. Writes an api_logs row with URL, status, duration, and error (if any) — always, via try/finally
  4. Re-throws any exception so the calling service retains full control over error handling

FuelPriceService (and future services hitting external APIs) inject ApiLogger and use it instead of calling Http:: directly.

What Gets Logged

Every outbound GET and POST — including:

  • Fuel Finder OAuth token requests (POST /oauth/generate_access_token)
  • Fuel Finder price batch fetches (GET /pfs/fuel-prices?batch-number=N)
  • Fuel Finder station metadata fetches (GET /pfs?batch-number=N)
  • Future: FRED Brent crude fetch, Postcodes.io lookups, Vonage, OneSignal

Out of Scope

  • Response body storage (not logged — too large, not needed)
  • Request headers or credentials (never logged)
  • Inbound request logging (request_logs — separate feature)
  • Relation between api_logs and station_prices rows

Pruning

Old rows can be pruned on a schedule (e.g. keep 30 days). Not in scope for this implementation but the table should support it via created_at index.