Monitoreo y Observabilidad
Propósito y Alcance
Section titled “Propósito y Alcance”Este documento describe los sistemas de monitoreo y observabilidad del backend Orchestrator. El sistema implementa dos subsistemas complementarios:
Sistema de Auditoría Rastrea eventos de seguridad, acciones de usuario y mutaciones de datos para análisis forense.
Métricas de Rendimiento Recolecta datos de rendimiento de la aplicación utilizando instrumentación estilo Prometheus.
Ambos sistemas están diseñados para entornos de alto rendimiento con escrituras por lotes para minimizar la sobrecarga de I/O.
Arquitectura del Sistema
Section titled “Arquitectura del Sistema”La infraestructura de monitoreo consiste en dos servicios singleton que se integran en la pila de middleware de Express. Ambos servicios almacenan datos en memoria temporalmente y periódicamente los escriben a tablas PostgreSQL en la base de datos nostromo_command bajo el esquema monitoring.
Visión General
Section titled “Visión General”flowchart TB
%% =========================
%% Pila de Middleware Express
%% =========================
subgraph Express["Pila de Middleware Express"]
TrustProxy[trust proxy]
HTTPS[Redirección HTTPS]
Helmet[seguridad helmet]
Limiter[globalLimiter]
CORS[cors]
Morgan[registro morgan]
RequestMW[requestMiddleware]
MetricsMW[metricsMiddleware]
AuditMW[auditMiddleware]
Routes[Rutas API]
TrustProxy --> HTTPS
HTTPS --> Helmet
Helmet --> Limiter
Limiter --> CORS
CORS --> Morgan
Morgan --> RequestMW
RequestMW --> MetricsMW
MetricsMW --> AuditMW
end
%% =========================
%% Bases de datos
%% =========================
subgraph DBs["PostgreSQL <br/> (nostromo_command)"]
AuditDB[(monitoring.audit_log)]
MetricsDB[(monitoring.system_metrics)]
end
%% =========================
%% Sistema de Auditoría
%% =========================
subgraph AuditSys["Sistema de Auditoría"]
AuditLogger[AuditLogger Clase<br/>Singleton]
AuditAPI[API auditLog<br/>login/logout/insert/update/delete]
AuditBuffer[Cola en Memoria<br/>Buffer por Lotes]
AuditTimer[Temporizador Flush<br/>5s o 50 entradas]
AuditLogger --> AuditAPI
AuditAPI --> AuditBuffer
AuditBuffer --> AuditTimer
AuditTimer -->|Inserción por lotes| AuditDB
end
%% =========================
%% Sistema de Métricas
%% =========================
subgraph MetricsSys["Sistema de Métricas"]
MetricsCollector[MetricsCollector Clase<br/>Singleton]
MetricsAPI[API metrics<br/>incCounters/observeHistogram]
MetricsStore[Almacén en Memoria<br/>counters/gauges/histograms]
MetricsTimer[Temporizador Flush<br/>60s]
MetricsEndpoint[GET /metrics<br/>metricsHandler]
MetricsCollector -->|Métricas del sistema intervalo 30s| MetricsStore
MetricsAPI --> MetricsStore
MetricsStore --> MetricsTimer
MetricsTimer -->|Inserción por lotes| MetricsDB
MetricsCollector --> MetricsEndpoint
end
%% =========================
%% Conexiones entre sistemas
%% =========================
MetricsMW -->|Rastrear petición| MetricsCollector
AuditMW -->|Registrar mutación| AuditLogger
Routes -->|Llamadas explícitas| AuditAPI
Routes -->|Llamadas explícitas| MetricsAPI
AuditMW --> Routes
Puntos de Integración
Section titled “Puntos de Integración”Posición en la Pila de Middleware
Section titled “Posición en la Pila de Middleware”El middleware de monitoreo está posicionado estratégicamente en la pila de Express:
- Antes de Autenticación: Para capturar todos los intentos, incluidos fallos de login.
- Después de Request ID: Para asegurar trazabilidad.
- Métricas Antes de Auditoría: Para medir rendimiento “puro”.
Apagado Elegante
Section titled “Apagado Elegante”Ambos sistemas implementan apagado elegante para asegurar que los datos en buffer se persistan:
// Registrado al cargar el móduloprocess.on('beforeExit', async () => {await auditLogger.shutdown(); // Flush entradas de auditoría pendientesawait metrics.shutdown(); // Flush métricas pendientes});Patrones de Uso
Section titled “Patrones de Uso”Registro Explícito de Auditoría
Section titled “Registro Explícito de Auditoría”import { auditLog, extractAuditContext } from '@/lib/audit';
// Ejemplo: Registrar creación de empleadoconst ctx = extractAuditContext(req);await centralPool.query('INSERT INTO employees ...');auditLog.insert('remuneraciones.employees', newEmployee, ctx);Métricas Personalizadas
Section titled “Métricas Personalizadas”// Ejemplo: Rastrear cálculos de nóminaconst timer = createTimer();const result = await payrollEngine.calculate(input);timer.observe('payroll_calculation_duration_ms', {employee_count: input.employees.length});