""" Alert Processor Service v2.0 Main FastAPI application with RabbitMQ consumer lifecycle management. """ from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from contextlib import asynccontextmanager import structlog from app.core.config import settings from app.consumer.event_consumer import EventConsumer from app.api import alerts, sse from shared.redis_utils import initialize_redis, close_redis # Configure structured logging structlog.configure( processors=[ structlog.processors.TimeStamper(fmt="iso"), structlog.processors.add_log_level, structlog.processors.JSONRenderer() ] ) logger = structlog.get_logger() # Global consumer instance consumer: EventConsumer = None @asynccontextmanager async def lifespan(app: FastAPI): """ Application lifecycle manager. Startup: Initialize Redis and RabbitMQ consumer Shutdown: Close consumer and Redis connections """ global consumer logger.info("alert_processor_starting", version=settings.VERSION) # Startup: Initialize Redis and start consumer try: # Initialize Redis connection await initialize_redis( settings.REDIS_URL, db=settings.REDIS_DB, max_connections=settings.REDIS_MAX_CONNECTIONS ) logger.info("redis_initialized") consumer = EventConsumer() await consumer.start() logger.info("alert_processor_started") except Exception as e: logger.error("alert_processor_startup_failed", error=str(e)) raise yield # Shutdown: Stop consumer and close Redis try: if consumer: await consumer.stop() await close_redis() logger.info("alert_processor_shutdown") except Exception as e: logger.error("alert_processor_shutdown_failed", error=str(e)) # Create FastAPI app app = FastAPI( title="Alert Processor Service", description="Event processing, enrichment, and alert management system", version=settings.VERSION, lifespan=lifespan, debug=settings.DEBUG ) # CORS middleware app.add_middleware( CORSMiddleware, allow_origins=["*"], # Configure appropriately for production allow_credentials=True, allow_methods=["*"], allow_headers=["*"], ) # Include routers app.include_router( alerts.router, prefix="/api/v1/tenants/{tenant_id}", tags=["alerts"] ) app.include_router( sse.router, prefix="/api/v1", tags=["sse"] ) @app.get("/health") async def health_check(): """ Health check endpoint. Returns service status and version. """ return { "status": "healthy", "service": settings.SERVICE_NAME, "version": settings.VERSION } @app.get("/") async def root(): """Root endpoint with service info""" return { "service": settings.SERVICE_NAME, "version": settings.VERSION, "description": "Event processing, enrichment, and alert management system" } if __name__ == "__main__": import uvicorn uvicorn.run( "app.main:app", host="0.0.0.0", port=8000, reload=settings.DEBUG )