Skip to content

feat(api-request-log): re-enable logging, increase retention to 30 days, add admin download panel#1745

Open
kilo-code-bot[bot] wants to merge 3 commits intomainfrom
session/agent_bac8088d-f769-4ccf-ac19-8ecfce8305a2
Open

feat(api-request-log): re-enable logging, increase retention to 30 days, add admin download panel#1745
kilo-code-bot[bot] wants to merge 3 commits intomainfrom
session/agent_bac8088d-f769-4ccf-ac19-8ecfce8305a2

Conversation

@kilo-code-bot
Copy link
Copy Markdown
Contributor

@kilo-code-bot kilo-code-bot bot commented Mar 30, 2026

Summary

  • Re-enable API request logging in the openrouter proxy route (was disabled pending migration)
  • Increase cleanup cron retention from 7 days to 30 days
  • Add new admin panel at /admin/api-request-log for downloading request/response data as a streamed zip file
  • Admin can filter by user ID and date range; each request/response is a separate file named <timestamp>_<id>_request|response.json|txt with human-readable JSON formatting
  • Added archiver dependency for server-side zip streaming

Verification

  • tsgo --noEmit — no new type errors (5 pre-existing errors in packages/db unrelated to this change)
  • Verified handleRequestLogging import was re-added to the openrouter route
  • Confirmed cleanup cron now uses 30-day cutoff

Visual Changes

N/A

Reviewer Notes

  • The handleRequestLogging function still gates logging behind an allowlist (kilo.ai/kilocode.ai emails + specific user/org hashes). This PR only uncomments the call site — it does not change who gets logged.
  • The zip download endpoint loads all matching rows into memory before streaming. For very large result sets this could be a concern, but given the allowlist-gated logging volume this should be fine in practice.
  • File naming example: 2026-03-30_12-00-00-000_123_request.json — timestamps have colons/dots replaced with hyphens for filesystem compatibility.

…ys, add admin download panel

- Uncomment handleRequestLogging call in openrouter proxy route
- Increase cleanup cron retention from 7 to 30 days
- Add admin page with user ID and date range filters
- Stream zip file with formatted request/response JSON files
- Add archiver dependency for server-side zip streaming

const conditions = [
eq(api_request_log.kilo_user_id, userId),
gte(api_request_log.created_at, new Date(startDate).toISOString()),
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Invalid dates trigger a 500 here

new Date(...).toISOString() throws a RangeError for malformed query strings (for example startDate=foo or endDate=2026-02-31). Because this route is still reachable via a normal GET request, a bad parameter currently becomes a 500 instead of a 400. Validate both dates before building the Drizzle predicates.

return;
}

const blob = await response.blob();
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION: The client buffers the full ZIP before starting the download

response.blob() defeats the server-side zip streaming and keeps the entire export in browser memory before the save prompt appears. For larger 30-day exports, this can make the admin page much heavier than necessary. Navigating directly to the download URL (for example with a normal link or form submission) preserves streaming end-to-end.

@kilo-code-bot
Copy link
Copy Markdown
Contributor Author

kilo-code-bot bot commented Mar 30, 2026

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0

Fix these issues in Kilo Cloud

Issue Details (click to expand)

WARNING

File Line Issue
src/app/admin/api-request-log/page.tsx 41 Direct navigation preserves streaming, but any non-2xx response now replaces the admin page with raw JSON instead of using the existing inline error UI.
Other Observations (not in diff)

N/A

Files Reviewed (2 files)
  • src/app/admin/api-request-log/page.tsx - 1 issue
  • src/app/admin/api/api-request-log/download/route.ts - 0 issues

Reviewed by gpt-5.4-20260305 · 154,960 tokens

…irect URL download

- Validate date params before building queries to return 400 instead of 500
- Use window.location.href for download to preserve end-to-end streaming
- Add void to archive.finalize() to satisfy lint
- Run oxfmt formatting
});

// Navigate directly to preserve server-side streaming
window.location.href = `/admin/api/api-request-log/download?${params}`;
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WARNING: Direct navigation drops server-side error handling

Navigating the current tab preserves streaming, but any non-2xx response from this endpoint (No records found, invalid date after manual input, expired admin session) now replaces the admin page with raw JSON instead of using the existing inline error UI. This is a regression from the previous flow, so the download path still needs a way to surface server-side failures without leaving the page.

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.

1 participant