From b25abea80a88cc155a6f3cfeb3d5e0b45a699e8f Mon Sep 17 00:00:00 2001 From: gahusb Date: Thu, 28 May 2026 02:45:10 +0900 Subject: [PATCH] =?UTF-8?q?feat(agent-office/db):=20get=5Flogs=EC=97=90?= =?UTF-8?q?=EC=84=9C=20State:=20=EC=9E=90=EB=8F=99=20=EB=A1=9C=EA=B7=B8=20?= =?UTF-8?q?=EC=A0=9C=EC=99=B8=20+=20delete=5Fold=5Flogs(90=EC=9D=BC)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agent-office/app/db.py | 23 ++++++++++++++++++++++- agent-office/app/test_db.py | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/agent-office/app/db.py b/agent-office/app/db.py index 030d893..e9212e0 100644 --- a/agent-office/app/db.py +++ b/agent-office/app/db.py @@ -321,7 +321,13 @@ def add_log(agent_id: str, message: str, level: str = "info", task_id: str = Non def get_logs(agent_id: str, limit: int = 50) -> List[Dict[str, Any]]: with _conn() as conn: rows = conn.execute( - "SELECT * FROM agent_logs WHERE agent_id=? ORDER BY created_at DESC LIMIT ?", + """ + SELECT * FROM agent_logs + WHERE agent_id = ? + AND message NOT LIKE 'State: %' + ORDER BY created_at DESC + LIMIT ? + """, (agent_id, limit), ).fetchall() return [ @@ -332,6 +338,7 @@ def get_logs(agent_id: str, limit: int = 50) -> List[Dict[str, Any]]: "level": r["level"], "message": r["message"], "created_at": r["created_at"], + "source": "agent", } for r in rows ] @@ -588,6 +595,20 @@ def get_activity_feed(limit: int = 50, offset: int = 0) -> dict: return {"items": items, "total": total} +import datetime as _dt + + +def delete_old_logs(days: int = 90) -> int: + """retention 정책: N일 이전 agent_logs 삭제. 매일 03:00 스케줄러가 호출.""" + cutoff = (_dt.datetime.utcnow() - _dt.timedelta(days=days)).isoformat() + with _conn() as conn: + c = conn.execute( + "DELETE FROM agent_logs WHERE created_at < ?", + (cutoff,), + ) + return c.rowcount + + # ── youtube_research_jobs CRUD ──────────────────────────────────────────────── def add_youtube_research_job(countries: list) -> int: diff --git a/agent-office/app/test_db.py b/agent-office/app/test_db.py index 267763b..08ebcab 100644 --- a/agent-office/app/test_db.py +++ b/agent-office/app/test_db.py @@ -93,6 +93,41 @@ def test_telegram_state(): print(" [PASS] test_telegram_state") +def test_get_logs_excludes_state_messages(): + init_db() + add_log("stock", "State: idle -> working (큐레이션 시작)") + add_log("stock", "뉴스 12건 스크랩 완료") + add_log("stock", "State: working -> idle ()") + + logs = get_logs("stock", limit=10) + messages = [x["message"] for x in logs] + assert "뉴스 12건 스크랩 완료" in messages + assert not any(m.startswith("State: ") for m in messages) + + +def test_delete_old_logs_removes_beyond_retention(): + import datetime as _dt + from app.db import delete_old_logs, _conn + + init_db() + add_log("stock", "오래된 로그") + # 강제로 200일 전으로 옮김 + cutoff = (_dt.datetime.utcnow() - _dt.timedelta(days=200)).isoformat() + with _conn() as conn: + conn.execute( + "UPDATE agent_logs SET created_at = ? WHERE message = '오래된 로그'", + (cutoff,), + ) + + add_log("stock", "최근 로그") + deleted = delete_old_logs(days=90) + assert deleted >= 1 + + msgs = [x["message"] for x in get_logs("stock", limit=20)] + assert "최근 로그" in msgs + assert "오래된 로그" not in msgs + + if __name__ == "__main__": test_init_and_seed() test_agent_config_update()