Skip to content

[AISAGE-733] feat(ai-gateway): errors-only request logging and API request log filters - #8060

Merged
chrarnoldus merged 2 commits into
mainfrom
add-error-only-logging-option
Oct 19, 2026
Merged

chrarnoldus merged 2 commits into
mainfrom
add-error-only-logging-option

Conversation

@chrarnoldus

Copy link
Copy Markdown
Contributor

Summary

Changes to the API Request Log tab at /admin/gateway?tab=api-request-log.

Errors-only request logging opt-ins

When creating a request logging opt-in, you can now set Log to All requests (the default) or Errors only. The active opt-ins table has a new Log column.

  • What gets logged. An errors-only opt-in writes an api_request_log row and its R2 bodies only for:

    • an upstream status of 400 or higher,
    • a response body read error (timeout, disconnect, or client cancel), or
    • invalid tool-call arguments.

    This matches the download's existing "Errors only" filter. The response body is still buffered, because tool-call errors can only be detected after the body is read. Successful responses are dropped before anything is uploaded to R2 or inserted.

  • Overlapping opt-ins. When an account opt-in and an organization opt-in both match, the broader one wins: if either logs all requests, all requests are logged.

  • Existing data. errors_only is a new field in the ai_gateway_request_logging_opt_ins.opt_ins JSON. It defaults to false, so existing opt-ins keep logging all requests. No migration is needed.

  • Code changes. isDynamicallyOptedIntoRequestLogging is replaced by getDynamicRequestLoggingMode, which returns 'all' | 'errors_only' | null.

Download filters

  • Organization ID filter. Matches organization_id exactly and adds _org-<id> to the ZIP filename.
  • Model filter is now a prefix match. The placeholder is now anthropic/. LIKE wildcards (%, _, \) in the input are escaped, so they match literally.

Limitations

  • Errors that are not detected. Errors-only logging uses the upstream HTTP status, so a 200 stream that reports an error inside an SSE event is not logged (unless it produces a read error or invalid tool-call arguments).
  • Errors that happen before a response. Requests that fail before an upstream response arrives were never logged, and still are not. Examples: auth failures, rate limits, upstream fetch failures.
  • Rollout order. If the web app deploys before the AI gateway, an errors-only opt-in created in between logs all requests until the gateway deploys, because the old schema drops the unknown field.

Verification

  • jest -i for request-logging-opt-ins.test.ts and rewriteModelResponse.test.ts (136 passed). New tests check that an errors-only opt-in:

    • logs 400 responses,
    • skips 200 responses (no row and no R2 upload),
    • logs 200 responses that hit a body read error,
    • loses to a matching opt-in that logs all requests.

    Legacy opt-ins without errors_only parse as logging all requests.

  • jest -i src/app/admin/api/api-request-log/download (40 passed). New tests cover:

    • model prefix matching,
    • the organization filter and its filename,
    • literal %/_ in the prefix,
    • the organization filter combined with a log ID.
  • pnpm --filter web --filter ai-gateway --filter @kilocode/web-shared typecheck

  • oxlint --config .oxlintrc.json on the changed files, plus pnpm format:changed and git diff --check

  • Manually check the admin UI in a browser

Visual Changes

  • Request logging opt-ins form: new Log select (All requests / Errors only). The active opt-ins table has a new Log column.
  • Download form: new Organization ID field. "Model" is renamed to Model prefix, with placeholder e.g. anthropic/.

Reviewer Notes

The errors-only check runs inside the existing after() callback in createRequestLogCapture (packages/web-shared/src/lib/ai-gateway/rewriteModelResponse.ts), before the R2 upload.

@chrarnoldus chrarnoldus self-assigned this Oct 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants