Files
homelab-optimized/dashboard/api/routers/logs.py
Gitea Mirror Bot e03072e1ec
Some checks failed
Documentation / Deploy to GitHub Pages (push) Has been cancelled
Documentation / Build Docusaurus (push) Has been cancelled
Sanitized mirror from private repository - 2026-04-19 08:30:52 UTC
2026-04-19 08:30:52 +00:00

60 lines
1.7 KiB
Python

"""Unified log viewer routes."""
from fastapi import APIRouter, Query
from pathlib import Path
router = APIRouter(tags=["logs"])
LOG_DIR = Path("/app/logs") if Path("/app/logs").exists() else Path("/tmp")
LOG_FILES = {
"stack-restart": "stack-restart.log",
"backup": "backup-validator.log",
"gmail-lz": "gmail-organizer.log",
"gmail-dvish": "gmail-organizer-dvish.log",
"proton": "proton-organizer.log",
"receipt": "receipt-tracker.log",
"drift": "config-drift.log",
"digest": "email-digest.log",
"disk": "disk-predictor.log",
"changelog": "changelog-generator.log",
"subscription": "subscription-auditor.log",
"pr-review": "pr-reviewer.log",
}
@router.get("/logs")
def list_logs():
"""List available log files with sizes."""
result = []
for name, filename in LOG_FILES.items():
path = LOG_DIR / filename
if path.exists():
stat = path.stat()
result.append({
"name": name,
"filename": filename,
"size_bytes": stat.st_size,
"modified": stat.st_mtime,
})
return result
@router.get("/logs/{log_name}")
def get_log(log_name: str, tail: int = Query(200, le=2000), search: str = Query(None)):
"""Get log file contents."""
if log_name not in LOG_FILES:
return {"error": f"Unknown log: {log_name}", "lines": []}
path = LOG_DIR / LOG_FILES[log_name]
if not path.exists():
return {"lines": [], "total": 0}
with open(path) as f:
all_lines = f.readlines()
if search:
all_lines = [l for l in all_lines if search.lower() in l.lower()]
lines = all_lines[-tail:]
return {"lines": [l.rstrip() for l in lines], "total": len(all_lines)}