freeleaps-ops/apps/gitea-webhook-ambassador-python/app/handlers/logs.py

106 lines
3.5 KiB
Python

from datetime import datetime, timedelta
from typing import List, Optional
from fastapi import APIRouter, Depends, HTTPException, Query
from pydantic import BaseModel
from sqlalchemy.orm import Session
from app.database import get_db
from app.models.trigger_log import TriggerLog
from app.auth import get_current_user
router = APIRouter(prefix="/api/logs", tags=["logs"])
class TriggerLogResponse(BaseModel):
id: int
repository_name: str
branch_name: str
commit_sha: str
job_name: str
status: str
error_message: Optional[str] = None
created_at: datetime
class Config:
from_attributes = True
@router.get("/", response_model=List[TriggerLogResponse])
async def get_trigger_logs(
repository: Optional[str] = Query(None, description="Repository name filter"),
branch: Optional[str] = Query(None, description="Branch name filter"),
since: Optional[str] = Query(None, description="Since timestamp (RFC3339 format)"),
limit: int = Query(100, ge=1, le=1000, description="Maximum number of logs to return"),
db: Session = Depends(get_db),
current_user: dict = Depends(get_current_user)
):
"""
Get trigger logs
"""
try:
# Build query
query = db.query(TriggerLog)
# Apply filters
if repository:
query = query.filter(TriggerLog.repository_name == repository)
if branch:
query = query.filter(TriggerLog.branch_name == branch)
if since:
try:
since_time = datetime.fromisoformat(since.replace('Z', '+00:00'))
query = query.filter(TriggerLog.created_at >= since_time)
except ValueError:
raise HTTPException(
status_code=400,
detail="Invalid since parameter format (use RFC3339)"
)
# Order by time desc and limit
logs = query.order_by(TriggerLog.created_at.desc()).limit(limit).all()
return logs
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed to get trigger logs: {str(e)}")
@router.get("/stats")
async def get_log_stats(
db: Session = Depends(get_db),
current_user: dict = Depends(get_current_user)
):
"""
Get log statistics
"""
try:
# Total logs
total_logs = db.query(TriggerLog).count()
# Successful and failed logs
successful_logs = db.query(TriggerLog).filter(TriggerLog.status == "success").count()
failed_logs = db.query(TriggerLog).filter(TriggerLog.status == "failed").count()
# Logs in the last 24 hours
yesterday = datetime.utcnow() - timedelta(days=1)
recent_logs = db.query(TriggerLog).filter(TriggerLog.created_at >= yesterday).count()
# Stats by repository
repo_stats = db.query(
TriggerLog.repository_name,
db.func.count(TriggerLog.id).label('count')
).group_by(TriggerLog.repository_name).all()
return {
"total_logs": total_logs,
"successful_logs": successful_logs,
"failed_logs": failed_logs,
"recent_logs_24h": recent_logs,
"repository_stats": [
{"repository": repo, "count": count}
for repo, count in repo_stats
]
}
except Exception as e:
raise HTTPException(status_code=500, detail=f"Failed to get log stats: {str(e)}")