Add GET /api/logs/{name} endpoint to admin API
This commit is contained in:
parent
7ce4d3a895
commit
a9b0168c71
@ -169,6 +169,18 @@ async def get_ollama_models(
|
||||
except Exception:
|
||||
return {"models": [], "reachable": False}
|
||||
|
||||
@app.get("/api/logs/{name}")
|
||||
async def get_log_lines(name: str, _ = Depends(require_admin_auth)):
|
||||
if name not in ("usage", "error"):
|
||||
raise HTTPException(status_code=400, detail="name must be 'usage' or 'error'")
|
||||
log_file = Path(os.getenv("LOG_FILE", "logs/usage.log"))
|
||||
path = log_file if name == "usage" else log_file.parent / "error.log"
|
||||
try:
|
||||
lines = path.read_text(encoding="utf-8").splitlines()
|
||||
return {"lines": lines[-10:]}
|
||||
except FileNotFoundError:
|
||||
return {"lines": []}
|
||||
|
||||
# Statisches Frontend ausliefern (nur im Produktivbetrieb, wenn dist/ existiert)
|
||||
_dist = Path(__file__).parent.parent / "frontend" / "dist"
|
||||
if _dist.exists():
|
||||
|
||||
59
backend/tests/test_admin_logs.py
Normal file
59
backend/tests/test_admin_logs.py
Normal file
@ -0,0 +1,59 @@
|
||||
import os
|
||||
import pytest
|
||||
from fastapi.testclient import TestClient
|
||||
|
||||
os.environ.setdefault("ADMIN_PASSWORD", "test-admin-pw")
|
||||
os.environ.setdefault("OLLAMA_URL", "http://127.0.0.1:9999")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def client(tmp_path):
|
||||
log_file = tmp_path / "usage.log"
|
||||
log_file.write_text("\n".join(f"Zeile {i}" for i in range(1, 16)) + "\n")
|
||||
(tmp_path / "error.log").write_text("Fehler A\nFehler B\n")
|
||||
os.environ["LOG_FILE"] = str(log_file)
|
||||
|
||||
from database import Base, engine
|
||||
Base.metadata.drop_all(bind=engine)
|
||||
Base.metadata.create_all(bind=engine)
|
||||
|
||||
from admin import app
|
||||
yield TestClient(app, raise_server_exceptions=False)
|
||||
|
||||
Base.metadata.drop_all(bind=engine)
|
||||
os.environ.pop("LOG_FILE", None)
|
||||
|
||||
|
||||
AUTH = {"Authorization": "Bearer test-admin-pw"}
|
||||
|
||||
|
||||
def test_logs_usage_returns_last_10_lines(client):
|
||||
resp = client.get("/api/logs/usage", headers=AUTH)
|
||||
assert resp.status_code == 200
|
||||
lines = resp.json()["lines"]
|
||||
assert len(lines) == 10
|
||||
assert lines[-1] == "Zeile 15"
|
||||
assert lines[0] == "Zeile 6"
|
||||
|
||||
|
||||
def test_logs_error_returns_content(client):
|
||||
resp = client.get("/api/logs/error", headers=AUTH)
|
||||
assert resp.status_code == 200
|
||||
assert resp.json()["lines"] == ["Fehler A", "Fehler B"]
|
||||
|
||||
|
||||
def test_logs_missing_file_returns_empty(client, tmp_path):
|
||||
os.environ["LOG_FILE"] = str(tmp_path / "nonexistent.log")
|
||||
resp = client.get("/api/logs/usage", headers=AUTH)
|
||||
assert resp.status_code == 200
|
||||
assert resp.json()["lines"] == []
|
||||
|
||||
|
||||
def test_logs_invalid_name_returns_400(client):
|
||||
resp = client.get("/api/logs/secret", headers=AUTH)
|
||||
assert resp.status_code == 400
|
||||
|
||||
|
||||
def test_logs_requires_auth(client):
|
||||
resp = client.get("/api/logs/usage")
|
||||
assert resp.status_code == 401
|
||||
Loading…
x
Reference in New Issue
Block a user