"""접속 로그 조회 및 초기화.""" from __future__ import annotations import sqlite3 from fastapi import APIRouter, Query from config_io import LOG_DB router = APIRouter() @router.get("/logs") def list_logs( limit: int = Query(50, ge=1, le=500), offset: int = Query(0, ge=0), action: str | None = Query(None), from_ts: float | None = Query(None, description="unix epoch seconds, inclusive"), to_ts: float | None = Query(None, description="unix epoch seconds, exclusive"), ) -> dict: if not LOG_DB.exists(): return {"total": 0, "items": []} con = sqlite3.connect(LOG_DB) try: con.row_factory = sqlite3.Row conds: list[str] = [] params: list = [] if action: conds.append("action = ?") params.append(action) if from_ts is not None: conds.append("ts >= ?") params.append(from_ts) if to_ts is not None: conds.append("ts < ?") params.append(to_ts) where = ("WHERE " + " AND ".join(conds)) if conds else "" total = con.execute( f"SELECT COUNT(*) FROM connections {where}", params ).fetchone()[0] rows = con.execute( f"SELECT id, ts, client_ip, domain, next_state, action, reason " f"FROM connections {where} ORDER BY id DESC LIMIT ? OFFSET ?", [*params, limit, offset], ).fetchall() finally: con.close() return {"total": total, "items": [dict(r) for r in rows]} @router.delete("/logs") def clear_logs( from_ts: float | None = Query(None, description="ts >= from_ts 만 삭제"), to_ts: float | None = Query(None, description="ts < to_ts 만 삭제"), ) -> dict: """접속 로그를 삭제한다. - from_ts/to_ts 둘 다 없으면 전체 삭제 (AUTOINCREMENT 카운터까지 리셋) - 둘 중 하나만 있으면 그 조건만 적용 - 둘 다 있으면 [from_ts, to_ts) 범위 삭제 — 날짜 선택 삭제 용도 """ if not LOG_DB.exists(): return {"deleted": 0} con = sqlite3.connect(LOG_DB, timeout=5) try: conds: list[str] = [] params: list = [] if from_ts is not None: conds.append("ts >= ?") params.append(from_ts) if to_ts is not None: conds.append("ts < ?") params.append(to_ts) if conds: where = "WHERE " + " AND ".join(conds) cur = con.execute(f"DELETE FROM connections {where}", params) deleted = cur.rowcount else: cur = con.execute("DELETE FROM connections") deleted = cur.rowcount con.execute("DELETE FROM sqlite_sequence WHERE name='connections'") con.commit() finally: con.close() return {"deleted": deleted}