"""Logs daemon handler. Reads system logs and journal entries. """ import logging from pathlib import Path from daemon.server import registry from lib.common import run_proc logger = logging.getLogger(__name__) PROJECT_DIR = Path(__file__).resolve().parent.parent.parent _APP_LOG_FILE = PROJECT_DIR / "data" / "logs" / "vacuum-wall.log" _MAX_LINES = 200 def _tail_file(path: str, n: int = _MAX_LINES, sudo: bool = False) -> str: try: if sudo: result = run_proc(["cat", path], sudo=True) lines = result.stdout.splitlines(keepends=True) else: with open(path) as f: lines = f.readlines() return "".join(lines[-n:]) except FileNotFoundError: return "(log file not found)\n" except PermissionError: return "(permission denied)\n" def _sudo_journalctl(unit: str, n: int = _MAX_LINES) -> str: try: result = run_proc( ["journalctl", "--unit=" + unit, "-n", str(n)], sudo=True, check=False, timeout=10, ) output = result.stdout.strip() return output if output else f"(no journal entries for {unit})\n" except Exception as exc: return f"(error reading journal: {exc})\n" @registry.register("GET", "/logs/journal") def journal(_request, _body) -> str: return _sudo_journalctl("vacuum-wall") @registry.register("GET", "/logs/nginx/access") def nginx_access(_request, _body) -> str: return _tail_file("/var/log/nginx/access.log", sudo=True) @registry.register("GET", "/logs/nginx/error") def nginx_error(_request, _body) -> str: return _tail_file("/var/log/nginx/error.log", sudo=True) @registry.register("GET", "/logs/dnsmasq") def dnsmasq_log(_request, _body) -> str: return _sudo_journalctl("dnsmasq") @registry.register("GET", "/logs/app") def app_log(_request, _body) -> str: return _tail_file(str(_APP_LOG_FILE))