Backend Integration:
- Created PipelineClient for communicating with Pipeline Monitor (port 8100)
- Added proxy endpoints in monitoring.py:
* /api/v1/monitoring/pipeline/stats - Queue status and article counts
* /api/v1/monitoring/pipeline/health - Pipeline service health
* /api/v1/monitoring/pipeline/queues/{name} - Queue details
* /api/v1/monitoring/pipeline/workers - Worker status
Frontend Integration:
- Added Pipeline Monitor API functions to monitoring.ts
- Updated Monitoring page to display:
* Redis queue status (keyword, rss, search, summarize, assembly)
* Article statistics (today, total, active keywords)
* Pipeline health status
* Worker status for each pipeline type
Architecture:
- Console acts as API Gateway, proxying requests to Pipeline Monitor
- Pipeline Monitor (services/pipeline/monitor) manages:
* RSS Collector, Google Search, AI Summarizer, Article Assembly workers
* Redis queues for async job processing
* MongoDB for article and keyword storage
This integration allows the News Engine Console to monitor and display
real-time pipeline activity, queue status, and worker health.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
194 lines
6.0 KiB
Python
194 lines
6.0 KiB
Python
from fastapi import APIRouter, Depends, Query
|
|
from typing import Optional
|
|
from datetime import datetime
|
|
|
|
from app.core.auth import get_current_active_user, User
|
|
from app.core.database import get_database
|
|
from app.core.pipeline_client import get_pipeline_client, PipelineClient
|
|
from app.services.monitoring_service import MonitoringService
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
def get_monitoring_service(db=Depends(get_database)) -> MonitoringService:
|
|
"""Dependency to get monitoring service"""
|
|
return MonitoringService(db)
|
|
|
|
|
|
@router.get("/health")
|
|
async def get_system_health(
|
|
current_user: User = Depends(get_current_active_user),
|
|
monitoring_service: MonitoringService = Depends(get_monitoring_service)
|
|
):
|
|
"""
|
|
Get overall system health status
|
|
|
|
Includes MongoDB, pipelines, and other component health checks
|
|
"""
|
|
health = await monitoring_service.get_system_health()
|
|
return health
|
|
|
|
|
|
@router.get("/metrics")
|
|
async def get_system_metrics(
|
|
current_user: User = Depends(get_current_active_user),
|
|
monitoring_service: MonitoringService = Depends(get_monitoring_service)
|
|
):
|
|
"""
|
|
Get system-wide metrics
|
|
|
|
Includes counts and aggregations for keywords, pipelines, users, and applications
|
|
"""
|
|
metrics = await monitoring_service.get_system_metrics()
|
|
return metrics
|
|
|
|
|
|
@router.get("/logs")
|
|
async def get_activity_logs(
|
|
limit: int = Query(100, ge=1, le=1000, description="Maximum number of logs"),
|
|
level: Optional[str] = Query(None, description="Filter by log level (INFO, WARNING, ERROR)"),
|
|
start_date: Optional[datetime] = Query(None, description="Filter logs after this date"),
|
|
end_date: Optional[datetime] = Query(None, description="Filter logs before this date"),
|
|
current_user: User = Depends(get_current_active_user),
|
|
monitoring_service: MonitoringService = Depends(get_monitoring_service)
|
|
):
|
|
"""
|
|
Get activity logs
|
|
|
|
Returns logs from all pipelines with optional filtering
|
|
"""
|
|
logs = await monitoring_service.get_activity_logs(
|
|
limit=limit,
|
|
level=level,
|
|
start_date=start_date,
|
|
end_date=end_date
|
|
)
|
|
return {"logs": logs, "total": len(logs)}
|
|
|
|
|
|
@router.get("/database/stats")
|
|
async def get_database_stats(
|
|
current_user: User = Depends(get_current_active_user),
|
|
monitoring_service: MonitoringService = Depends(get_monitoring_service)
|
|
):
|
|
"""
|
|
Get MongoDB database statistics (admin only)
|
|
|
|
Includes database size, collections, indexes, etc.
|
|
"""
|
|
if current_user.role != "admin":
|
|
from fastapi import HTTPException, status
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="Only admins can view database statistics"
|
|
)
|
|
|
|
stats = await monitoring_service.get_database_stats()
|
|
return stats
|
|
|
|
|
|
@router.get("/database/collections")
|
|
async def get_collection_stats(
|
|
current_user: User = Depends(get_current_active_user),
|
|
monitoring_service: MonitoringService = Depends(get_monitoring_service)
|
|
):
|
|
"""
|
|
Get statistics for all collections (admin only)
|
|
|
|
Includes document counts, sizes, and index information
|
|
"""
|
|
if current_user.role != "admin":
|
|
from fastapi import HTTPException, status
|
|
raise HTTPException(
|
|
status_code=status.HTTP_403_FORBIDDEN,
|
|
detail="Only admins can view collection statistics"
|
|
)
|
|
|
|
collections = await monitoring_service.get_collection_stats()
|
|
return {"collections": collections, "total": len(collections)}
|
|
|
|
|
|
@router.get("/pipelines/performance")
|
|
async def get_pipeline_performance(
|
|
hours: int = Query(24, ge=1, le=168, description="Number of hours to look back"),
|
|
current_user: User = Depends(get_current_active_user),
|
|
monitoring_service: MonitoringService = Depends(get_monitoring_service)
|
|
):
|
|
"""
|
|
Get pipeline performance metrics
|
|
|
|
Shows success rates, error counts, and activity for each pipeline
|
|
"""
|
|
performance = await monitoring_service.get_pipeline_performance(hours=hours)
|
|
return performance
|
|
|
|
|
|
@router.get("/errors/summary")
|
|
async def get_error_summary(
|
|
hours: int = Query(24, ge=1, le=168, description="Number of hours to look back"),
|
|
current_user: User = Depends(get_current_active_user),
|
|
monitoring_service: MonitoringService = Depends(get_monitoring_service)
|
|
):
|
|
"""
|
|
Get summary of recent errors
|
|
|
|
Shows error counts and recent error details
|
|
"""
|
|
summary = await monitoring_service.get_error_summary(hours=hours)
|
|
return summary
|
|
|
|
|
|
# =============================================================================
|
|
# Pipeline Monitor Proxy Endpoints
|
|
# =============================================================================
|
|
|
|
@router.get("/pipeline/stats")
|
|
async def get_pipeline_stats(
|
|
current_user: User = Depends(get_current_active_user),
|
|
pipeline_client: PipelineClient = Depends(get_pipeline_client)
|
|
):
|
|
"""
|
|
Get pipeline statistics from Pipeline Monitor service
|
|
|
|
Returns queue status, article counts, and worker info
|
|
"""
|
|
return await pipeline_client.get_stats()
|
|
|
|
|
|
@router.get("/pipeline/health")
|
|
async def get_pipeline_health(
|
|
current_user: User = Depends(get_current_active_user),
|
|
pipeline_client: PipelineClient = Depends(get_pipeline_client)
|
|
):
|
|
"""
|
|
Get Pipeline Monitor service health status
|
|
"""
|
|
return await pipeline_client.get_health()
|
|
|
|
|
|
@router.get("/pipeline/queues/{queue_name}")
|
|
async def get_queue_details(
|
|
queue_name: str,
|
|
current_user: User = Depends(get_current_active_user),
|
|
pipeline_client: PipelineClient = Depends(get_pipeline_client)
|
|
):
|
|
"""
|
|
Get details for a specific pipeline queue
|
|
|
|
Returns queue length, processing count, failed count, and preview of items
|
|
"""
|
|
return await pipeline_client.get_queue_details(queue_name)
|
|
|
|
|
|
@router.get("/pipeline/workers")
|
|
async def get_pipeline_workers(
|
|
current_user: User = Depends(get_current_active_user),
|
|
pipeline_client: PipelineClient = Depends(get_pipeline_client)
|
|
):
|
|
"""
|
|
Get status of all pipeline workers
|
|
|
|
Returns active worker counts for each pipeline type
|
|
"""
|
|
return await pipeline_client.get_workers()
|