Skip to content

Commit f75bea8

Browse files
committed
feat: Implement log management API endpoints with filtering, pagination, and summary analysis
1 parent 97abd60 commit f75bea8

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

app/api/logs.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
"""Log management API endpoints."""
2+
3+
from datetime import datetime
4+
from typing import Optional
5+
from uuid import UUID
6+
7+
from fastapi import APIRouter, Depends, HTTPException, Query, status
8+
from sqlalchemy.ext.asyncio import AsyncSession
9+
10+
from app.core.security import get_current_user
11+
from app.db.session import get_db
12+
from app.schemas.log_schemas import (
13+
LogEntryResponse,
14+
LogListResponse,
15+
AnalysisSummaryResponse,
16+
APIResponse,
17+
)
18+
from app.services.log_service import LogService
19+
20+
router = APIRouter()
21+
22+
23+
@router.get("/logs", response_model=LogListResponse)
24+
async def get_logs(
25+
service_name: Optional[str] = Query(None),
26+
log_level: Optional[str] = Query(None),
27+
start_date: Optional[datetime] = Query(None),
28+
end_date: Optional[datetime] = Query(None),
29+
page: int = Query(1, ge=1),
30+
page_size: int = Query(50, ge=1, le=500),
31+
db: AsyncSession = Depends(get_db),
32+
current_user: dict = Depends(get_current_user),
33+
) -> LogListResponse:
34+
"""
35+
Retrieve processed logs with filtering and pagination.
36+
37+
Requires JWT authentication.
38+
"""
39+
log_service = LogService(db)
40+
41+
offset = (page - 1) * page_size
42+
43+
logs, total = await log_service.get_logs(
44+
service_name=service_name,
45+
log_level=log_level,
46+
start_date=start_date,
47+
end_date=end_date,
48+
limit=page_size,
49+
offset=offset,
50+
)
51+
52+
total_pages = (total + page_size - 1) // page_size
53+
54+
return LogListResponse(
55+
data=[LogEntryResponse.model_validate(log) for log in logs],
56+
total=total,
57+
page=page,
58+
page_size=page_size,
59+
pages=total_pages,
60+
)
61+
62+
63+
@router.get("/logs/{log_id}", response_model=LogEntryResponse)
64+
async def get_log(
65+
log_id: UUID,
66+
db: AsyncSession = Depends(get_db),
67+
current_user: dict = Depends(get_current_user),
68+
) -> LogEntryResponse:
69+
"""Get a specific log entry by ID."""
70+
log_service = LogService(db)
71+
72+
log = await log_service.get_log_by_id(log_id)
73+
74+
if not log:
75+
raise HTTPException(
76+
status_code=status.HTTP_404_NOT_FOUND, detail="Log entry not found"
77+
)
78+
79+
return LogEntryResponse.model_validate(log)
80+
81+
82+
@router.get("/logs/summary", response_model=APIResponse)
83+
async def get_logs_summary(
84+
service_name: Optional[str] = Query(None),
85+
start_date: Optional[datetime] = Query(None),
86+
end_date: Optional[datetime] = Query(None),
87+
db: AsyncSession = Depends(get_db),
88+
current_user: dict = Depends(get_current_user),
89+
) -> APIResponse:
90+
"""
91+
Fetch aggregated insights and summary by service.
92+
93+
Returns analysis metrics and common errors.
94+
"""
95+
log_service = LogService(db)
96+
97+
logs, _ = await log_service.get_logs(
98+
service_name=service_name,
99+
start_date=start_date,
100+
end_date=end_date,
101+
limit=10000, # Large limit for analysis
102+
)
103+
104+
# Calculate summary
105+
from app.processing.analyzer import LogAnalyzer
106+
107+
analyzer = LogAnalyzer()
108+
analysis = analyzer.analyze_logs(logs)
109+
110+
return APIResponse(
111+
data=analysis,
112+
status_code=200,
113+
message="Log summary retrieved successfully",
114+
)

0 commit comments

Comments
 (0)