200e078bc5
- Add daemon/ module with aiohttp server, sync client, and handler registry - Add daemon/handlers/ for privileged operations (acme, dnsmasq, firewall, logs, nginx, wireguard) - Add system/acme-deploy.py, vacuum-walld sudoers and systemd service - Update API routes to use daemon client instead of lib/ directly - Update lib/, tests/, and webui/ for new architecture - Update docs and deployment scripts
69 lines
1.7 KiB
Python
69 lines
1.7 KiB
Python
"""Log viewing API blueprint.
|
|
|
|
Serves log content to the /logs page via HTMX endpoints through vacuum-walld.
|
|
"""
|
|
|
|
import logging
|
|
|
|
from flask import Blueprint, render_template_string
|
|
|
|
from daemon.client import get
|
|
|
|
logger = logging.getLogger(__name__)
|
|
bp = Blueprint("logs", __name__)
|
|
|
|
_LOG_LINE_TEMPLATE = """\
|
|
{% for line in lines %}
|
|
<div class="log-line{% if 'ERROR' in line %} log-error{% elif 'WARN' in line %} log-warn{% endif %}">{{ line | e }}</div>
|
|
{% endfor %}"""
|
|
|
|
|
|
def _render_log_lines(text: str) -> str:
|
|
lines = text.rstrip("\n").split("\n") if text.strip() else []
|
|
return render_template_string(_LOG_LINE_TEMPLATE, lines=lines)
|
|
|
|
|
|
@bp.route("/journal")
|
|
def journal():
|
|
try:
|
|
text = get("/logs/journal")
|
|
return _render_log_lines(text)
|
|
except RuntimeError:
|
|
return _render_log_lines("(error reading journal)\n")
|
|
|
|
|
|
@bp.route("/nginx/access")
|
|
def nginx_access():
|
|
try:
|
|
text = get("/logs/nginx/access")
|
|
return _render_log_lines(text)
|
|
except RuntimeError:
|
|
return _render_log_lines("(log file not found)\n")
|
|
|
|
|
|
@bp.route("/nginx/error")
|
|
def nginx_error():
|
|
try:
|
|
text = get("/logs/nginx/error")
|
|
return _render_log_lines(text)
|
|
except RuntimeError:
|
|
return _render_log_lines("(log file not found)\n")
|
|
|
|
|
|
@bp.route("/dnsmasq")
|
|
def dnsmasq():
|
|
try:
|
|
text = get("/logs/dnsmasq")
|
|
return _render_log_lines(text)
|
|
except RuntimeError:
|
|
return _render_log_lines("(error reading journal)\n")
|
|
|
|
|
|
@bp.route("/app")
|
|
def app_log():
|
|
try:
|
|
text = get("/logs/app")
|
|
return _render_log_lines(text)
|
|
except RuntimeError:
|
|
return _render_log_lines("(log file not found)\n")
|