""" Metrics collection for microservices """ import time import logging from typing import Dict, Any from prometheus_client import Counter, Histogram, Gauge, start_http_server from functools import wraps logger = logging.getLogger(__name__) # Prometheus metrics REQUEST_COUNT = Counter( 'http_requests_total', 'Total HTTP requests', ['method', 'endpoint', 'status_code', 'service'] ) REQUEST_DURATION = Histogram( 'http_request_duration_seconds', 'HTTP request duration in seconds', ['method', 'endpoint', 'service'] ) ACTIVE_CONNECTIONS = Gauge( 'active_connections', 'Active database connections', ['service'] ) TRAINING_JOBS = Counter( 'training_jobs_total', 'Total training jobs', ['status', 'service'] ) FORECASTS_GENERATED = Counter( 'forecasts_generated_total', 'Total forecasts generated', ['service'] ) class MetricsCollector: """Metrics collector for microservices""" def __init__(self, service_name: str): self.service_name = service_name self.start_time = time.time() def start_metrics_server(self, port: int = 8080): """Start Prometheus metrics server""" try: start_http_server(port) logger.info(f"Metrics server started on port {port}") except Exception as e: logger.error(f"Failed to start metrics server: {e}") def record_request(self, method: str, endpoint: str, status_code: int, duration: float): """Record HTTP request metrics""" REQUEST_COUNT.labels( method=method, endpoint=endpoint, status_code=status_code, service=self.service_name ).inc() REQUEST_DURATION.labels( method=method, endpoint=endpoint, service=self.service_name ).observe(duration) def record_training_job(self, status: str): """Record training job metrics""" TRAINING_JOBS.labels( status=status, service=self.service_name ).inc() def record_forecast_generated(self): """Record forecast generation metrics""" FORECASTS_GENERATED.labels( service=self.service_name ).inc() def set_active_connections(self, count: int): """Set active database connections""" ACTIVE_CONNECTIONS.labels( service=self.service_name ).set(count) def metrics_middleware(metrics_collector: MetricsCollector): """Middleware to collect metrics""" def middleware(request, call_next): start_time = time.time() response = call_next(request) duration = time.time() - start_time metrics_collector.record_request( method=request.method, endpoint=request.url.path, status_code=response.status_code, duration=duration ) return response return middleware