feat: GET /api/0/log — paged, filtered events journal API

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-10 15:15:46 -04:00
co-authored by Claude Fable 5
parent 7afc06a329
commit 7591268a89
+42
View File
@@ -20,6 +20,7 @@ from . import users as users_mod
from . import oauth as oauth_mod from . import oauth as oauth_mod
from . import ws as ws_mod from . import ws as ws_mod
from . import configio as configio_mod from . import configio as configio_mod
from . import journal as journal_mod
from . import config_access from . import config_access
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -362,6 +363,46 @@ async def start(
lst = data.msgs[-30:] lst = data.msgs[-30:]
return web.json_response(lst) return web.json_response(lst)
async def api_log(request):
"""Paged, filtered read of the events journal (newest first)."""
user, err = _require_auth(request)
if err:
return err
qa = request.rel_url.query
try:
limit = max(1, min(int(qa.get("limit", "100")), 1000))
except ValueError:
limit = 100
before = None
if qa.get("before"):
try:
before = float(qa["before"])
except ValueError:
return web.json_response({"error": "invalid before"}, status=400)
host_f = qa.get("host") or None
level_f = qa.get("level") or None
q_f = qa.get("q") or None
def visible(ev):
h = ev.get("host")
return not h or ws_mod._user_can_see_host(user, h)
ej = journal_mod.get_events_journal(config)
if ej.enabled and ej.journal_path.is_file():
events, more = journal_mod.read_events(
ej.journal_dir, ej.journal_file,
limit=limit, before=before, host=host_f, level=level_f, q=q_f,
predicate=visible,
)
else:
# Journal disabled or not yet written: serve the in-memory ring
events, more = journal_mod.filter_events(
reversed(data.msgs),
limit=limit, before=before, host=host_f, level=level_f, q=q_f,
predicate=visible,
)
return web.json_response({"events": events, "more": more})
async def cmd(request): async def cmd(request):
user, err = _require_auth(request) user, err = _require_auth(request)
if err: if err:
@@ -1779,6 +1820,7 @@ async def start(
web.get("/api/0/hosts", api_hosts), web.get("/api/0/hosts", api_hosts),
web.get("/api/0/alert_summary", api_alert_summary), web.get("/api/0/alert_summary", api_alert_summary),
web.get("/api/0/messages", api_messages), web.get("/api/0/messages", api_messages),
web.get("/api/0/log", api_log),
web.get("/api/0/hosts/{hostname}/plugins", api_host_plugins), web.get("/api/0/hosts/{hostname}/plugins", api_host_plugins),
web.get("/api/0/hosts/{hostname}/plugins/{plugin_name}", api_host_plugin_detail), web.get("/api/0/hosts/{hostname}/plugins/{plugin_name}", api_host_plugin_detail),
web.get("/api/0/hosts/{hostname}/alerts", api_host_alerts), web.get("/api/0/hosts/{hostname}/alerts", api_host_alerts),