Files
bakery-ia/services/alert_processor/app/main.py
2025-12-05 20:07:01 +01:00

138 lines
3.1 KiB
Python

"""
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
)