Plan2026/10-decision-observabilidad.md

576 lines
31 KiB
Markdown

# Decision: Capa de observabilidad avanzada (punto 7)
## Contexto
Las Capas 1-6 proporcionan toda la telemetría: métricas (VictoriaMetrics), logs (Loki), seguridad (Wazuh), inventario (Netbox), alertas (Alertmanager → Telegram). La Capa 7 trata de qué hacemos con esos datos más allá de reaccionar a alertas: visibilidad por cliente, medición de niveles de servicio, planificación de capacidad, informes y correlación.
No introduce herramientas nuevas. Todo se construye sobre Grafana + VictoriaMetrics + Loki + Netbox ya desplegados.
5 subcapas:
- 7.1 Dashboards por cliente
- 7.2 SLOs/SLIs (niveles de servicio)
- 7.3 Capacity planning (planificación de capacidad)
- 7.4 Status page e informes para clientes
- 7.5 Correlación avanzada (métricas + logs + seguridad)
---
## 7.1 Dashboards por cliente
### El problema
Hoy para ver el estado de un cliente hay que:
1. Entrar en Grafana → buscar métricas del PVE donde están sus VMs
2. Entrar en PBS → buscar su datastore y ver si los backups están bien
3. Entrar en Wazuh → filtrar eventos por sus hosts
4. Entrar en Netbox → buscar qué tiene contratado
Para un técnico de soporte con un ticket abierto, esto son 4 herramientas y 5 minutos antes de saber qué pasa. Multiplicado por 50+ clientes.
### DECISION 7.1 (confirmada)
**Dashboard Grafana por cliente**: una vista única que muestra todo lo relevante de un cliente.
#### Contenido del dashboard
```
┌─────────────────────────────────────────────────────────┐
│ CLIENTE: ACME Corp [Último refresh: 2m] │
├─────────────────────────────────────────────────────────┤
│ │
│ 📊 RESUMEN │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ VMs: 5/5 UP │ │ Backups: OK │ │ Storage: 234/600│ │
│ │ │ │ Último: 3h │ │ GB (39%) │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
│ │
│ 🖥️ VMs │
│ ┌──────────┬───────┬─────────┬──────────┬───────────┐ │
│ │ VM │ CPU │ RAM │ Disco │ Estado │ │
│ ├──────────┼───────┼─────────┼──────────┼───────────┤ │
│ │ web-01 │ 12% │ 2.1/4GB │ 18/50GB │ ✅ UP │ │
│ │ db-01 │ 45% │ 7.2/8GB │ 42/100GB │ ✅ UP │ │
│ │ mail-01 │ 3% │ 1.1/2GB │ 8/20GB │ ✅ UP │ │
│ │ app-01 │ 28% │ 3.5/4GB │ 22/50GB │ ✅ UP │ │
│ │ gw-01 │ 1% │ 0.3/1GB │ 2/10GB │ ✅ UP │ │
│ └──────────┴───────┴─────────┴──────────┴───────────┘ │
│ │
│ 💾 BACKUPS (PBS1) │
│ ┌──────────┬──────────────┬────────┬────────────────┐ │
│ │ VM │ Último backup│ Tamaño │ Verify │ │
│ ├──────────┼──────────────┼────────┼────────────────┤ │
│ │ web-01 │ Hoy 03:15 │ 12 GB │ ✅ OK (hace 5d)│ │
│ │ db-01 │ Hoy 03:22 │ 38 GB │ ✅ OK (hace 3d)│ │
│ │ mail-01 │ Hoy 03:18 │ 6 GB │ ✅ OK (hace 7d)│ │
│ │ app-01 │ Hoy 03:20 │ 15 GB │ ✅ OK (hace 2d)│ │
│ │ gw-01 │ Hoy 03:16 │ 1 GB │ ✅ OK (hace 6d)│ │
│ └──────────┴──────────────┴────────┴────────────────┘ │
│ │
│ 📈 STORAGE PBS │
│ [███████████████░░░░░░░░░░░░░░░░░░░░░░░] 39% (234/600) │
│ Tendencia: +2.1 GB/semana → lleno en ~174 semanas │
│ │
│ 🔄 SYNC PBS2 (archivo) │
│ Última sincronización: Hoy 06:00 ✅ │
│ Snapshots en PBS2: 16 (7d + 4w + 5m) │
│ │
│ 🔒 SEGURIDAD (últimas 24h) │
│ Eventos Wazuh: 23 (todos nivel bajo) │
│ Alertas activas: 0 │
│ │
│ 🌐 CONECTIVIDAD │
│ WG Hub: ✅ conectado (handshake hace 47s) │
│ DNS: ✅ resolviendo │
│ Servicios publicados: portal.acme.com ✅ (200 OK) │
│ │
└─────────────────────────────────────────────────────────┘
```
#### Implementación técnica
El dashboard usa **variables de Grafana** para filtrar por cliente:
```
Variable: $customer
Type: Query
Data source: VictoriaMetrics
Query: label_values(pbs_datastore_size_bytes, datastore)
O bien: API de Netbox (plugin Grafana-Netbox)
```
Cada panel filtra por el cliente seleccionado:
```promql
# VMs del cliente (PVE exporter, filtrado por tags de Netbox)
pve_guest_info{name=~"$customer.*"}
# Storage PBS
pbs_datastore_used_bytes{datastore="$customer"}
pbs_datastore_size_bytes{datastore="$customer"}
# Último backup
pbs_snapshot_timestamp{datastore="$customer"}
# Eventos Wazuh (via Loki)
count_over_time({job="wazuh"} |= "$customer" [24h])
```
La relación VM↔cliente viene de Netbox (custom field `tenant`). El plugin `grafana-netbox-datasource` permite usar Netbox como data source de variables.
#### Un dashboard, todos los clientes
No se crea un dashboard por cliente. Es **un solo dashboard con variable dropdown**. El técnico selecciona "ACME" y ve todo de ACME. Selecciona "BETA" y ve todo de BETA.
Para clientes con acceso a Grafana (futuro): Grafana Organizations + RBAC limita cada cliente a ver solo sus datos.
#### Prioridad
| Paso | Qué | Cuándo |
|------|-----|--------|
| Construir dashboard base con paneles de VMs y backups | Mes 1 |
| Añadir storage PBS y tendencia | Mes 1 |
| Añadir sync PBS2 y verify | Mes 2 |
| Añadir seguridad (Wazuh) y conectividad (WG) | Mes 2-3 |
| Integrar variable de Netbox (automático al añadir clientes) | Mes 2 |
---
## 7.2 SLOs/SLIs (niveles de servicio medibles)
### El problema
Hoy se dice al cliente "tus backups se hacen diariamente" pero no se mide. Si un backup falla 3 días seguidos y nadie mira, no se sabe. Cuando el cliente pregunta "¿cuál ha sido mi uptime este mes?" la respuesta es "no sé, creo que bien".
Sin métricas de nivel de servicio:
- No puedes definir SLAs con datos reales
- No sabes si estás cumpliendo lo que prometes
- No puedes detectar degradación gradual (funciona, pero cada vez peor)
- No tienes datos para justificar precio o mejoras
### DECISION 7.2 (confirmada)
**Definir SLIs medibles y trackearlos en Grafana.** No es necesario implementar un sistema de SLO formal (Google SRE style con error budgets). Es suficiente con métricas que respondan a las preguntas clave del negocio.
#### SLIs definidos
| SLI | Qué mide | Cómo se calcula | Objetivo |
|-----|----------|----------------|----------|
| **Backup freshness** | ¿El backup es reciente? | Tiempo desde último backup exitoso | < 24h |
| **Backup success rate** | ¿Los backups funcionan? | Backups exitosos / backups programados (30 días) | > 99% |
| **Verify pass rate** | ¿Los backups son íntegros? | Verificaciones OK / verificaciones ejecutadas | > 99.5% |
| **Sync freshness** | ¿PBS2 está al día? | Tiempo desde última sincronización exitosa | < 48h |
| **Storage headroom** | ¿Queda espacio? | % libre del quota del cliente | > 15% |
| **VM availability** | ¿Las VMs están UP? | Tiempo UP / tiempo total (30 días) | > 99.5% |
| **Restore time** | ¿Cuánto tarda un restore? | Tiempo medio de restore (medido en ejercicios) | < 2h |
#### Implementación en Grafana
```promql
# SLI: Backup freshness (horas desde último backup)
(time() - pbs_snapshot_timestamp{datastore="$customer"}) / 3600
# SLI: Backup success rate (últimos 30 días)
# Requiere recording rule que cuente éxitos/intentos
pbs_backup_success_total{datastore="$customer"}
/ pbs_backup_attempts_total{datastore="$customer"}
# SLI: VM availability (30 días)
avg_over_time(up{job="pve", instance=~"$customer.*"}[30d])
# SLI: Storage headroom
1 - (pbs_datastore_used_bytes{datastore="$customer"}
/ pbs_datastore_size_bytes{datastore="$customer"})
```
#### Panel SLO en Grafana
```
┌──────────────────────────────────────────────────┐
│ SLOs - ACME Corp - Marzo 2026 │
├──────────────────────────────────────────────────┤
│ │
│ Backup Freshness ████████████████████ 100% │
│ Objetivo: < 24h Actual: 3h ✅ │
│ │
│ Backup Success ████████████████████ 100% │
│ Objetivo: > 99% Actual: 30/30 días ✅ │
│ │
│ Verify Pass Rate ███████████████████░ 99.7% │
│ Objetivo: > 99.5% Actual: 1 warn en 30d ✅ │
│ │
│ Sync PBS2 ████████████████████ 100% │
│ Objetivo: < 48h Actual: 6h ✅ │
│ │
│ Storage Headroom █████████████░░░░░░░ 61% │
│ Objetivo: > 15% Actual: 366 GB libre ✅ │
│ │
│ VM Availability ████████████████████ 99.97% │
│ Objetivo: > 99.5% Actual: 12min down ✅ │
│ │
│ Score global: 6/6 SLOs cumplidos ✅ │
│ │
└──────────────────────────────────────────────────┘
```
#### Alertas de SLO
| Alerta | Condición | Severidad |
|--------|-----------|-----------|
| SLOBackupFreshnessBreach | Backup > 24h para cualquier VM | Critical |
| SLOBackupSuccessLow | Success rate < 99% en ventana 7d | Warning |
| SLOSyncFreshnessBreach | Sync PBS2 > 48h | Critical |
| SLOStorageHeadroomLow | Storage headroom < 15% | Warning |
| SLOVMAvailabilityLow | VM availability < 99.5% en ventana 7d | Warning |
Estas alertas son **adicionales** a las de infraestructura (Capa 1). Las de Capa 1 dicen "algo falla ahora". Las de SLO dicen "estamos incumpliendo lo que prometimos".
#### Prioridad
| Paso | Qué | Cuándo |
|------|-----|--------|
| Definir SLIs de backup (freshness + success) | Mes 1 |
| Panel SLO básico en Grafana | Mes 2 |
| Añadir SLIs de sync, verify, storage | Mes 2 |
| Añadir SLI de VM availability | Mes 3 |
| Recording rules para cálculos eficientes | Mes 3 |
---
## 7.3 Capacity planning (planificación de capacidad)
### El problema
- Un cliente llena su quota de PBS un viernes a las 22h no hay backups del fin de semana ticket el lunes
- Un pool ZFS llega al 80% rendimiento degrada todos los clientes del pool sufren
- Se contratan 10 clientes nuevos y no se sabe si caben en el PBS actual o hay que provisionar otro
Hoy se reacciona cuando algo se llena. Con datos de tendencia se puede **anticipar semanas antes**.
### DECISION 7.3 (confirmada)
**Dashboards de tendencia en Grafana con funciones de predicción de VictoriaMetrics.**
VictoriaMetrics tiene funciones nativas de predicción que Prometheus no tiene:
#### Predicción de llenado
```promql
# ¿Cuándo se llena el datastore de ACME?
# predict_linear: regresión lineal sobre los últimos 30 días
predict_linear(pbs_datastore_used_bytes{datastore="acme"}[30d], 86400*90)
# ¿Cuántos días quedan para llegar al 100% del quota?
(pbs_datastore_size_bytes{datastore="$customer"} - pbs_datastore_used_bytes{datastore="$customer"})
/ deriv(pbs_datastore_used_bytes{datastore="$customer"}[30d])
/ 86400
```
#### Panel de capacity planning
```
┌──────────────────────────────────────────────────────────┐
│ CAPACITY PLANNING - Todos los clientes │
├──────────────────────────────────────────────────────────┤
│ │
│ ⚠️ ATENCIÓN REQUERIDA (se llenan en < 60 días) │
│ ┌───────────┬──────────┬────────┬───────────────────┐ │
│ │ Cliente │ Usado │ Quota │ Días para llenarse│ │
│ ├───────────┼──────────┼────────┼───────────────────┤ │
│ │ DELTA │ 520/600 │ 87% │ ⚠️ 23 días │ │
│ │ GAMMA │ 380/500 │ 76% │ ⚠️ 45 días │ │
│ └───────────┴──────────┴────────┴───────────────────┘ │
│ │
│ ✅ SIN RIESGO (> 60 días) │
│ ┌───────────┬──────────┬────────┬───────────────────┐ │
│ │ ACME │ 234/600 │ 39% │ 174 días │ │
│ │ BETA │ 120/400 │ 30% │ 280 días │ │
│ │ ... (47 clientes más) │ │
│ └───────────────────────────────────────────────────┘ │
│ │
│ 📊 POOL ZFS GLOBAL │
│ pool9: 18.2 TB / 24 TB (76%) │
│ Tendencia: +120 GB/semana → lleno en ~48 semanas │
│ Recomendación: planificar ampliación antes del Q4 │
│ │
│ 📈 CRECIMIENTO POR CLIENTE (últimos 90 días) │
│ DELTA: +8.2 GB/semana (el que más crece) │
│ GAMMA: +5.1 GB/semana │
│ ACME: +2.1 GB/semana │
│ BETA: +1.3 GB/semana │
│ │
└──────────────────────────────────────────────────────────┘
```
#### Alertas de capacity
| Alerta | Condición | Severidad |
|--------|-----------|-----------|
| CapacityDatastoreFull30d | Datastore se llena en < 30 días (predicción) | Warning |
| CapacityDatastoreFull7d | Datastore se llena en < 7 días (predicción) | Critical |
| CapacityPoolFull90d | Pool ZFS se llena en < 90 días (predicción) | Warning |
| CapacityPoolFull30d | Pool ZFS se llena en < 30 días (predicción) | Critical |
Estas alertas permiten actuar **semanas antes**: contactar al cliente para ampliar quota, provisionar disco adicional, o redistribuir clientes entre pools.
#### Prioridad
| Paso | Qué | Cuándo |
|------|-----|--------|
| Panel básico de uso por cliente con tendencia | Mes 1-2 |
| Predicción de llenado (predict_linear) | Mes 2 |
| Alertas de capacity (30d, 7d) | Mes 2 |
| Panel de crecimiento por cliente | Mes 3 |
---
## 7.4 Status page e informes para clientes
### El problema
- El cliente no tiene visibilidad de su servicio: no sabe si sus backups funcionan, si su storage está bien, cuánto espacio le queda
- Cuando hay una incidencia, el cliente se entera porque algo no funciona, no porque se le haya comunicado
- No hay informes periódicos: "este mes todo fue bien" no tiene datos detrás
### DECISION 7.4 (confirmada)
**Dos herramientas, dos públicos, dos momentos:**
#### A) Status page per-client (tiempo real)
Cada cliente puede ver el estado actual de sus servicios. Dos opciones:
**Opción simple (mes 2): Grafana con permisos**
- Grafana Organizations: una org por cliente
- Dashboards de solo lectura con sus métricas
- SSO con Authentik (el cliente entra con su cuenta)
- Ve: VMs (UP/DOWN), backups (último, estado), storage (uso)
- No ve: métricas de otros clientes, infra interna
**Opción dedicada (mes 3+): página de diagnóstico custom**
Ya documentada en Capa 4.2: Flask/FastAPI ligero, SSO Authentik, detecta IP WG del cliente, muestra checks en tiempo real. Complementa el dashboard Grafana con tests activos (WG conectado, DNS resolviendo, certificado válido, PBS accesible).
#### B) Informes periódicos (mensuales)
Informe mensual generado automáticamente y enviado al cliente:
```
┌──────────────────────────────────────────────────┐
│ INFORME MENSUAL - ACME Corp - Marzo 2026 │
├──────────────────────────────────────────────────┤
│ │
│ RESUMEN EJECUTIVO │
│ ✅ Todos los SLOs cumplidos │
│ ✅ 0 incidencias de seguridad │
│ ✅ Storage en niveles saludables │
│ │
│ BACKUPS │
│ - Backups exitosos: 150/150 (100%) │
│ - Último verify: OK (12/03/2026) │
│ - Copia archivo (PBS2): sincronizada │
│ │
│ STORAGE │
│ - Uso actual: 234 GB / 600 GB (39%) │
│ - Crecimiento mes: +8.4 GB │
│ - Estimación llenado: 174 semanas │
│ │
│ DISPONIBILIDAD │
│ - Uptime VMs: 99.97% (12 min downtime) │
│ - Downtime planificado: 10 min (actualización) │
│ - Downtime no planificado: 2 min (reinicio red) │
│ │
│ SEGURIDAD │
│ - Eventos Wazuh: 687 (todos nivel informativo) │
│ - Alertas críticas: 0 │
│ - Vulnerabilidades parcheadas: 3 │
│ │
└──────────────────────────────────────────────────┘
```
Implementación:
```
Semaphore (cron mensual, día 1)
→ Playbook que consulta APIs:
- VictoriaMetrics (métricas del mes)
- Loki (eventos del mes)
- PBS API (backups, verify)
→ Genera PDF/HTML con template Jinja2
→ Envía por email o lo deja en Outline/Zammad
```
No es urgente. Es un diferenciador de servicio que se implementa cuando el stack está maduro.
#### Prioridad
| Paso | Qué | Cuándo |
|------|-----|--------|
| Grafana org por cliente (los que lo pidan) | Mes 3 |
| Página de diagnóstico custom | Mes 3+ |
| Template de informe mensual | Mes 4+ |
| Automatización de generación y envío | Mes 4+ |
---
## 7.5 Correlación avanzada (métricas + logs + seguridad)
### El problema
Las herramientas de las Capas 1-2 generan datos en silos:
- VictoriaMetrics tiene métricas (CPU, disco, red)
- Loki tiene logs (auth, syslog, PBS)
- Wazuh tiene eventos de seguridad (FIM, rootkits, vulnerabilidades)
Para investigar un incidente hay que saltar entre 3 herramientas y correlacionar mentalmente: "el disco subió a las 03:15, a ver qué hay en los logs a las 03:15, a ver si Wazuh detectó algo a las 03:15".
### DECISION 7.5 (confirmada)
**Grafana como panel de correlación único.** Grafana ya soporta múltiples data sources en el mismo dashboard y la misma vista temporal.
#### Dashboard de investigación
Un dashboard dedicado a investigar incidentes, con todos los data sources sincronizados en el mismo rango temporal:
```
┌─────────────────────────────────────────────────────────┐
│ INVESTIGACIÓN - Servidor: ns31787946 │
│ Rango temporal: [13/03/2026 02:00 - 04:00] │
├─────────────────────────────────────────────────────────┤
│ │
│ 📊 MÉTRICAS (VictoriaMetrics) │
│ CPU: ─────────────────╱╲───────────── pico 92% 03:12 │
│ IO: ────────────────╱──╲──────────── pico 03:12-03:18│
│ Disco:────────────────────/──────────── subió 2GB 03:15│
│ Red: ─────────────────────────────── normal │
│ │
│ 📝 LOGS (Loki) │
│ 03:10 [syslog] proxmox-backup: starting GC datastore X │
│ 03:12 [syslog] proxmox-backup: GC phase1 marking... │
│ 03:15 [syslog] zfs: pool9: io error on sda │
│ 03:15 [auth] sshd: Accepted key for root from 83.50… │
│ 03:16 [syslog] proxmox-backup: GC failed: IO error │
│ 03:18 [syslog] zfs: pool9: scrub repaired 4K │
│ │
│ 🔒 SEGURIDAD (Wazuh via Loki o API) │
│ 03:15 [level 7] File integrity: /var/log changed │
│ 03:15 [level 3] SSH login from known IP (informativo) │
│ │
│ CORRELACIÓN AUTOMÁTICA: │
│ → GC empezó a las 03:10 │
│ → Error de IO en disco sda a las 03:15 │
│ → GC falló por el error de IO │
│ → ZFS reparó el error (scrub) │
│ → El login SSH fue del técnico investigando │
│ → Conclusión: problema de disco, no seguridad │
│ │
└─────────────────────────────────────────────────────────┘
```
#### Cómo funciona en Grafana
Grafana tiene la funcionalidad **Explore** que permite:
- Seleccionar un rango temporal en una gráfica de métricas
- Ver automáticamente los logs de Loki del mismo período
- Usar **annotations** para marcar eventos de Wazuh en las gráficas de métricas
- **Split view**: métricas a la izquierda, logs a la derecha, sincronizados
```yaml
# Annotations automáticas en dashboards de métricas
# Marca eventos de Wazuh como líneas verticales en las gráficas
annotations:
- name: Wazuh Alerts
datasource: Loki
expr: '{job="wazuh"} |= "level" | json | level >= 10'
tagKeys: rule.description
textFormat: "{{rule.description}}"
```
#### Wazuh en Grafana
Dos opciones para tener datos de Wazuh en Grafana:
| Opción | Cómo | Pros | Contras |
|--------|------|------|---------|
| **Wazuh logs → Loki** | Alloy recoge logs de Wazuh Manager y los envía a Loki | Consultas LogQL en Grafana, mismo data source que otros logs | Requiere parsear formato Wazuh |
| **Wazuh API → Grafana** | Plugin Grafana o JSON datasource que consulta API de Wazuh | Datos estructurados, alertas con metadata | Plugin no oficial, mantenimiento |
**Recomendación**: Wazuh logs Loki (opción A). Los alertas de Wazuh van al JSON log de `/var/ossec/logs/alerts/alerts.json`. Alloy los recoge y envía a Loki con labels (level, rule_id, agent_name). Consultas LogQL funcionan directamente.
#### Prioridad
| Paso | Qué | Cuándo |
|------|-----|--------|
| Wazuh alerts.json Alloy Loki | Mes 1 (junto con despliegue Alloy) |
| Dashboard de investigación básico (métricas + logs) | Mes 2 |
| Annotations de Wazuh en dashboards de métricas | Mes 2 |
| Dashboard de investigación completo con correlación | Mes 3 |
---
## Resumen Capa 7 completa (DECISIONES FINALES)
```
┌─────────────────────────────────────────────────────┐
│ CAPA 7: OBSERVABILIDAD AVANZADA │
├─────────────────────────────────────────────────────┤
│ │
│ 7.1 DASHBOARDS POR CLIENTE (confirmada) │
│ ┌───────────────────────────────────┐ │
│ │ Un dashboard Grafana con │ │
│ │ variable dropdown por cliente │ │
│ │ - VMs, backups, storage, sync │ │
│ │ - Seguridad, conectividad │ │
│ │ - Variables desde Netbox │ │
│ └───────────────────────────────────┘ │
│ │
│ 7.2 SLOs/SLIs (confirmada) │
│ ┌───────────────────────────────────┐ │
│ │ Métricas de nivel de servicio │ │
│ │ - Backup freshness < 24h │ │
│ │ - Backup success > 99% │ │
│ │ - VM availability > 99.5% │ │
│ │ - Storage headroom > 15% │ │
│ │ - Sync freshness < 48h │ │
│ │ Panel SLO en Grafana │ │
│ └───────────────────────────────────┘ │
│ │
│ 7.3 CAPACITY PLANNING (confirmada) │
│ ┌───────────────────────────────────┐ │
│ │ Predicción de llenado │ │
│ │ - predict_linear (VictoriaM.) │ │
│ │ - Alertas: lleno en <30d, <7d │ │
│ │ - Crecimiento por cliente │ │
│ │ - Panel pool ZFS global │ │
│ └───────────────────────────────────┘ │
│ │
│ 7.4 STATUS PAGE + INFORMES (confirmada) │
│ ┌───────────────────────────────────┐ │
│ │ Grafana org per-client (mes 3) │ │
│ │ Página diagnóstico custom (3+) │ │
│ │ Informes mensuales auto (mes 4+)│ │
│ │ - Template Jinja2 → PDF/HTML │ │
│ │ - Envío automático por email │ │
│ └───────────────────────────────────┘ │
│ │
│ 7.5 CORRELACIÓN AVANZADA (confirmada) │
│ ┌───────────────────────────────────┐ │
│ │ Grafana como panel único de │ │
│ │ investigación │ │
│ │ - Métricas + Logs + Wazuh │ │
│ │ - Mismo rango temporal │ │
│ │ - Annotations de seguridad │ │
│ │ - Wazuh alerts → Loki │ │
│ └───────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────┘
Recursos Capa 7:
- Herramientas nuevas: NINGUNA
- Todo se construye sobre Grafana + VictoriaMetrics +
Loki + Wazuh + Netbox (ya desplegados en Capas 1-2)
- Coste: 0 (dashboards, queries, recording rules)
- Esfuerzo: configuración progresiva meses 1-4
```