Skip to Content

Logs

The logging system captures server-side activity into an in-memory ring buffer with REST and SSE streaming access. Logs are ideal for debugging extensions, cron jobs, and API calls without needing external log aggregation.

Log Entry Structure

interface LogEntry { id: string; // Unique entry ID timestamp: string; // ISO timestamp level: 'debug' | 'info' | 'warn' | 'error'; source: 'extension' | 'api' | 'emitter' | 'database' | 'auth' | 'system'; message: string; data?: Record<string, any>; // Optional structured data extensionId?: string; extensionName?: string; collection?: string; requestId?: string; userId?: string; }

Configuration

Environment variableDefaultDescription
LOG_MAX_ENTRIES1000Ring buffer size
LOG_MIN_LEVELdebugMinimum log level (debug, info, warn, error)
LOG_CONSOLE_OUTPUTtrueAlso write to stdout

REST API

Get logs

GET /api/logs

Requires authentication (unauthenticated requests receive 401). Access is granted to admins and to any user whose policy grants the system:logs module access key (Policy editor → Module-Level Access); other users receive 403. The same gate applies to GET /api/logs/stream. Clearing logs (DELETE /api/logs) remains admin-only.

Query parameters:

ParameterDescriptionExample
limitNumber of entries to return (default: 50, max: 500)?limit=100
levelFilter by level?level=error
sourceFilter by source?source=extension
extensionIdFilter by extension UUID?extensionId=<uuid>
extensionNameFilter by extension name (partial match)?extensionName=slug
collectionFilter by collection?collection=articles
sinceEntries after this timestamp or relative time (1h, 30m, 1d)?since=2025-01-01T00:00:00Z
untilEntries before this timestamp?until=2025-01-02T00:00:00Z
searchText search in message?search=validation

Response:

{ "data": { "count": 1, "entries": [ { "id": "log-uuid", "timestamp": "2025-01-15T10:00:00Z", "level": "error", "source": "extension", "message": "Validation failed: title is required", "extensionName": "article-validator", "collection": "articles" } ] } }

Clear logs

DELETE /api/logs

Clears all log entries from the in-memory buffer. Requires admin access.

Stream logs (SSE)

GET /api/logs/stream

Returns a text/event-stream response. Each new log entry is pushed as a Server-Sent Event. Supports level, source, and extensionName query parameters for filtering.

const es = new EventSource('/api/logs/stream?level=error', { headers: { Authorization: `Bearer ${token}` }, }); es.onmessage = (event) => { const entry = JSON.parse(event.data); console.log(entry.message); };

MCP Tool

The logs MCP tool exposes log access to AI agents. The tool is admin-only — all actions (including tail and read) require an admin token; the system:logs key applies to the REST API and Logs page only.

// Tail the last 50 entries { "action": "tail", "lines": 50, "level": "error" } // Read with filters { "action": "read", "since": "2025-01-15T00:00:00Z", "source": "extension" } // Search log messages { "action": "search", "query": "validation failed", "source": "extension" } // Get buffer statistics { "action": "stats" } // Clear all logs (admin only) { "action": "clear" }

The log buffer is in-memory and is cleared on server restart. In clustered deployments each worker process keeps its own buffer, so /api/logs, the SSE stream, and the Logs page show only the output of the worker that happened to serve your request. For persistent and complete log storage, aggregate container stdout — every worker echoes its logs to the console when LOG_CONSOLE_OUTPUT is enabled (the default), so stdout captures the whole cluster.

Last updated on