"""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 %}
{{ line | e }}
{% endfor %}"""
def _render_log_lines(text: str) -> str:
"""Render raw log text into styled HTML log-line divs.
Args:
text: Raw log content with newline-separated lines.
Returns:
HTML string with color-coded log-line elements.
"""
lines = text.rstrip("\n").split("\n") if text.strip() else []
return render_template_string(_LOG_LINE_TEMPLATE, lines=lines)
@bp.route("/journal")
def journal():
"""GET /api/logs/journal — Return systemd journal log lines.
Fetches the daemon's journal log content via vacuum-walld and
renders it as styled HTML log-line elements.
Returns:
HTML string containing rendered journal log lines.
"""
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():
"""GET /api/logs/nginx/access — Return nginx access log lines.
Fetches the nginx access log content via vacuum-walld and
renders it as styled HTML log-line elements.
Returns:
HTML string containing rendered access log lines.
"""
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():
"""GET /api/logs/nginx/error — Return nginx error log lines.
Fetches the nginx error log content via vacuum-walld and
renders it as styled HTML log-line elements.
Returns:
HTML string containing rendered error log lines.
"""
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():
"""GET /api/logs/dnsmasq — Return dnsmasq log lines.
Fetches the dnsmasq log content via vacuum-walld and
renders it as styled HTML log-line elements.
Returns:
HTML string containing rendered dnsmasq log lines.
"""
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():
"""GET /api/logs/app — Return application log lines.
Fetches the application log content via vacuum-walld and
renders it as styled HTML log-line elements.
Returns:
HTML string containing rendered application log lines.
"""
try:
text = get("/logs/app")
return _render_log_lines(text)
except RuntimeError:
return _render_log_lines("(log file not found)\n")