Skip to content

26 - Traffic Logs

Purpose

Tradeboard records HTTP request metadata for monitoring, latency review, and security analysis. It does not store request bodies, response bodies, headers, user agents, or a per-request processing timeline in the traffic table.

Capture Flow

utils/traffic_logger.py wraps the Flask WSGI application. For each included request it captures context before submitting a serialized write to a single-worker executor:

FieldSource
timestampDatabase default
client_ipTrusted client-IP helper
methodFlask request method
pathFlask request path
status_codeWSGI response status
duration_msMiddleware wall time
hostRequest host
errorUnhandled middleware exception, when present
user_idflask.g, when populated

Writes go to logs.db through database/traffic_db.py. The executor has one worker so SQLite commits remain serialized and do not delay the HTTP response. The worker removes its scoped session after every write.

Static assets, the favicon, latency-log reads, and the traffic dashboard's own routes are excluded to avoid noise and recursion.

Dashboard

The supported React page is /logs/traffic. traffic_bp is registered with url_prefix="/traffic", and GET /traffic/ still renders the older server-side template. The React page calls the session-authenticated routes under /traffic:

RouteBehavior
GET /traffic/api/logsReturn recent entries; limit defaults to 100 and is capped at 1,000
GET /traffic/api/statsReturn overall, /api/v1-only, and selected endpoint statistics
GET /traffic/exportExport the current log set as CSV

The page shows total requests, error requests, average duration, a recent-request table, and per-endpoint totals/errors/average duration. UI filters select all versus /api/v1 traffic and all, successful, or error status.

The table displays timestamp, method, path, status, duration, client IP, and host. It deliberately does not expose stored request/response payloads because none are collected.

Retention

init_traffic_logging() initializes the store, purges rows beyond the retention window, and then installs the middleware. purge_old_traffic_logs() deletes traffic_logs rows older than TRAFFIC_LOG_RETENTION_DAYS (env var, default 30) and runs once at startup. Retention is not driven by the persisted security settings, and there is no multi-tier archive scheme.

Security

  • Proxy-derived IP headers are trusted only when TRUST_PROXY_HEADERS is enabled for a controlled reverse proxy.
  • API keys and tokens are not captured because traffic logging stores metadata only.
  • Dashboard, stats, logs, and export routes require a valid application session and have explicit rate limits.
  • logs.db also contains IP-ban and invalid-attempt security data; it is separate from tradeboard.db. Its location comes from LOGS_DATABASE_URL (default sqlite:///db/logs.db).

Key Files

FileResponsibility
utils/traffic_logger.pyMiddleware, exclusions, asynchronous write dispatch
database/traffic_db.pyTraffic schema, queries, retention, IP/security tables
blueprints/traffic.pyLogs, stats, CSV export, legacy template route
frontend/src/pages/monitoring/TrafficDashboard.tsxCurrent dashboard