from __future__ import annotations from app.services.system_logs import SystemLogService def test_system_log_service_reads_tail(tmp_path) -> None: log_dir = tmp_path / "logs" log_dir.mkdir(parents=True, exist_ok=True) log_file = log_dir / "app.log" log_file.write_text( "\n".join(f"line-{index}" for index in range(1, 21)) + "\n", encoding="utf-8", ) service = SystemLogService(log_dir=log_dir) files = service.list_files() tail = service.read_tail("app.log", line_limit=5) assert [item.name for item in files] == ["app.log"] assert tail.name == "app.log" assert tail.line_count == 5 assert tail.lines == ["line-16", "line-17", "line-18", "line-19", "line-20"] def test_system_log_service_parses_entries(tmp_path) -> None: log_dir = tmp_path / "logs" log_dir.mkdir(parents=True, exist_ok=True) log_file = log_dir / "app.log" log_file.write_text( "\n".join( [ "2026-05-15 09:00:00 | INFO | app.middleware.access | GET /api/v1/health 200 8.2ms request_id=req_1", "2026-05-15 09:00:01 | WARNING | app.services.settings | Skipping undecryptable model API key", "2026-05-15 09:00:02 | ERROR | app.services.demo | Failed to load plugin", "Traceback line 1", ] ) + "\n", encoding="utf-8", ) service = SystemLogService(log_dir=log_dir) entries = service.list_entries(entry_limit=10) assert len(entries) == 3 assert entries[0].level == "ERROR" assert entries[0].event_type == "系统异常" assert "Traceback line 1" in entries[0].raw assert entries[1].outcome == "告警" assert entries[2].event_type == "HTTP 请求" assert entries[2].method == "GET" assert entries[2].status_code == 200 assert entries[2].request_id == "req_1" assert service.get_entry(entries[2].id).id == entries[2].id