dashboard/app/routers/journal.py

68 lines
1.9 KiB
Python

from typing import Any
from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse
from app import journal
from app.render import render
router = APIRouter(prefix="/api", tags=["journal"])
@router.get("/journal")
async def journal_view(
_request: Request,
level: str = "all",
unit: str = "",
search: str = "",
cursor: str = "",
hide_sudo: str = "",
):
"""Render the Journal tab fragment: a page of journal entries.
Without a cursor it fetches 100 lines; with one (continuing a scroll)
200, then keeps the newest 400 for the template. level is validated
against journal.LEVELS, and failures (RuntimeError/OSError from
journalctl) are rendered as an error banner instead of a 500.
Args:
_request: FastAPI request (unused).
level: "all" / "warn" / "err".
unit: unit name filter, empty for none.
search: free-text filter, empty for none.
cursor: journal cursor to continue after, empty for none.
hide_sudo: "on" to hide sudo's own log entries.
Returns:
The rendered journal.html as an HTMLResponse.
"""
if level not in journal.LEVELS:
level = "all"
lines = 200 if cursor else 100
error = None
entries: list[dict[str, Any]] = []
next_cursor = ""
try:
entries, nc = await journal.tail(
cursor or None,
level,
unit or None,
search or None,
lines,
hide_sudo=(hide_sudo == "on"),
)
next_cursor = nc or ""
entries = entries[-400:]
except (RuntimeError, OSError) as e:
error = str(e)[:300]
return HTMLResponse(
render(
"journal.html",
entries=entries,
next_cursor=next_cursor,
level=level,
unit=unit,
search=search,
error=error,
)
)