New alert system and panel de control page
This commit is contained in:
@@ -1,11 +1,28 @@
|
||||
# shared/config/rabbitmq_config.py
|
||||
"""
|
||||
RabbitMQ configuration for the alert and recommendation system
|
||||
Supports both alerts and recommendations through a unified topic exchange
|
||||
RabbitMQ configuration for the event system
|
||||
|
||||
Supports three event classes through a unified topic exchange:
|
||||
- ALERT: Actionable events requiring user decision
|
||||
- NOTIFICATION: Informational state changes
|
||||
- RECOMMENDATION: AI-generated suggestions
|
||||
|
||||
Routing key pattern: {event_class}.{event_domain}.{severity}
|
||||
Examples:
|
||||
- alert.inventory.urgent
|
||||
- notification.production.info
|
||||
- recommendation.demand.medium
|
||||
"""
|
||||
|
||||
RABBITMQ_CONFIG = {
|
||||
"exchanges": {
|
||||
"events": {
|
||||
"name": "events.exchange",
|
||||
"type": "topic",
|
||||
"durable": True,
|
||||
"auto_delete": False
|
||||
},
|
||||
# Legacy exchange for backward compatibility during migration
|
||||
"alerts": {
|
||||
"name": "alerts.exchange",
|
||||
"type": "topic",
|
||||
@@ -20,19 +37,31 @@ RABBITMQ_CONFIG = {
|
||||
}
|
||||
},
|
||||
"queues": {
|
||||
"alert_processing": {
|
||||
"name": "alert.processing.queue",
|
||||
"event_processing": {
|
||||
"name": "event.processing.queue",
|
||||
"durable": True,
|
||||
"arguments": {
|
||||
"x-message-ttl": 3600000, # 1 hour TTL
|
||||
"x-max-length": 10000, # Max 10k messages
|
||||
"x-overflow": "reject-publish",
|
||||
"x-overflow": "reject-publish",
|
||||
"x-dead-letter-exchange": "dlx.exchange",
|
||||
"x-dead-letter-routing-key": "failed.events"
|
||||
}
|
||||
},
|
||||
# Legacy queue for backward compatibility
|
||||
"alert_processing": {
|
||||
"name": "alert.processing.queue",
|
||||
"durable": True,
|
||||
"arguments": {
|
||||
"x-message-ttl": 3600000,
|
||||
"x-max-length": 10000,
|
||||
"x-overflow": "reject-publish",
|
||||
"x-dead-letter-exchange": "dlx.exchange",
|
||||
"x-dead-letter-routing-key": "failed.items"
|
||||
}
|
||||
},
|
||||
"dead_letter": {
|
||||
"name": "alert.dead_letter.queue",
|
||||
"name": "event.dead_letter.queue",
|
||||
"durable": True,
|
||||
"arguments": {
|
||||
"x-message-ttl": 86400000 # 24 hours for dead letters
|
||||
@@ -40,43 +69,148 @@ RABBITMQ_CONFIG = {
|
||||
}
|
||||
},
|
||||
"bindings": [
|
||||
# New event architecture bindings
|
||||
{
|
||||
"queue": "event.processing.queue",
|
||||
"exchange": "events.exchange",
|
||||
"routing_key": "*.*.*" # event_class.event_domain.severity
|
||||
},
|
||||
# Legacy bindings for backward compatibility
|
||||
{
|
||||
"queue": "alert.processing.queue",
|
||||
"exchange": "alerts.exchange",
|
||||
"routing_key": "*.*.*" # alert/recommendation.severity.service
|
||||
},
|
||||
{
|
||||
"queue": "alert.dead_letter.queue",
|
||||
"queue": "event.dead_letter.queue",
|
||||
"exchange": "dlx.exchange",
|
||||
"routing_key": "failed.items"
|
||||
"routing_key": "failed.events"
|
||||
},
|
||||
{
|
||||
"queue": "event.dead_letter.queue",
|
||||
"exchange": "dlx.exchange",
|
||||
"routing_key": "failed.items" # Legacy
|
||||
}
|
||||
],
|
||||
"routing_patterns": {
|
||||
# alert/recommendation.severity.service_name
|
||||
"alert": "alert.{severity}.{service}",
|
||||
"recommendation": "recommendation.{severity}.{service}",
|
||||
# New event architecture patterns
|
||||
# event_class.event_domain.severity
|
||||
"alert_inventory": "alert.inventory.*",
|
||||
"alert_production": "alert.production.*",
|
||||
"alert_supply_chain": "alert.supply_chain.*",
|
||||
"notification_inventory": "notification.inventory.*",
|
||||
"notification_production": "notification.production.*",
|
||||
"notification_operations": "notification.operations.*",
|
||||
"recommendation_all": "recommendation.*.*",
|
||||
|
||||
# By severity
|
||||
"all_urgent": "*.*.urgent",
|
||||
"all_high": "*.*.high",
|
||||
"all_medium": "*.*.medium",
|
||||
"all_low": "*.*.low",
|
||||
|
||||
# By event class
|
||||
"all_alerts": "alert.*.*",
|
||||
"all_notifications": "notification.*.*",
|
||||
"all_recommendations": "recommendation.*.*",
|
||||
"urgent_items": "*.urgent.*",
|
||||
"high_items": "*.high.*"
|
||||
|
||||
# By domain
|
||||
"inventory_all": "*.inventory.*",
|
||||
"production_all": "*.production.*",
|
||||
"supply_chain_all": "*.supply_chain.*",
|
||||
"demand_all": "*.demand.*",
|
||||
"operations_all": "*.operations.*",
|
||||
|
||||
# Legacy patterns (for backward compatibility)
|
||||
"legacy_alert": "alert.{severity}.{service}",
|
||||
"legacy_recommendation": "recommendation.{severity}.{service}",
|
||||
}
|
||||
}
|
||||
|
||||
def get_routing_key(item_type: str, severity: str, service: str) -> str:
|
||||
"""Generate routing key for item publishing"""
|
||||
|
||||
def get_routing_key(event_class: str, event_domain: str, severity: str) -> str:
|
||||
"""
|
||||
Generate routing key for event publishing.
|
||||
|
||||
New pattern: {event_class}.{event_domain}.{severity}
|
||||
|
||||
Args:
|
||||
event_class: 'alert', 'notification', or 'recommendation'
|
||||
event_domain: 'inventory', 'production', 'supply_chain', 'demand', 'operations'
|
||||
severity: 'urgent', 'high', 'medium', 'low'
|
||||
|
||||
Returns:
|
||||
Routing key string
|
||||
|
||||
Examples:
|
||||
>>> get_routing_key('alert', 'inventory', 'urgent')
|
||||
'alert.inventory.urgent'
|
||||
>>> get_routing_key('notification', 'production', 'info')
|
||||
'notification.production.info'
|
||||
"""
|
||||
return f"{event_class}.{event_domain}.{severity}"
|
||||
|
||||
|
||||
def get_legacy_routing_key(item_type: str, severity: str, service: str) -> str:
|
||||
"""
|
||||
Generate legacy routing key for backward compatibility.
|
||||
|
||||
Legacy pattern: {item_type}.{severity}.{service}
|
||||
|
||||
TODO: Remove after migration is complete.
|
||||
"""
|
||||
return f"{item_type}.{severity}.{service}"
|
||||
|
||||
def get_binding_patterns(item_types: list = None, severities: list = None, services: list = None) -> list:
|
||||
"""Generate binding patterns for selective consumption"""
|
||||
|
||||
def get_binding_patterns(
|
||||
event_classes: list = None,
|
||||
event_domains: list = None,
|
||||
severities: list = None
|
||||
) -> list:
|
||||
"""
|
||||
Generate binding patterns for selective consumption.
|
||||
|
||||
Args:
|
||||
event_classes: List of event classes to bind (default: all)
|
||||
event_domains: List of event domains to bind (default: all)
|
||||
severities: List of severities to bind (default: all)
|
||||
|
||||
Returns:
|
||||
List of routing key patterns
|
||||
|
||||
Examples:
|
||||
>>> get_binding_patterns(['alert'], ['inventory'], ['urgent', 'high'])
|
||||
['alert.inventory.urgent', 'alert.inventory.high']
|
||||
"""
|
||||
patterns = []
|
||||
|
||||
item_types = item_types or ["alert", "recommendation"]
|
||||
|
||||
event_classes = event_classes or ["alert", "notification", "recommendation"]
|
||||
event_domains = event_domains or ["inventory", "production", "supply_chain", "demand", "operations"]
|
||||
severities = severities or ["urgent", "high", "medium", "low"]
|
||||
services = services or ["*"]
|
||||
|
||||
for item_type in item_types:
|
||||
for severity in severities:
|
||||
for service in services:
|
||||
patterns.append(f"{item_type}.{severity}.{service}")
|
||||
|
||||
return patterns
|
||||
|
||||
for event_class in event_classes:
|
||||
for event_domain in event_domains:
|
||||
for severity in severities:
|
||||
patterns.append(f"{event_class}.{event_domain}.{severity}")
|
||||
|
||||
return patterns
|
||||
|
||||
|
||||
def priority_score_to_severity(priority_score: int) -> str:
|
||||
"""
|
||||
Convert priority score (0-100) to severity level.
|
||||
|
||||
Args:
|
||||
priority_score: Priority score (0-100)
|
||||
|
||||
Returns:
|
||||
Severity level: 'urgent', 'high', 'medium', or 'low'
|
||||
"""
|
||||
if priority_score >= 90:
|
||||
return "urgent"
|
||||
elif priority_score >= 70:
|
||||
return "high"
|
||||
elif priority_score >= 50:
|
||||
return "medium"
|
||||
else:
|
||||
return "low"
|
||||
Reference in New Issue
Block a user