CreaRack-SL

monitoring/metric_names.py — contrato único de nombres de métrica (Agente → VictoriaMetrics)

Propósito

Archivo: monitoring/metric_names.py (72 LOC, nuevo · A46 fase 1, auditoría #261, PR #441, commit d48b681a, v1.85.4, 2026-08-27).

Es el único sitio donde se declara el mapeo metric_type que emite el Local Agent → nombre de serie que se escribe en VictoriaMetrics. Antes de este cambio ese mapa (METRIC_TYPE_MAP) vivía inline dentro de receive_bulk_metrics en terminal/api/sentinel_ingest.py, y tests/monitoring/test_metrics_read_write_contract.py lo leía con una expresión regular sobre el código fuente. Ese patrón — una capa declara el nombre, otra lo lee con una copia o un regex — fue la causa raíz de los incidentes #259 y #213 (“una capa escribe un nombre y otra lee otro”). Este módulo cierra esa clase de fallo: el ingest (terminal/api/sentinel_ingest.py) y los tests de contrato (ver [[entity—monitoring—test—metrics-read-write-contract]]) importan la misma tabla, en vez de cada uno tener su propia copia o rascar el código del otro.

Fase 2 pendiente (sin fecha): que los lectores (monitoring/services/metrics_reader.py, monitoring/api/*.py) usen estas constantes en vez de literales sueltos, y exponer la tabla a JS (hoy el frontend no la consume, solo el backend).

Contrato (firma pública)

Tres tipos de métrica según cómo el Agente compone el metric_type:

  1. Estáticas — AGENT_TO_VM: dict[str, str]. Nueve pares fijos (ping_latency, ping_loss, ping_reachable, tcp_up, tcp_latency, snmp_in/out/errors/discards) → nombre de serie VM.
  2. Por interfaz (Agente 2.22.0+, #262) — IF_METRIC_RE reconoce snmp_if_(in|out|errors|discards)_<ifIndex> y IF_VM_NAMES mapea a snmp_if_bandwidth_in_mbps / _out_mbps / _errors_per_min / _discards_per_min (nombres DISTINTOS de la interfaz principal — las gráficas existentes no cambian).
  3. Dinámicas — DYNAMIC_METRIC_RE acepta snmp_(extras|fast)_[a-z0-9_]{1,64} (claves de OID de VendorProfile.monitoring_oids/fast_poll_oids). El acotamiento a 64 caracteres y al prefijo esperado es una barrera de seguridad: sin ella, un Agente comprometido podría fabricar series arbitrarias e inflar el índice de VictoriaMetrics (retención de 180 días).

Funciones:

  • map_interface_metric(metric_type: str) -> tuple[str, str] | None — (nombre_vm, ifIndex) si metric_type casa con el patrón por interfaz, si no None.
  • vm_name_for(metric_type: str) -> tuple[str, str | None] | None — resuelve cualquier metric_type del Agente a (nombre_vm, ifIndex_o_None), probando las tres categorías en orden (estática → por interfaz → dinámica). Devuelve None si no pertenece al contrato — es lo que usa el ingest para rechazar una métrica desconocida.
  • vm_names_written() -> set[str] — unión de todos los nombres de serie con productor declarado (AGENT_TO_VM.values() | IF_VM_NAMES.values()); la usan los tests de contrato en vez de rascar el código fuente.

Dependencias

  • Lo consume: terminal/api/sentinel_ingest.py (receive_bulk_metrics) — resuelve cada métrica del lote con vm_name_for(); si devuelve None, la rechaza (rejected += 1). El módulo re-exporta AGENT_TO_VM (como METRIC_TYPE_MAP), DYNAMIC_METRIC_RE (como _VALID_DYNAMIC_METRIC) y map_interface_metric para no romper otros imports existentes.
  • Lo importan los tests: tests/monitoring/test_metrics_read_write_contract.py (vm_names_written, AGENT_TO_VM — ver [[entity—monitoring—test—metrics-read-write-contract]]) y tests/monitoring/test_contrato_agente_cadencia.py (AGENT_TO_VM, vm_name_for — verifica que todo metric_type literal que emite terminal/agent/sentinel/*.py lo acepte este contrato).
  • No depende de nada más (re de la librería estándar, sin imports de Django).

Ejemplo de uso

from monitoring.metric_names import vm_name_for

vm_name_for("ping_latency")          # ("ping_latency_ms", None)
vm_name_for("snmp_if_in_3")          # ("snmp_if_bandwidth_in_mbps", "3")
vm_name_for("snmp_extras_noise_floor_1")  # ("snmp_extras_noise_floor_1", None)
vm_name_for("algo_inventado")        # None → el ingest rechaza la métrica

Véase también

  • [[entity—monitoring—test—metrics-read-write-contract]]
  • [[entity—terminal—service—sentinel-ingest]]
  • [[entity—monitoring—service—metrics-reader]]
  • [[entity—monitoring—service—metrics-writer]]
  • [[entity—terminal—endpoint—agent-metrics-bulk]]
  • [[concept—observability—metricas-victoria-metrics]]
  • [[feature—monitoring—bandwidth-snmp-por-interfaz]]