Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

🎃 Export the audit log as CSV or JSON from /logs

Đang mở
#849 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
68/100
Loại issue
Tính năng
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
typescript

Hướng nghiên cứu

Start with the list filters in packages/backend/src/audit/audit.controller.ts and orgScope()/getRecentInvocations() in audit.service.ts; then read the logs page and audit client paths listed in the issue. Run the backend tests with cd packages/backend && npm test and add the specified CSV utility tests. Done means the streamed export honors filters, admin and organization restrictions, row cap and truncation header, with the frontend button and API docs updated.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

enhancement hacktoberfest help wanted

Part of the October Challenge #846.

Why

The Audit Log page (/logs) only lets you page through tool calls 50 at a time. Admins who need to send a compliance report, look into an incident in a spreadsheet, or attach evidence to a support ticket have nothing to download. Most API gateways and MCP platforms (Kong, Tyk, Apigee, Postman monitors) have a "download logs" button. This issue adds a streamed export that applies the filters the user already has set.

Self-hosted vs Cloud

  • Self-hosted: enabled in Community and Business. Not a Business feature: do not touch ee/.
  • Cloud (DEPLOYMENT_MODE=cloud): enabled, behaves the same. Cloud is multi-tenant, so the export must always be scoped to the caller's organization: refuse with 403 when req.user.organizationId is not set, and never fall back to unscoped rows. One tenant can hold millions of rows (see the comment in bound-payload.ts), so the row cap and the throttle are required.
  • Who can use it: ADMIN only (@Roles('ADMIN') + RolesGuard). Every role can view the list today, but a bulk download of the whole org's call payloads is a bigger step, so it is limited to admins. Hide the button for other roles. The data is always filtered to the caller's organization.

What to build

  1. Backend: GET /api/audit/invocations/export?format=csv|json in audit.controller.ts. It takes the same filters as the list (status, search, connectorId, mcpServerId, toolId) plus optional ISO from/to on createdAt.
  2. Move the where construction out of getRecentInvocations() into one helper (e.g. buildInvocationWhere(filters)) that both the list and the export call, so the two cannot drift apart.
  3. Stream the response: read in batches (e.g. 1000 rows, keyset pagination on createdAt/id, newest first) and write each batch to res. Never load everything into memory. Cap at AUDIT_EXPORT_MAX_ROWS (default 50000). Send X-Export-Truncated: true when the cap was hit (do a count first). Set Content-Disposition: attachment; filename="anythingmcp-logs-YYYY-MM-DD.csv". Throttle with @Throttle({ default: { limit: 5, ttl: 60_000 } }).
  4. Columns (only data the page already shows): createdAt (ISO), status, durationMs, tool, connector, connectorType, mcpServer, userEmail, authMethod, apiKeyName, error. JSON additionally includes the input/output excerpts exactly as stored. Do not export intent, costMicros, usedProxy, the raw clientInfo blob, internal ids other than the invocation id, or anything else the UI does not show.
  5. CSV safety: RFC 4180 quoting (wrap in quotes, double any "), and escape formula injection: prefix any cell that starts with =, +, -, @, tab or CR with '. Put this in a small pure function (e.g. packages/backend/src/audit/csv.util.ts) so it can be unit-tested. JSON: either one array or NDJSON. Pick one and document it.
  6. Frontend: an "Export" button (with a CSV/JSON choice) in the page actions next to Refresh. Call it with the current filters, fetch with the Bearer token, download the result as a Blob (same pattern as connectors/page.tsx:139-149), and show a notice when X-Export-Truncated is set. Add an audit.exportInvocations() helper in lib/api.ts. The shared request() helper parses JSON, so it can't be used for the file.

Where to look

  • packages/backend/src/audit/audit.controller.ts:13-38: the list endpoint and its filters.
  • packages/backend/src/audit/audit.service.ts:176-225: orgScope() and getRecentInvocations().
  • packages/backend/src/audit/bound-payload.ts:16: _amcp_truncated marker. Stored payloads are excerpts, so don't try to recover full bodies.
  • packages/backend/src/knowledge-graph/kg.controller.ts:22,52: RolesGuard + @Roles('ADMIN') pattern.
  • packages/backend/src/auth/login.controller.ts:137: @Throttle pattern.
  • packages/backend/src/auth/login.controller.ts:87: @Res() usage with Express.
  • packages/frontend/src/app/logs/page.tsx:116-134 (filters), :183-207 (the exportButton variable is actually Refresh; rename it), :204-208 (actions).
  • packages/frontend/src/app/settings/layout.tsx:54: user?.role === 'ADMIN' check.
  • packages/frontend/src/lib/api.ts:735-747: audit client.

Acceptance criteria

  • Export applies every active filter, and only the caller's org rows are ever returned (unit test: organizationId is in the where; a missing org gives 403).
  • Non-admins get 403, and the button is hidden for them.
  • Results are streamed in batches, the row cap is honored, and the truncation header is set.
  • csv.util.spec.ts covers quoting, newlines inside cells, and =cmd|' /C calc'!A0-style injection.
  • audit.service.spec.ts / a new controller spec covers the shared where-builder (cd packages/backend && npm test).
  • docs/api-reference.md Audit section (line 219) documents the endpoint. Also fix the existing examples at lines 226-236, which use toolName/from/to params the list endpoint does not support.

Out of scope

  • Scheduled exports, emailing exports, S3/SIEM push.
  • Exporting security events or product events.
  • Changing what is stored in tool_invocations, or the retention policy.

Size

M (1–2 days)

How to claim

Comment "I'd like to work on this" and we'll assign you. Rules in #846.

Ngôn ngữ chính
TypeScript
Star
856
Fork
82
Merge trung bình
5 giờ 18 phút
Pull request đã merge (30 ngày)
162

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của HelpCode-ai/anythingmcp

Tất cả issue của HelpCode-ai/anythingmcp

Issue tương tự

Thêm issue về TypeScript

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.