You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
SLM GUI has no application-log visibility — /api/monitoring/logs only serves fleet node events, not backend/frontend error logs #11302
The only builtin log surface — GET /slm/api/monitoring/logs (autobot-slm-backend/api/monitoring.py:746), which the SLM GUI's log view uses — returns fleet/node health events only:
severity=error&limit=10 → 1 result: {"event_type":"health_check","message":"Node status changed from online to error"}.
No access to the actual application error logs (/var/log/autobot/backend-error.log, celery-error.log, rum.log) — tracebacks, HTTP 500s, UndefinedColumnError, ImportError, etc.
Impact
Operators can't diagnose app-level failures from the GUI. Real incidents this session — Company OS 500s (unapplied migration), the Ollama ImportError/provider registration failure, the CEO-chat "no available provider" — were invisible to the builtin log view; they could only be found via shell on the box. "Loop through the logs" is not possible with builtin tooling.
Ask
Add a builtin application-log endpoint/view (tail + filter by service/severity/since over backend-error.log / celery-error.log / rum.log), surfaced in the SLM GUI alongside the fleet events. Redact secrets; paginate.
GET /slm/api/monitoring/logs (autobot-slm-backend/api/monitoring.py:745) queries only the NodeEvent table (select(NodeEvent)…, lines 758–786) — fleet/node health events. It has no path to real application logs. Those are written by systemd to files, not the DB:
Frontend surface: MonitoringView.vue:33 (logs tab) → LogViewer.vue → useSlmApi.ts:806 (GET /monitoring/logs). So the GUI's only log view shows fleet events; tracebacks/500s/ImportErrors are invisible without SSH.
Goal / non-goals
Goal: a builtin endpoint + GUI view to tail/filter real application logs (service, severity, since, text) with secret redaction and pagination, alongside the existing fleet events.
As an operator, I filter backend-error.log by severity=error since=1h in the GUI and read the traceback — no SSH.
As an operator, I pick a service (backend / celery / celery-beat / mcp-bridge / chromadb) and tail its error log live.
As an operator, I search log text (e.g. ImportError) across a service and paginate results.
As a security-conscious operator, secrets/tokens in log lines are redacted before they reach my browser.
Functional requirements
New endpoint (e.g. GET /api/monitoring/app-logs) — params: service, severity, since/hours, q (text), page, per_page; bounded tail (cap bytes/lines read).
Server-side allowlist of readable files under backend_log_dir (no arbitrary path traversal).
Redaction pass reusing existing secret-redaction util before serialization.
New GUI sub-view/tab in MonitoringView.vue + LogViewer.vue, service/severity/since filters, paginated virtualized list.
Auth: same get_current_user gate as /logs; consider admin-only RBAC (open question).
UX / API surface
API: GET /slm/api/monitoring/app-logs (LogsResponse-shaped: entries + total + page + per_page). Reuse LogEntry-style DTO.
UI entry: Monitoring → Logs → new "Application logs" segment (SLM frontend is single-locale — no 11-locale i18n needed here; still route all strings through the SLM i18n layer).
Success criteria
With a seeded traceback in backend-error.log, the GUI shows it filtered by service=backend severity=error within one refresh.
A line containing a token renders redacted.
Path-traversal / non-allowlisted service value → 400, no file read.
Reading a large log is bounded (no full-file load; verifiable via response cap).
Risks / open questions (OWNER decides)
Architecture — where do the logs physically live? SLM backend is the control plane; backend-error.log etc. are written on managed nodes, not necessarily the SLM host (architecture_two_backends). Does this view read (a) SLM-host-local logs only, (b) per-node via an agent/SSH/journald API, or (c) a forwarded store? LogForwardingSettings.vue exists — is forwarding the intended source? This choice drives the whole design.
RBAC: admin-only, or any authenticated operator?
Retention/volume: tail-only, or persist/index for historical search?
journald vs raw files as the read source.
Status: PRD drafted for review — not yet approved for build.
Key finding: a per-node service-logs endpoint already exists (GET /nodes/{node_id}/services/{service_name}/logs, services.py:701) but runs journalctl -u <svc> — which misses the real app logs. The backend/celery/etc. services redirect stdout+stderr to files via systemd StandardError=append:/var/log/autobot/*-error.log (autobot-backend.service.j2 etc.), bypassing journald. So journalctl shows only unit start/stop noise; tracebacks live only in the *.log files. #11302 is therefore a real gap.
Confirmed source (owner): read the log files per node via the existing guarded execute primitive (nodes_execution.py, POST /nodes/{node_id}/execute, Issue #3406) which already allows tail/cat/head on /var/log/ with allowlist + path-traversal + sensitive-path guards + admin.system RBAC + audit. No new file-reading surface.
Build:
GET /slm/api/monitoring/app-logs?node_id&service&severity&hours&q&page&per_page — maps service (backend|celery|celery-beat|mcp-bridge|chromadb) → allowlisted file under backend_log_dir; runs bounded tail on the node via the execute internals; parses → LogEntry-shaped DTOs; redacts secrets; filters severity/text/since; paginates. RBAC admin.system. Non-allowlisted service → 400.
SLM GUI: Monitoring → Logs → new "Application logs" segment (node picker + service + severity/since/text filters + paginated list). Strings via SLM i18n (en.json); SLM frontend is single-locale.
✅ Delivered in PR #12188 (merged to Dev_new_gui). New GET /slm/api/monitoring/app-logs reads real app-log files per node via the guarded /nodes execute primitive (allowlist + redaction + ADMIN_SYSTEM RBAC), surfaced as an 'Application Logs' tab in the SLM GUI. 187 backend tests pass. Closing.
Activity
mrveiss commentedon Jul 22, 2026
PRD — Application-log visibility in the SLM GUI
Problem
GET /slm/api/monitoring/logs(autobot-slm-backend/api/monitoring.py:745) queries only theNodeEventtable (select(NodeEvent)…, lines 758–786) — fleet/node health events. It has no path to real application logs. Those are written by systemd to files, not the DB:backend-error.log—ansible/roles/backend/templates/autobot-backend.service.j2:50(StandardError=append:{{ backend_log_dir }}/backend-error.log)celery-error.log—autobot-celery.service.j2:44;celery-beat-error.log—autobot-celery-beat.service.j2:50;mcp-bridge-%i-error.log;chromadb-error.logbackend_log_dirdefault/var/log/autobot(ansible/roles/backend/defaults/main.yml:13)Frontend surface:
MonitoringView.vue:33(logstab) →LogViewer.vue→useSlmApi.ts:806(GET /monitoring/logs). So the GUI's only log view shows fleet events; tracebacks/500s/ImportErrors are invisible without SSH.Goal / non-goals
User stories
backend-error.logbyseverity=error since=1hin the GUI and read the traceback — no SSH.ImportError) across a service and paginate results.Functional requirements
GET /api/monitoring/app-logs) — params:service,severity,since/hours,q(text),page,per_page; bounded tail (cap bytes/lines read).backend_log_dir(no arbitrary path traversal).MonitoringView.vue+LogViewer.vue, service/severity/since filters, paginated virtualized list.get_current_usergate as/logs; consider admin-only RBAC (open question).UX / API surface
GET /slm/api/monitoring/app-logs(LogsResponse-shaped: entries + total + page + per_page). ReuseLogEntry-style DTO.Success criteria
backend-error.log, the GUI shows it filtered byservice=backend severity=errorwithin one refresh.servicevalue → 400, no file read.Risks / open questions (OWNER decides)
backend-error.logetc. are written on managed nodes, not necessarily the SLM host (architecture_two_backends). Does this view read (a) SLM-host-local logs only, (b) per-node via an agent/SSH/journald API, or (c) a forwarded store?LogForwardingSettings.vueexists — is forwarding the intended source? This choice drives the whole design.Status: PRD drafted for review — not yet approved for build.
mrveiss commentedon Jul 23, 2026
✅ Design confirmed (owner approved) — reuse
/nodes/{node_id}/executefile-read pathKey finding: a per-node service-logs endpoint already exists (
GET /nodes/{node_id}/services/{service_name}/logs,services.py:701) but runsjournalctl -u <svc>— which misses the real app logs. The backend/celery/etc. services redirect stdout+stderr to files via systemdStandardError=append:/var/log/autobot/*-error.log(autobot-backend.service.j2etc.), bypassing journald. So journalctl shows only unit start/stop noise; tracebacks live only in the*.logfiles. #11302 is therefore a real gap.Confirmed source (owner): read the log files per node via the existing guarded execute primitive (
nodes_execution.py,POST /nodes/{node_id}/execute, Issue #3406) which already allowstail/cat/headon/var/log/with allowlist + path-traversal + sensitive-path guards +admin.systemRBAC + audit. No new file-reading surface.Build:
GET /slm/api/monitoring/app-logs?node_id&service&severity&hours&q&page&per_page— mapsservice(backend|celery|celery-beat|mcp-bridge|chromadb) → allowlisted file underbackend_log_dir; runs boundedtailon the node via the execute internals; parses →LogEntry-shaped DTOs; redacts secrets; filters severity/text/since; paginates. RBACadmin.system. Non-allowlistedservice→ 400.en.json); SLM frontend is single-locale.Moving to build.
feat(slm): application-log viewer — tail app-log files per node via g…
github-actions commentedon Jul 23, 2026
PR #12188 (merged to
Dev_new_gui) references this issue with a close keyword.If this issue is fully resolved, close it manually. If work remains, no action is needed.
mrveiss commentedon Jul 23, 2026
✅ Delivered in PR #12188 (merged to Dev_new_gui). New
GET /slm/api/monitoring/app-logsreads real app-log files per node via the guarded/nodes executeprimitive (allowlist + redaction + ADMIN_SYSTEM RBAC), surfaced as an 'Application Logs' tab in the SLM GUI. 187 backend tests pass. Closing.refactor(slm-frontend): migrate core useSlmApi composable onto slmApi…