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:
- 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. - Por interfaz (Agente 2.22.0+, #262) —
IF_METRIC_REreconocesnmp_if_(in|out|errors|discards)_<ifIndex>yIF_VM_NAMESmapea asnmp_if_bandwidth_in_mbps/_out_mbps/_errors_per_min/_discards_per_min(nombres DISTINTOS de la interfaz principal — las gráficas existentes no cambian). - Dinámicas —
DYNAMIC_METRIC_REaceptasnmp_(extras|fast)_[a-z0-9_]{1,64}(claves de OID deVendorProfile.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)simetric_typecasa con el patrón por interfaz, si noNone.vm_name_for(metric_type: str) -> tuple[str, str | None] | None— resuelve cualquiermetric_typedel Agente a(nombre_vm, ifIndex_o_None), probando las tres categorías en orden (estática → por interfaz → dinámica). DevuelveNonesi 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 convm_name_for(); si devuelveNone, la rechaza (rejected += 1). El módulo re-exportaAGENT_TO_VM(comoMETRIC_TYPE_MAP),DYNAMIC_METRIC_RE(como_VALID_DYNAMIC_METRIC) ymap_interface_metricpara 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]]) ytests/monitoring/test_contrato_agente_cadencia.py(AGENT_TO_VM,vm_name_for— verifica que todometric_typeliteral que emiteterminal/agent/sentinel/*.pylo acepte este contrato). - No depende de nada más (
rede 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]]