feat(agent-office/db): get_logs에서 State: 자동 로그 제외 + delete_old_logs(90일)
This commit is contained in:
@@ -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]]:
|
def get_logs(agent_id: str, limit: int = 50) -> List[Dict[str, Any]]:
|
||||||
with _conn() as conn:
|
with _conn() as conn:
|
||||||
rows = conn.execute(
|
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),
|
(agent_id, limit),
|
||||||
).fetchall()
|
).fetchall()
|
||||||
return [
|
return [
|
||||||
@@ -332,6 +338,7 @@ def get_logs(agent_id: str, limit: int = 50) -> List[Dict[str, Any]]:
|
|||||||
"level": r["level"],
|
"level": r["level"],
|
||||||
"message": r["message"],
|
"message": r["message"],
|
||||||
"created_at": r["created_at"],
|
"created_at": r["created_at"],
|
||||||
|
"source": "agent",
|
||||||
}
|
}
|
||||||
for r in rows
|
for r in rows
|
||||||
]
|
]
|
||||||
@@ -588,6 +595,20 @@ def get_activity_feed(limit: int = 50, offset: int = 0) -> dict:
|
|||||||
return {"items": items, "total": total}
|
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 ────────────────────────────────────────────────
|
# ── youtube_research_jobs CRUD ────────────────────────────────────────────────
|
||||||
|
|
||||||
def add_youtube_research_job(countries: list) -> int:
|
def add_youtube_research_job(countries: list) -> int:
|
||||||
|
|||||||
@@ -93,6 +93,41 @@ def test_telegram_state():
|
|||||||
print(" [PASS] 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__":
|
if __name__ == "__main__":
|
||||||
test_init_and_seed()
|
test_init_and_seed()
|
||||||
test_agent_config_update()
|
test_agent_config_update()
|
||||||
|
|||||||
Reference in New Issue
Block a user