Probado en
Dónde se ejecutó, se midió o se comprobó cada parte de mikroscope: el equipo, la versión de
RouterOS, la fecha y las condiciones, lo que encontró cada ejecución y lo que no se ha probado. Las
guías dicen lo que hace la herramienta y enlazan aquí la prueba. Los veredictos de las funciones se
contrastaron con el código de la 1.2.0 y de la 1.2.2 el 2026-09-24, los apartados que vinieron de
las guías con el código de la 1.3.1 el 2026-09-26, y lo que esta página dice del código posterior a
la 1.3.1, que es el que publica la 1.4.0, con ese código el 2026-09-27, y sus apartados sobre la
publicación en Grafana, uninstall y las baterías de pruebas con el código de la 1.5.0 el mismo día;
la versión actual es la 1.6.1.
Hardware de referencia
Sección titulada «Hardware de referencia»Todas las cifras medidas en hardware de router que aparecen en esta documentación salen de un único MikroTik RB5009UG+S+: arm64, 4 × 1,4 GHz Cortex-A72 (r0p1), 1 GiB de RAM, Linux 5.6.3. Es el router de producción del mantenedor del proyecto, José Manuel Requena Plens, así que nada que necesite un reinicio se hace en él fuera de una ventana de mantenimiento, y no se le provoca ninguna tormenta de conntrack, que puede dejar sin acceso el camino por el que se está trabajando. No hay un segundo equipo físico. El único otro RouterOS que usa el proyecto es el laboratorio virtual. Qué RouterOS tenía en cada momento está en Equipos y versiones.
Kernel y PMU
Sección titulada «Kernel y PMU»- Ficheros de contabilidad (campaña
kernel-2026-09-11): no hay/proc/pressureni/proc/schedstat, y la columnairqde/proc/statvale siempre 0, así que el tiempo de IRQ hardware se cuenta dentro desystem.USER_HZes 100, un tick de 10 ms. - Trazado: un contenedor de descubrimiento privilegiado no encontró el 2026-09-12 ni eBPF, ni
kprobes, ni ftrace: ni BTF, ni debugfs, ni tracefs, y los puntos de montaje no existen. Una nueva
comprobación el 2026-09-14 encontró
/sys/fs/bpfpresente y vacío y/proc/modulescon 238 módulos cargados, pero ni/lib/modules, ni cabeceras del kernel, ni compilador en el equipo. - PMU, desde dentro de un contenedor privilegiado el 2026-09-12 (RouterOS 7.24.2): la prueba abrió
cycles,instructions,cache-misses,branch-missesybus-cyclesa nivel de sistema en 4 de 4 CPU. En los datos del propio agente de las 24 h que terminaron el 2026-09-12, seis de los siete contadores que pide informaron en 4 de 4 núcleos,cache-referencesentre ellos, ybranch-instructionsno produjo ninguna fila. Los eventos genéricosstalled-frontendystalled-backenddevuelvenENOENTen el A72. - El trabajo que el tick no ve: en una muestra de 100,4 ms en la que
/proc/statno marcó ningún tick ocupado en ninguno de los cuatro núcleos, la PMU contó entre 2,2 y 4,6 millones de ciclos y entre 0,8 y 2,1 millones de instrucciones ejecutadas, con una tasa de fallos de caché del 3,8–5,7 % (registrado el 2026-09-12). Durante 2 s ese mismo día, las instrucciones por ciclo fueron de 0,381 en cpu0 a 0,992 en cpu1. - Privilegios:
perf_event_paranoidvale 2 y no bloquea a un contenedor privilegiado, que conservaCAP_SYS_ADMINefectiva frente al host (medido el 2026-09-12). Un contenedor sin privilegios ya tiene las 38 capacidades, y su root corresponde al uid 32768 del host, así que/proc/slabinfoy/dev/kmsgdevuelvenEACCES(RouterOS 7.24.2; la fecha de estas dos lecturas no consta). Conprivileged=yes, el log del kernel,/proc/slabinfo, los contadores ECC de la MTD y la PMU se encontraron legibles el 2026-09-12 (RouterOS 7.24.2, kernel 5.6.3).
Sensores y relojes
Sección titulada «Sensores y relojes»/sys/class/hwmonestá vacío, incluso con privilegios. Las dos zonas térmicas,cpu-thermalysoc-thermal, son todo el conjunto de sensores del modelo base, y las dos se leen sin privileged. El/system/healthde RouterOS en esta placa informa de exactamente un sensor,cpu-temperature, que es la zonasoc-thermaltruncada a grados enteros: un desfase medio de +0,55 °C durante los 8 minutos en que existieron las dos series (2026-09-14).- Las dos zonas declaran un
polling_delayde 1 000 ms y unpolling-delay-passivede 250 ms (leído el 2026-09-14), así que el kernel vuelve a leer el sensor a 1 Hz. El punto de disparo crítico declarado es 105 °C, leído de/sys(la fecha no consta). El sensor cuantiza en escalones de unos 0,42 °C (floors-overnight). - El gobernador de cpufreq marcaba
userspaceel 2026-09-14, y los clusters de cpufreq, leídos derelated_cpusyaffected_cpusdentro del contenedor ese mismo día (RouterOS 7.24.2), son{0,1}y{2,3}.
Vista desde el contenedor
Sección titulada «Vista desde el contenedor»- Globales dentro del contenedor (establecido el 2026-09-11, RouterOS 7.24.2, kernel 5.6.3): los
ficheros de CPU, interrupciones, memoria y dispositivos de bloques, y
/proc/net/softnet_stat. Un contenedor normal leyó además como del router, el 2026-09-12: las dos zonas térmicas,scaling_cur_freqpor núcleo,/proc/yaffsy/proc/buddyinfo./proc/device-tree/modeldiceRB5009incluso sin privilegios. - Los del propio contenedor (campaña
netns-2026-09-12):/proc/net/dev,/proc/net/snmp,/proc/net/netstatynf_conntrack_countdescribían la veth del contenedor, 4 paquetes mientras el router reenviaba millones, yprivileged=yesno cambió eso. El resto de esa frontera:
| Qué | Lo que ve el contenedor | Leído |
|---|---|---|
/sys/class/net |
solo lo y la veth; ningún dispositivo para ningún puerto frontal, privilegiado o no |
2026-09-14 |
/sys/class/mdio_bus, /sys/class/phy |
mdio_bus solo contiene fixed-0; phy está vacío |
2026-09-14 |
netdev_budget, netdev_max_backlog y las demás entradas globales de net.core |
ausentes; las entradas por espacio de nombres, como somaxconn, están presentes |
2026-09-14 |
ficheros de /proc/net/* creados por módulos |
los del propio contenedor: fib_trie muestra solo el /30 de la veth, snmp6 cuenta sus paquetes |
2026-09-15 |
nf_conntrack_max |
el techo real del router, 966 656, el mismo que RouterOS informa como max-entries |
2026-09-14 |
| tiempos de expiración de conntrack | los valores por defecto de Linux (tcp_timeout_established 432 000 s frente al 1d de RouterOS) |
2026-09-14 |
Desliza en horizontal para ver todas las columnas
- Los montajes del host no cruzan la frontera: ver el hecho verificado del 2026-09-15.
- El registro de datos del equipo lleva los techos propios de la placa, nunca un número sacado de otro sitio: el techo de conntrack de 966 656 y el límite de memoria de 64 MiB del contenedor.
Almacenamiento
Sección titulada «Almacenamiento»nbd0–nbd15están presentes e inactivos ymtdblock0–2dan todo ceros (2026-09-12, RouterOS 7.24.2, kernel 5.6.3;internal/, el panel de E/S en curso de disco). La fila dedashboards/ panels.go /proc/yaffso de/proc/diskstatsde un dispositivo solo se guarda cuando su delta no es cero, lo que aquí ocurre unas pocas veces por minuto. El almacén InfluxDB de referencia seguía sin tabla de dispositivos de bloques, y sin tabla de PSI, el 2026-09-25, con RouterOS 7.24.4.- Los contadores ECC de la MTD están todos a cero tras años de servicio (la fecha de la lectura no consta).
/proc/slabinfoocupa 13 833 bytes y 129 líneas por lectura (2026-09-14), el mayor análisis por tick, un orden de magnitud por encima de cualquier otro.- El log del router tenía 66 217 filas cuando
recordlo leyó, porque su temadnsregistra a disco (la fecha no consta). - Tiene un disco tmpfs, que usa
--ephemeral. Su cortafuegos raw lleva las dos reglas de descartedefconf:de MikroTik en su forma de listas,in-interface-list=!LANysrc-address-list=!LANs(Listas del firewall).
Puertos e interfaces
Sección titulada «Puertos e interfaces»- Nombres del kernel frente a nombres de RouterOS
(Nombres de puertos):
eth1=ether2por el bucle de capa 2 del caso real (2026-09-13).eth5=ether6yeth6=ether7el 2026-09-15: los dos puertos están comentados comoUnusedy ninguno estabaRUNNING, así que cada uno se apagó y se volvió a encender por la API mientras el agente leía/dev/kmsg. El kernel registróbr0: port 7(eth5) entered disabled statedentro de la ventana deether6yport 7(eth6)dentro de la deether7, con nueve segundos entre ellas, lo que descarta leer dos veces el mismo apagado. No se interrumpió ningún tráfico y los dos puertos estaban de vuelta en menos de cuatro segundos. Los seis pares deducidos y el switch se apoyan en un/interface/de solo lectura del 2026-09-13: direcciones MAC consecutivas, deethernet/ print …:55paraether1a…:5Dparasfp-sfpplus1, en el orden de enumeración de RouterOS, y los nueve puertos declarandoswitch=switch1frente al únicoswitch0del kernel. El device tree, analizado el 2026-09-14, muestra elethernet@0del SoC con tres MAC, soloeth0habilitada (el enlace de subida de 10 G) yeth1/eth2deshabilitadas; los nueve puertos del frontal son netdevs que el driver del switch crea en tiempo de ejecución. La tabla es la de esta placa, observada con RouterOS 7.24.2. - Las formas de registro del log del kernel para cada clase de suceso de puerto se vieron entre el 2026-09-12 y el 2026-09-15 (kernel 5.6.3).
- Inventario (2026-09-16, RouterOS 7.24.2): las tres lecturas de configuración devuelven 17
interfaces.
ether1es unetherde la listaLAN, puerto debridge, etiquetado «TrueNAS - High Performance Storage», MTU 9000;ether5es unetherdeWANque no está en ningún bridge, etiquetado «DIGI ONT»;PPPoE_DIGIespppoe-out,WAN, MTU 1480;VLAN_DIGIesvlan,WAN;wg_devicesywg_trasterosonwgenLAN,VPN;ether6yether7llevan el comentario «Unused». - Contadores: 9 puertos × 45 contadores, y 15 en cada interfaz bridge, VLAN, PPPoE, WireGuard,
veth o loopback, contados en las propias filas
mikroscope_del colector el 2026-09-24. La versión de RouterOS no se leyó con ellas; el router tenía 7.24.4 ese día.api_ ifcounters
Laboratorio virtual
Sección titulada «Laboratorio virtual»El Cloud Hosted Router de MikroTik bajo QEMU, en un contenedor Docker, en la máquina en la que se
construyó el laboratorio (x86_64, 12 núcleos, 27 GB de RAM, Docker 29.8, QEMU 10.0.13), aprovisionado
en una instantánea limpia con el paquete container y device-mode container=yes. Medido el
2026-09-26 con RouterOS 7.24.4 y la CLI y la imagen del agente 1.3.1 publicadas:
- CHR x86_64 con KVM: 2 núcleos, kernel
5.6.3-64. - CHR arm64 con la emulación TCG de QEMU,
cortex-a72, 2 vCPU, 1 GiB: kernel5.6.3, la arquitectura, la versión del kernel y el modelo de CPU del RB5009, a la velocidad del host.
Lo que muestra: corrección. Las órdenes de RouterOS que envía mikroscope y lo que responde
RouterOS, la lectura que hace doctor del router, que RouterOS elija y descargue la imagen de su
arquitectura, el arranque y la parada del contenedor, la detección de capacidades del agente, su
formato de muestra y su anillo. Las rutas de instalación que se ejecutaron allí están en
Rutas de instalación probadas.
Cómo llega el laboratorio a sus agentes: por una ruta estática. El lado LAN del laboratorio,
192.168.88.10/24 dentro del contenedor del laboratorio, tiene su ruta por defecto por el puente de
Docker, no por el router, y llega a cada agente por 172.30.0.0/16 via 192.168.88.1, el valor por
defecto de LAB_AGENT_ROUTES: el prefijo más amplio de
Ruta estática. El 2026-09-27, la
172.30.10.0/30 por defecto y una instalación en 172.30.11.0/30 respondieron ambas a /healthz por
ella.
Lo que no puede mostrar:
- Una placa. No hay chip de switch, flash, sensores ni modelo en el device tree, así que no hay mapa
de puertos. Las
/capabilitiesdel agente dancpufreq,mtd,psi,schedstatythermalausentes en los dos,perfykmsgpresentes en los dos, yyaffsausente en x86_64 y presente en arm64, un/proc/yaffssin flash detrás. - Cadencias por encima de 10 Hz. La licencia gratuita de CHR limita lo que envía el router a
1 Mbit/s por interfaz: copiar 2 MiB desde el router por ether2 llevó 15,6 s, unos 1,07 Mbit/s,
frente a 0,2 s hacia él.
/streammidió 2 526 B por línea en el laboratorio, 0,21 Mbit/s a 10 Hz, así que 50 Hz está en el tope y 100 Hz por encima. No se midió ninguna de las dos. - Ningún coste en arm64. Con TCG el reloj del invitado sigue al del host, así que ninguna duración,
ninguna cifra de CPU (
cpu-load,self.cpu_us,read_ns,wake_ns, la dispersión dedt_ns,slipped), ninguna tasa de interrupciones, softirqs o cambios de contexto y ninguna cuenta de la PMU del laboratorio arm64 mide un Cortex-A72. El agente aguantó allí a 10 Hz, 3 003 ticks en 300,1 s con 1 retrasado y 1 202 en 120,1 s sin ninguno, y su tamaño residente de 14–16 MiB (32 MiB cargados a su cgroup) es solo orientativo.
Un bucle de rutas del propio laboratorio, ya corregido, hacía que el router emulado se arrastrara
cada vez que algo sondeaba una dirección de agente sin veth detrás: antes de la corrección, install
en arm64 tardó 38,4, 11,8 y 34,1 s, y el primero y el tercero salieron con 1 en una instalación
completa. Las cifras de arm64 de aquí son de después de la corrección; las de x86_64 se tomaron
antes. Lo que encontró allí la 1.3.1 está en
Problemas conocidos.
Tiempos del laboratorio
Sección titulada «Tiempos del laboratorio»En la máquina de arriba, desde la instantánea limpia. Cómo se ejecuta cada batería está en Baterías de pruebas.
- Un arranque desde la instantánea hasta que responde ssh, 2026-09-26: 7 s en x86_64 (6,9, 7,2, 7,4 y 7,4 s) y de 26 a 28 s en arm64 (25,7, 26,6, 27,0 y 27,5 s).
make roundtrip, 2026-09-26:doctor,install,status,upgradeyuninstall, cada orden con--ephemeral, y el/exportdel router resumido con un hash antes y después. De 28 a 34 s en x86_64 en tres ejecuciones y de 40 a 45 s en arm64 en cuatro, con el export idéntico byte a byte todas las veces. Con el código de la 1.4.0, que hace un solo intento deuninstall, el 2026-09-27: 20 s en x86_64 y 35 s en arm64, una ejecución de cada una con los pasos de compilación de make incluidos, con el export idéntico byte a byte. Con el código de la 1.5.0 el mismo día: 21 s en x86_64 y 30 s en arm64, medidos igual, con el export idéntico byte a byte.make test-labcon los escenarios de la 1.3.1, 2026-09-26: de 7 min 21 s a 9 min 49 s en x86_64 en seis ejecuciones y de 12 min 12 s a 16 min 48 s en arm64 en tres, las más lentas de cada una con las dos baterías en paralelo en un anfitrión ocupado. Ninguna instalación falló.make test-labcon los escenarios de las opciones de instalación, con el código posterior a la 1.3.1, 2026-09-27: 28 min 32 s en x86_64 sola, y después 28 min 17 s en x86_64 y 57 min 29 s en arm64 en paralelo. Tras las correcciones que pidió la revisión, 29 min 2 s y 57 min 13 s en paralelo, con todas las pruebas superadas; las veinte desinstalaciones de S9 con un cliente en/stream, diez por arquitectura, quedaron limpias al primer intento, en 8,0 a 12,6 s. Ese mismo día S17 se ejecutó en un laboratorio CHR x86_64 con RouterOS 7.23.7: adoctorle faltóRouterOS 7.24 or latery leyó todas las demás comprobaciones.- RouterOS 7.24.4 cambia su propio
/export: añade y quita por su cuenta una línea/system keymat-provider … name=default, así que la comparación de la batería deja esa línea fuera (2026-09-26).
Corte de corriente tras instalar
Sección titulada «Corte de corriente tras instalar»El 2026-09-26, un corte de corriente hecho en cuanto una instalación recién hecha respondió no
devolvió ningún agente en 90 s en tres de cuatro intentos en el laboratorio arm64. Los dos
contenedores que se miraron no podían arrancar (Exec format error, Segmentation fault), muy
probablemente porque RouterOS aún no había escrito la instalación en su disco; eso no se examinó. En
x86_64 volvieron tres de tres. El escenario del arranque con el router, S7, espera 45 s entre la
instalación y su corte, y solo pregunta si ese arranque funciona. S6 corta la corriente bajo una
instalación --ephemeral en el disco tmpfs del laboratorio: después el contenedor sigue configurado y
detenido, su raíz, su imagen y el manifiesto se han ido con el contenido del disco, el disco sigue ahí
y vacío, y nada responde; uninstall --ephemeral no deja después nada en absoluto. Pasó en las dos
arquitecturas en las ejecuciones del 2026-09-27.
Detecciones de reinicio
Sección titulada «Detecciones de reinicio»El 2026-10-05, en el laboratorio x86_64 (CHR, RouterOS 7.24.4, KVM), el colector del código
posterior a la 1.5.0 ejecutó forward --api-mode off --stdout json a través de un reinicio hecho
con el propio /system/reboot de RouterOS, con el agente 1.5.0 instalado por la descarga de Docker
Hub y arranque con el sistema. El agente volvió a responder unos 20 s después del reinicio; el
colector registró agent restarted: its newest sample is 439 and the cursor was 1057; resuming from 1, y agent-restart saltó con su resumen de los 30 s anteriores: 300 muestras, CPU ocupada al 0 %,
MemAvailable 767,5 MiB de 863,0 MiB, nf_conntrack 24 de 843 776, ninguna caída en softnet y después
16,2 s sin muestras. reboot no saltó: ningún registro del log del kernel tras volver el agente
tenía un tiempo desde el arranque menor que el último de antes del reinicio. Una sola ejecución, en
un router en reposo.
Más tarde ese mismo día, en el mismo laboratorio, el agente y el colector del código posterior a la
1.5.0 que lee el identificador de arranque del kernel (el agente del tar de la rama, con arranque con
el sistema) ejecutaron siete minutos de forward --api-mode off --stdout json a través de una parada
y un arranque del contenedor del agente y después un /system/reboot. El agente dentro del
contenedor de RouterOS leyó el identificador y lo sirvió en /healthz. Tras /container/stop y
/container/start (20,6 s sin muestras) el identificador era el mismo, y agent-restart lo dijo:
the kernel's boot id did not change, so the router did not reboot; ningún reboot. Tras
/system/reboot (16,5 s sin muestras) el identificador era nuevo: el colector registró router rebooted: the kernel's boot id went from 30b9831d-… to 8d4e19f2-…, y agent-restart y reboot
saltaron con la primera muestra del agente con el mismo resumen (300 muestras, CPU ocupada al 0 %,
nf_conntrack 24 de 843 776, ninguna caída en softnet). El log del kernel del arranque nuevo no hizo
saltar un segundo reboot. Una ejecución de cada caso, en un router en reposo; el laboratorio arm64
no se ejecutó.
Lo que RouterOS escribe sobre un arranque se leyó esa misma tarde por la API, de /log/print, tras
cada forma de tumbar el laboratorio x86_64. Tras /system/reboot desde una sesión SSH su buffer de
memoria tenía router rebooted by ssh-cmd:admin@192.168.88.10/ (topics system,info); desde
un script, …/script:rb/reboot; tras /system/shutdown y un arranque, …/shutdown; tras quitar la
corriente (power-cycle), router was rebooted without proper shutdown (system,error,critical), y
lo mismo tras el system_reset de QEMU (reset-button). Con una acción de logging que mandaba
también el topic system a disco, un /log/print sin más devolvió además las líneas del arranque
anterior, y /log/print ?buffer=memory solo las de este.
Después el colector del código que lo lee (forward --api-mode slow --stdout json, con la capa de
API recibiendo las credenciales del laboratorio mediante LAB_CLI_API=lab) funcionó ocho minutos a
través de un /system/reboot y un reset-button. Las dos veces la lectura salió bien en la lectura
de salud que notó el identificador de arranque nuevo, antes de que la ronda propia de la capa de API
reconectara (la lectura reabrió la conexión), así que reboot saltó con la primera muestra del
agente, con RouterOS logged at boot: "router rebooted by ssh-cmd:admin@192.168.88.10/ la
primera vez y "router was rebooted without proper shutdown" la segunda, 19,4 s y 22,1 s sin
muestras. Una ejecución de cada caso; la espera de dos minutos a una API que no ha vuelto no se
ejercitó en un router, solo en las pruebas unitarias.
En el RB5009 (RouterOS 7.24.4), el agente 1.6.0 instalado el 2026-10-06 sirvió el identificador de
arranque del kernel en /healthz desde dentro de su contenedor. El agent-restart de esa
actualización dijo the kernel's boot id did not change, so the router did not reboot, que era
cierto pero no se sabía: el agente 1.5.0 anterior no daba ningún identificador. En el código
posterior a la 1.6.0 el primer agente que da un identificador después de uno que no lo daba no
afirma nada sobre el kernel.
Un power-cycle del laboratorio no sirve para probar el colector: reinicia el contenedor del
laboratorio, y un colector lanzado antes con mikroscope-lab cli conserva el espacio de red del
contenedor viejo y no alcanzó nada tras el corte (no route to host hasta que terminó, el mismo
día). El reinicio desde dentro conserva la red del laboratorio.
Avisos de exposición de doctor
Sección titulada «Avisos de exposición de doctor»El 2026-10-05, en el laboratorio x86_64 (CHR, RouterOS 7.24.4, KVM), el doctor del código
posterior a la 1.5.0 que añade los dos avisos se ejecutó contra el router del laboratorio preparado
de tres maneras. Con allow-remote-requests=yes y ninguna regla de cortafuegos, avisó the router does not answer DNS from its uplink (…, uplink ether1: no rule drops a query that comes in on it).
Con las dos reglas de input de la configuración por defecto (aceptar
established,, descartar in-interface-list=!LAN) añadidas diez segundos antes,
pasó, nombrando el descarte !LAN; con solo in-interface=ether1 protocol=udp dst-port=53 action=drop también pasó. Con una regla de filter cuya lista de interfaces se había quitado y una
regla de raw cuya veth se había quitado, nombró las dos bajo no firewall rule doctor reads is invalid or names a deleted list.
Lo que hace RouterOS con una regla cuya referencia desaparece se leyó por SSH el mismo día. Una lista
de interfaces quitada bajo una regla dejó la regla válida, con in-interface-list=!*2000010; crear
una lista con el mismo nombre no la cambió, y la regla contó paquetes como una regla que lo coge
todo puesta al lado. Un descarte !LAN que se quedó así en la cadena input cortó el SSH del propio
laboratorio desde la LAN hasta que se reinició el laboratorio. Una veth quitada bajo una regla dejó
la regla inválida (in-interface=*4, about=vprobe not ready), y no contó ningún paquete. Una
regla leída justo después de añadirla era inválida sin about, y válida cinco segundos después.
RouterOS no deja añadir una regla que nombra una lista que no existe (input does not match any value of interface-list).
Para la colocación de la solución: place-before=0 falló desde una sesión SSH de una sola orden
(no such item), y un place-before de la primera regla de la cadena input falló con la cadena vacía
y funcionó con una regla en ella. Sin probar: IPv6, y una consulta DNS enviada desde fuera del
laboratorio, cuyo enlace de subida es la red de usuario de QEMU; doctor lee las reglas y no envía
ningún paquete.
En el RB5009 (RouterOS 7.24.4, 2026-10-06), el doctor de la 1.6.0 leyó 80 reglas activas en raw
prerouting y en filter forward e input, ninguna inválida ni que nombrara una lista borrada, y dijo
que la comprobación de DNS no tenía enlace de subida que evaluar: la ruta por defecto activa del
router va por PPPoE, y su immediate-gw es la interfaz sola (PPPoE_DIGI), que la lectura del
enlace de subida no contemplaba; el enlace DHCP del laboratorio se lee 10.0.2.2%ether1. Con esa
lectura corregida, el código posterior a la 1.6.0 encontró PPPoE_DIGI en la lista WAN y evaluó
las consultas como un quizá, porque la regla accept to local loopback (for CAPsMAN) de la
configuración por defecto, dst-address=127.0.0.1, va antes de su drop all not coming from LAN y
se leía como una aceptación posible. Tomando un destino de loopback como no coincidente para un
paquete que llega de Internet, nombró defconf: drop all not coming from LAN como la regla que
descarta las consultas. Cada una de las tres ejecuciones fue una sola conexión de lectura.
RouterOS x86 desde la ISO
Sección titulada «RouterOS x86 desde la ISO»El laboratorio opcional que instala RouterOS x86 desde la ISO de MikroTik se ejecutó el 2026-09-26
con RouterOS 7.24.4. El router informó de la placa x86 QEMU Standard PC (Q35 + ICH9, 2009) y de
una licencia de prueba sin nivel y con 24 horas por delante. La CLI 1.3.1 y el agente de la rama del
laboratorio se comportaron como en CHR x86_64: a doctor le faltaron las mismas dos listas, una
instalación desde el tar respondió al momento, status reconoció todos los objetos y uninstall
verificó el router limpio, dejando el mismo directorio mikroscope vacío. Las /capabilities del
agente fueron las de CHR x86_64.
Ejecuciones en la CI
Sección titulada «Ejecuciones en la CI»El flujo se ejecutó por primera vez en los runners de GitHub el 2026-09-26, como el trabajo del
laboratorio de la CI en el pull request #69: cuatro ejecuciones x86_64 entre las 21:06 UTC de ese día
y las 00:45 UTC del 2026-09-27, cada una con las diez pruebas que tenía entonces la batería superadas
(de 471,7 a 485,8 s) en un trabajo de 10 min 30 s a 13 min 30 s. De las tres ejecuciones de abajo,
las dos primeras tenían la caché vacía, así que make lab-up descargó RouterOS y lo aprovisionó; la
tercera tomó las descargas de la caché y aprovisionó una instantánea nueva.
| Ejecución | Commit | Runner | make lab-up |
Batería | Trabajo |
|---|---|---|---|---|---|
| arm64, a petición sobre main | e7efbbe, el laboratorio tal como se fusionó |
ubuntu-latest: 4 CPU, 15 989 MB, /dev/kvm presente |
4 min 29 s: aprovisionamiento 83 s, un arranque de la instantánea 24 s | 638,6 s, las diez pruebas de ese commit superadas | 16 min 24 s |
| x86_64, pull request #70 | 3c34d9a, las opciones de instalación |
ubuntu-latest: 4 CPU, 15 989 MB, /dev/kvm usado por KVM |
4 min 28 s: aprovisionamiento 46 s, un arranque de la instantánea 8 s | 1 591,4 s (26 min 31 s), todas las pruebas superadas; S17 omitida, porque necesita un RouterOS anterior a 7.24 | 32 min 42 s |
| x86_64, pull request #70 | 1826aa5, con la credencial de registro |
ubuntu-latest, /dev/kvm usado por KVM |
1 min 25 s: las descargas desde la caché, aprovisionamiento 76 s | 1 633,1 s (27 min 13 s), todas las pruebas superadas; S17 omitida. El router descargó como la cuenta de Docker Hub del repositorio, S2 incluida; S1, S18 y los scripts de Docker Hub y de GHCR de S5 arrancaron sin ella | 29 min 52 s |
Desliza en horizontal para ver todas las columnas
En las dos primeras de esas ejecuciones se cortó una descarga desde MikroTik
(connection reset by peer) y se reanudó al primer reintento. La sonda de KVM en el runner arm64 de
GitHub encontró ubuntu-24.04-arm con 4 CPU y sin /dev/kvm, así que el laboratorio arm64 sigue
emulado en un runner x86_64.
Las dos ejecuciones en el pull request #70 lo retuvieron 30 y 33 min, y por eso lab.yml se ejecuta ahora
solo cada semana y a petición, nunca en un pull request ni antes de una publicación.
En el commit de la publicación 1.4.0 (79b7c2f, una ejecución a petición el 2026-09-27, run
36329638066) la batería entera pasó en las dos arquitecturas: 1 517,2 s en x86_64 en un trabajo de
31 min 38 s, y 3 042,6 s en arm64, emulado, en un trabajo de 54 min 52 s. La imagen del agente 1.4.0
aún no estaba publicada, así que los trece casos de referencia que descargan su imagen descargaron la
de la 1.3.1, como hace S5 antes de una etiqueta y dice en su registro.
En el commit de la publicación 1.5.0 (e61ffb6, una ejecución a petición el 2026-09-27, run
36344788569) la batería entera volvió a pasar en las dos arquitecturas: 1 573,2 s en x86_64 en un
trabajo de 31 min 38 s, y 3 065,8 s en arm64, emulado, en un trabajo de 54 min 55 s. Los trece casos
de referencia que descargan su imagen descargaron la de la 1.4.0, porque la de la 1.5.0 aún no
estaba publicada, como registró S5.
Equipos y versiones
Sección titulada «Equipos y versiones»| Equipo | Tipo | RouterOS | Cuándo | Qué se ejecutó allí |
|---|---|---|---|---|
| RB5009UG+S+ | hardware, arm64 | 7.24.1 | hasta la actualización del 2026-09-10 | el coste de una conexión SSH, 2026-08-26 |
| RB5009UG+S+ | hardware, arm64 | 7.24.2 | del 2026-09-10 a más o menos el 2026-09-18 22:43 UTC | la mayoría de las campañas, del 2026-09-11 al 2026-09-18 |
| RB5009UG+S+ | hardware, arm64 | 7.24.4 | desde más o menos el 2026-09-18 22:43 UTC | la campaña de errores de puerto, los tiempos de /stream, las gráficas del almacén de referencia y las órdenes de despliegue desde el 2026-09-21; upgrade con la 1.5.0 y la 1.6.0, doctor con la 1.6.0 |
| CHR x86_64, laboratorio virtual | virtual (KVM), amd64 | 7.24.4 | 2026-09-26 y 2026-09-27 | doctor, plan, tres rutas de instalación, --expose, uninstall con la 1.3.1; la batería entera del laboratorio con el código posterior y en el commit de la 1.4.0 |
| CHR arm64, laboratorio virtual | emulado (TCG), arm64 | 7.24.4 | 2026-09-26 y 2026-09-27 | doctor, plan, tres rutas de instalación, uninstall con la 1.3.1; la batería entera del laboratorio con el código posterior y en el commit de la 1.4.0 |
| CHR x86_64, laboratorio virtual | virtual (KVM), amd64 | 7.23.7 | 2026-09-27 | doctor, que rechaza un RouterOS anterior a 7.24 (S17) |
| RouterOS x86 desde la ISO, laboratorio virtual | virtual (KVM), amd64 | 7.24.4 | 2026-09-26 | doctor, una instalación desde el tar, status y uninstall con la 1.3.1 |
Desliza en horizontal para ver todas las columnas
Cuándo pasó el RB5009 a 7.24.4. La actualización en sí no quedó anotada, pero está acotada: la fecha de compilación de 7.24.4 es 2026-09-16 11:32:21; el 2026-09-24 el router informó de 7.24.4 con un uptime de 5d15h49m12s, un arranque hacia el 2026-09-18 22:43 UTC; y una actualización de RouterOS lo reinició a las 00:43:30 CEST del 2026-09-19, las 22:43:30 UTC del día anterior, tras lo cual la capa del kernel se reanudó a las 00:45:03. El uptime de la capa de la API en el almacén de referencia crece al ritmo del reloj desde el 2026-09-19 a las 11:13:35 UTC. Así que el router tiene 7.24.4 desde ese arranque como tarde. Las campañas fechadas del 2026-09-16 al 2026-09-18 constan como 7.24.2; la cota ni lo confirma ni lo desmiente. Ninguna de las medidas de 7.24.2 se ha repetido sobre 7.24.4.
Lo que se ejecutó sobre 7.24.4. doctor, plan, install, status y uninstall el
2026-09-21, con el agente instalado funcionando de forma continua desde el 2026-09-19. El 2026-09-23
se reprodujo en solo lectura la forma 1.2.x del aviso de registro de doctor, y su aviso de token
con una instalación desechable que se expuso, se actualizó sin token y se retiró, así que upgrade
también se ha ejecutado allí. Ese mismo día doctor leyó 600 muestras del anillo del agente en
marcha y no encontró nada. El 2026-09-24 se le dio a RouterOS la referencia del agente con su host de
registro dentro de remote-image=
(dos hechos verificados). La capa de la API funciona sin
parar sobre 7.24.4 desde el 2026-09-19; sus lecturas de inventario y de claves de pérdidas y su
perfil de coste son de 7.24.2 (2026-09-15 y 16), y su prueba de reconexión y su A/B con 16
interfaces del 2026-09-19, tras la actualización de ese día, sin la versión anotada al lado.
Los ajustes del contenedor que escribe install se verificaron en el RB5009 con RouterOS 7.24.2
y se volvieron a ejercitar sobre 7.24.4; no se probó ninguna otra placa.
El agente del RB5009 se actualizó a 1.0.9 el 2026-09-19, a 1.2.0 a las 08:08:54 UTC del
2026-09-24 y a 1.2.1 y 1.2.2 ese mismo día, a 1.5.0 el 2026-09-27 y a 1.6.0 a las 07:15 UTC del
2026-10-06, cada vez con upgrade --remote-image; la última tardó 11,8 s desde la orden hasta la
respuesta de la sonda. Los tiempos de /stream del 2026-09-21 son del agente 1.0.9.
Plataformas
Sección titulada «Plataformas»De las cuatro plataformas que publica una versión, arm64 se ha ejecutado en hardware, el RB5009, y
emulada en el laboratorio. amd64 solo se ha ejecutado en el laboratorio, en el CHR x86_64 y en
RouterOS x86 desde la ISO, ambos bajo KVM, nunca en hardware x86. arm/v7 y arm/v5 nunca se han
ejecutado en RouterOS: se compilan de forma cruzada, y la CI arranca cada imagen con -version bajo
la emulación de modo usuario de QEMU (make agent-smoke), que no es RouterOS. Qué publica cada
versión, y qué números de versión nunca llegaron a publicarse, está en
Versiones.
Estado de las funciones
Sección titulada «Estado de las funciones»Todo lo siguiente se ejecutó contra el RB5009 salvo que diga la batería de contenedores o el laboratorio: con RouterOS 7.24.2 si está fechado hasta el 2026-09-18, y con 7.24.4 si está fechado desde el 2026-09-19 (Equipos y versiones). Cada parte empieza por su veredicto y la fecha que lo respalda.
El agente funciona en el RB5009: el instalado estaba en marcha allí el 2026-09-23, cuando doctor
leyó 600 muestras de su anillo. Lee /proc, /sys, /dev/kmsg y los contadores de
perf_event_open del kernel compartido con un temporizador fijo de 1 a 100 Hz (10 Hz por defecto;
10, 20, 50 y 100 Hz medidos), guarda las muestras en un
anillo y las sirve: /healthz, /capabilities, /snapshot, /stream, /sampler, y los endpoints
de captura por disparo /captures y /capture. No sirve ningún /metrics; la exposición es la del
colector.
Órdenes de despliegue
Sección titulada «Órdenes de despliegue»Las seis órdenes de despliegue se han ejecutado en el RB5009 con RouterOS 7.24.4, las seis a más
tardar el 2026-09-23, cada una con la CLI de su fecha. De la 1.4.0 en adelante solo se han
ejecutado allí upgrade (la 1.5.0 el 2026-09-27 y la 1.6.0 el 2026-10-06, la segunda leyendo el
manifiesto de instalación que escribió la primera) y doctor (1.6.0, 2026-10-06); el resto del
código posterior a la 1.3.1, que es el que publica la 1.4.0, solo se ha ejecutado en el laboratorio
virtual (2026-09-27). Según su código, la 1.5.0 no cambia ningún paso de las seis
órdenes en el router; su uninstall rechaza --grafana-dry-run y lista los objetivos de Grafana y
de los almacenes antes de tocar el router, ambas cosas comprobadas solo en pruebas unitarias
(uninstall --targets). doctor, plan, install, status, upgrade
y uninstall instalan, actualizan y retiran el agente, listando cada escritura antes de hacerla y
verificando cada retirada por recuento de propiedad.
- Ida y vuelta, 2026-09-12:
doctor→install→status→upgrade→uninstalldejó el/exportdel router idéntico byte a byte (verificado). El agente respondió 3 s después de la instalación, con un tiempo de ida y vuelta de 5–7 ms: dos sondeos, 7 ms trasinstally 5 ms trasupgrade, y el primero imprimiódirect transport ok: agent 4857d0a-dirty, 10 Hz, seq 29, 0 slipped, 7ms round trip. Es una instalación en una red, no una cifra para otra. La ejecución pasó--ephemeraladoctor,installyupgrade, y es anterior a 1.1.0, desde la queuninstallsolo retira con--yes.scripts/roundtrip.shpasa ahora--yesa su desinstalación (hasta 1.2.0 no lo hacía, así que ahí solo listaba y su comprobación del export fallaba) y--ephemerala todas las órdenes. En esa forma se ejecuta en el laboratorio comomake roundtrip(Tiempos del laboratorio), y no se ha ejecutado contra el RB5009, donde esmake roundtrip-device. - Rutas de instalación: cuatro rutas de principio a fin el 2026-09-17, y las del laboratorio el 2026-09-26, en Rutas de instalación probadas.
doctorpor sí solo lee además una vez el anillo del agente en marcha y nombra cuatro fallos que las herramientas de RouterOS no muestran: un bucle de capa 2, cambios continuos de STP, un enlace que cae y vuelve y descartes de softnet. Si ningún agente responde en 3 s lo dice y lo omite, y lo que encuentra nunca cambia el código de salida. El 2026-09-23 leyó 600 muestras y no encontró nada; los cuatro fallos los cubren pruebas que reproducen el texto real de los registros y la cadencia de 2,0 s del bucle del RB5009, no un fallo en vivo. Su hallazgo de cambios de STP se apoya en cómo se ve un enlace sano al subir: en el ether7 del RB5009, cinco subidas de enlace el 2026-09-21 registraron cada una tres pasos a learning a la vez y llegaron a forwarding entre 2,1 y 2,8 s después, y en 30 días del almacén de ese router toda subida sana dejó learning menos forwarding en 0.- Sus comprobaciones
WARN, que no cambian ni el código de salida ni queinstallsiga adelante. Dos son anteriores a la 1.4.0: con--remote-image, un usuario puesto en/container/configcuandoregistry-urlestá vacío o nombra un host distinto del que se descarga la imagen; y una instalación con el mismo--namepublicada en la LAN sinTOKENen su entorno. Lee si hay un usuario puesto y cuántas entradasTOKENexisten, nunca un valor. La forma 1.2.x del aviso de registro se reprodujo en solo lectura sobre 7.24.4 el 2026-09-23; la comparación de hosts que la sustituyó solo ha avisado contra respuestas de router falsas en los tests. La 1.4.0 añade unWARNpara una descarga en un router ARM de 32 bits, para una descarga con menos de 16 MiB libres por encima delmemory-maxdel contenedor, para el arranque con el router cuando la raíz está en un disco tmpfs, para una regla de cortafuegos que puede descartar las respuestas del agente, para un--lan-addressen el enlace de subida, para objetos etiquetados para la instalación que las opciones no seleccionan, y para una tabla de rutas o un cortafuegos que no pudo leer. De ellos, los avisos del tmpfs y de los objetos etiquetados saltaron en el laboratorio en CHR x86_64, RouterOS 7.24.4, el 2026-09-27; ninguno se ha ejecutado en el RB5009. - Extracción del tar, 7.24.2, 2026-09-11: un tar de 1,8 MiB, una compilación de esa fecha
anterior a 1.0.0, se extrajo en el mismo segundo que su
/container/add. La CLI de entonces borraba el tar tras una espera fija; la 1.4.0 espera a que el contenedor marquestopped, con--extract-timeoutcomo límite. - Una instalación expuesta actualizada sin su token, 7.24.4, 2026-09-21: el upgrade pasó su
comprobación, dejó las dos reglas en su sitio y escribió una envlist sin
TOKEN, y/snapshotpor la dirección LAN del router pasó de401a200. Desde 1.2.0doctorseñala ese estado, y el código posterior a la 1.3.1 rechaza unupgradeasí (laboratorio, 2026-09-27). - Un
uninstallsin más de una instalación expuesta, 7.24.4, 2026-09-21: retiró todo lo demás, imprimióverified: nothing mikroscope created remains on the routery dejó el dst-nat apuntando a una dirección que ya no existía. El código posterior a la 1.3.1 lee del router la forma de la instalación, y ununinstallsin más retiró las dos reglas en el laboratorio (2026-09-27).
record, mark y plot
Sección titulada «record, mark y plot»record, mark y plot funcionan de extremo a extremo, como muestra una grabación hecha en el
RB5009 el 2026-09-12: 60 s a 10 Hz, exactamente 600 muestras, 0 huecos y −7 ms de desfase de
reloj. Lo que mostró está en su campaña.
En el laboratorio el 2026-09-27 (CHR x86_64, RouterOS 7.24.4, la imagen publicada del agente 1.3.1),
record --for 60s escribió 600 muestras, seq de 11 a 610, con 0 huecos. Tres notas de mark
desde una segunda shell llegaron al mismo .markers.csv mientras record corría, y el resumen de
record dijo 0 marker(s): solo cuenta las notas escritas en él. mark --log-markers por la API
del laboratorio añadió 7 marcadores del log del router en la ventana, y plot dibujó las 600
muestras y 10 marcadores.
forward
Sección titulada «forward»forward se ha ejecutado desde el RB5009 hacia tres de sus once destinos, fichero, Prometheus e
InfluxDB 3, los tres a la vez el 2026-09-15; los otros ocho solo se han vuelto a leer desde productos
reales en contenedores, desde el 2026-09-16. forward une la capa del kernel con la capa de la API
de RouterOS y escribe en once destinos. Por Loki, OTLP, Graphite, Elasticsearch, SQL, PostgreSQL,
Telegraf y stdout no han pasado muestras del router; la batería de contenedores escribe en cada
producto real y lo vuelve a leer por su propia API (Baterías de pruebas).
- 2026-09-12, ocho minutos: 4 800 muestras del kernel y 479 de la API reenviadas con 0 huecos y 0
descartes, ejecutando
mikroscope forward --for 8m --prom :9124 --influx … --interfaces bridge,.ether1, PPPoE_ DIGI --conntrack-every 10s - 2026-09-15, cinco ejecuciones de cadencia a 10, 50 y 100 Hz hacia un fichero, una exposición
Prometheus e InfluxDB 3 a la vez: todos los destinos informaron de 0 huecos y 0 descartes
(
rates-2026-09-15). - Prometheus: un Prometheus 3.14 hizo scrape de la exposición del colector cada 5 s con el RB5009 alimentando el colector, el 2026-09-12 y de nuevo el 2026-09-15. No consta ningún otro intervalo de scrape ni ninguna otra versión de Prometheus.
- InfluxDB 3: el primer destino real, el 2026-09-12, respondió
422: would exceed limit of 5 databases, el límite por nodo que InfluxData documenta para Core. Las ejecuciones medidas usaron una instancia de InfluxDB 3 Core propia. El 2026-09-19 el colector pasó a InfluxDB 3 Enterprise 3.11.4 y escribió 44 820 filas en 36 tablas en sus primeros 19 minutos, 0 descartadas y 0 errores. Todo lo anterior a esa fecha se midió contra Core. - El colector frente a un agente más rápido, 2026-09-21: con el agente a 100 Hz y otra vez a
50 Hz,
/healthzdabarate_hz100 y 50 y el propio registro del colector repetía esa misma cadencia, mientras quemikroscope_info{rate_hz}valía10en los dos casos;mikroscope_llevaba los cuboscpu_ busy_ ticks le="0"ale="11"más+Infen los dos; ywindow="1s",window="10s"ywindow="60s"estaban los tres presentes en los dos. - Detecciones en el almacén de referencia, del 2026-09-19 a las 11:13 UTC al 2026-09-24 a las
08:26 UTC: saltaron cuatro de las once reglas,
microburst116 veces,ipc-collapse41 (en los cuatro núcleos),link-flap11 yagent-restartuna. Solo demicroburstse ha medido el comportamiento contra las muestras (microburst-replay-2026-09-16); las otras tres se contaron, sin cotejarlas con lo que hacía el router. Las 11 filas delink-flapestán enether1,ether2,ether4,ether6yether7, cada una con entre 2 y 6 registros de enlace en 60 s, todas sin provocar; no se comprobó cuál se debió a un cable, a un equipo del otro lado o a otra cosa. - Reinicios: el reinicio por la actualización de RouterOS del 2026-09-19 ejercitó de verdad la
resincronización del colector (la capa del kernel se reanudó a las 00:45:03 CEST). No se comprobó
si entonces se escribió una fila de
mikroscope_detectionparaagent-restart, y el almacén que la habría guardado se sustituyó más tarde ese mismo día; el actual empieza a las 11:13 UTC. Guarda una fila deagent-restart, a las 08:08:54 UTC del 2026-09-24, convalue1 frente athreshold4 338 037, cuando se actualizó el agente a 1.2.0. - Datos del equipo: enviados una sola vez al arrancar, los cuatro paneles del equipo muestran «No data» en toda ventana posterior: el 2026-09-17 la última fila de equipo del despliegue de referencia tenía 26 horas y esos paneles llevaban vacíos otro tanto. Repetidos cada cinco minutos, cuestan doce filas por envío en el RB5009.
- La entrega durante 24 horas, 2026-09-17, en el despliegue de referencia: la mayor interrupción fue de 114,5 s, y la provocamos nosotros, un cambio de contenedor más el minuto que tarda el colector en notar que el agente se ha reiniciado. En funcionamiento normal el colector nunca se quedó atrás. Por eso el anillo guarda 60 s por defecto: cubre un reinicio de cualquiera de los dos lados en una LAN.
Capa de la API
Sección titulada «Capa de la API»La capa de la API ha funcionado en una sola placa, el RB5009, sin parar sobre 7.24.4 desde el 2026-09-19.
- Reconexión, 2026-09-19, tras la actualización de ese día, sin tocar el router: a un colector que
ejecutaba
monitor-trafficsobre 16 interfaces (todas salvolo) a 1 Hz se le destruyó el socket de la API desde el host conss -K, que es como se ve desde él el lado del router en un reinicio. La capa reabrió la conexión y reintentó dentro de la misma ronda: 0 comandos fallidos, 0 rondas perdidas, 16 interfaces en cada uno de los 108 segundos a ambos lados de la muerte del socket. - Lo que devuelve RouterOS: claves de pérdidas,
una cuenta de
rx-overflowque solo llevan los contadores de puerto, los dos planos de cuenta de un puerto del switch y su bridge, y las horas del log. cpu-loades una media móvil de más o menos un segundo, ajustada contra/proc/stat(cpu-load-window-2026-09-15).- Lo que le cuesta al router: Coste de la capa API.
Dashboards
Sección titulada «Dashboards»Todos los paneles de los cinco dashboards respondieron sin error en un Grafana real sobre los
almacenes de la batería de contenedores (2026-09-17), y los dashboards de InfluxDB y Prometheus
superaron dashboards check sobre los datos del propio RB5009 (2026-09-16). Hay uno por almacén,
InfluxDB 3, Prometheus, PostgreSQL, Graphite y Elasticsearch, generados a partir de una sola lista de
paneles. Graphite y Elasticsearch llevan menos paneles a propósito
(39
y 28
frente a 177): Graphite no tiene etiquetas y
Elasticsearch no tiene documentos anidados. Los paneles de PostgreSQL son los de InfluxDB reescritos,
y la batería de contenedores hace que un PostgreSQL real planifique todas sus consultas. Las versiones
de Grafana usadas son la 12.3.2 el 2026-09-12; la 13.2.1 en las pasadas en el navegador del
2026-09-12 y el 2026-09-14, check y renderizado el 2026-09-15, check el 2026-09-16 y la batería
de contenedores; la 12.3.0 el 2026-09-21 y en los renderizados del 2026-09-25; y la 13.2.2 el
2026-09-24 y el 2026-09-25. No se ha probado ninguna otra versión.
- 2026-09-12. En Grafana 12.3.2, el dashboard de InfluxDB contra un InfluxDB 3 Core aislado
alimentado por
forwarddesde el RB5009: todos los paneles devolvieron filas, entre 158 y 316 por panel en 10 minutos. El dashboard de Prometheus contra un Prometheus 3.14 haciendo scrape del colector cada 5 s: todos los paneles devolvieron filas, entre 228 y 2 052 en 5 minutos. Sin el campotokende la fuente de datos, los paneles fallaban conflightsql: Unauthenticated. Ese mismo díadashboards check --store influxdb --window 12hpasó en los 125 paneles que recorrió mientras unos 90 eran ilegibles en un navegador: leyendas que decían “value core 0”, dos xycharts atascados en “Loading plugin panel…”, una franja de continuidad que seguía en verde sobre 2 170 ticks perdidos. Un Overview de ocho paneles se renderizó con 2 188 px de alto en una ventana de móvil de 844 px, y 900 puntos de datos es el ancho que envió el navegador para las gráficas. - 2026-09-14. Un Overview de once paneles midió 1 052 px de alto en una ventana de navegador de
1 080 px, una pantalla de escritorio; un
recorrido de renderizado contra una captura de 10,5 h del RB5009 renderizó 140 paneles de InfluxDB
con 0 insignias de error y 0 “No data”; la fuente de datos de InfluxDB escapó
$__interval_msen cinco paneles, en el navegador, convirtiéndolo en un SQL que InfluxDB 3 no podía analizar; y una consulta que nombraba un campo que el almacén nunca había recibido falló al planificarse,No field named limit. Valid fields are …, a través del proxy de la fuente de datos. - 2026-09-15, Grafana 13.2.1:
check, y un recorrido fila a fila sin interfaz de los dos dashboards en Chromium a 1600x1000, 0 insignias de error y 0 “No data” en 168 paneles de InfluxDB y 130 de Prometheus. No se ha repetido para los tres paneles que no cubrió: los dos de eventos de puerto y “What each interface is: type, role, bridge and label”. El mismo recorrido vio la proporción de fast path oscilar entre 0 y 100 % de una lectura a otra en interfaces que movían pocos paquetes. Regenerar ese día reprodujo byte a byte los ficheros del repositorio. - 2026-09-16, Grafana 13.2.1, contra el agente del RB5009 (RouterOS 7.24.2, privilegiado, los
disparadores por defecto),
forward --prom :9124 --influx … --interfaces bridge,durante 30 minutos hacia un InfluxDB 3 Core aislado, y un Prometheus 3.14 haciendo scrape del colector cada 5 s y del agente directamente para las familias que el colector no podía recalcular entonces:ether1, PPPoE_ DIGI --counters-every 10s
| Almacén | Ventana | Paneles | Fallan | Vacíos conocidos tolerados |
|---|---|---|---|---|
| InfluxDB 3 | 30 minutos | 171 | 0 | 10 (los dos paneles de eventos de puerto, la consulta opcional de conntrack, los dos paneles de disparos, PSI, los cuatro dispositivos de bloques en reposo) |
| Prometheus | 30 minutos | 133 | 0 | 9 (los dos paneles de eventos de puerto, los dos paneles de conntrack de la API, PSI, los cuatro dispositivos de bloques) |
Desliza en horizontal para ver todas las columnas
Los 10 y 9 son ese despliegue sobre esa ventana. El SQL de los dos paneles de eventos de puerto se
validó ese mismo día contra una tabla sintética en ese mismo InfluxDB 3, porque el almacén en vivo no
tenía columna kind hasta que se le escribiera el primer registro de puerto clasificado; la tiene
desde el 2026-09-19, con las ocho clases. La página de dashboards de esa fecha registró además que
la exposición del propio agente llevaba la etiqueta kind solo cuando el propio agente clasificaba,
cosa que el del RB5009 no hacía entonces; hoy los agentes no sirven exposición.
- 2026-09-17, batería de contenedores: los cinco dashboards importados en un Grafana real sobre los almacenes que llenó la batería, preguntando a cada panel: devolvieron datos 57, 98, 136, 35 y 28 paneles, y no falló ninguno.
- 2026-09-21, Grafana 12.3.0:
importcontra el almacén InfluxDB 3 en vivo y despuéschecksobre una ventana de 15 min: 167 paneles devolvieron filas, los 9 vacíos conocidos salieron vacíos, y el indicador de detecciones del Overview salió vacío porque el almacén no tenía ninguna detección en esa ventana, que es el único caso quecheckseñala y que un navegador lee como el «none» sano. - 2026-09-24, el Grafana de producción, cuyo endpoint de salud informaba de la 13.2.2 más tarde ese mismo día: el dashboard de InfluxDB importado y capturado a 390x844 y a 1600x1000 para comprobar el texto de 32 px de los paneles stat y la serie temporal de memoria. Con el tamaño automático de Grafana, un simple “0” se dibujaba de unos 60 px de alto a 390x844 y cada panel stat ocupaba cerca de un tercio de la pantalla; con el tamaño fijo, los números se leían a un tamaño normal en los dos. No se hizo recuento de insignias fila a fila, no se midió la altura del Overview y los otros cuatro dashboards no se capturaron.
- 2026-09-25, Grafana 12.3.0, 13.2.1 y 13.2.2 sobre un InfluxDB 3.11.2 Core desechable:
- La fila no disponible tal como estaba en 1.3.0 envió cinco consultas y pintó cinco insignias
table … not founden 12.3.0 y 13.2.1; con sus consultas publicadas ocultas no envió ninguna ni pintó ninguna, y 13.2.2 hizo lo mismo en un segundo renderizado. - Una consulta de detecciones contra una tabla
mikroscope_detectionque falta no puede escribirse de forma que evite el error de planificación de InfluxDB 3:WHERE false, unUNION ALLy una guardaEXISTSsobreinformation_schemafallaron todas al planificar. En 13.2.1 la capa que falla no mostró nada en el dashboard y escribió en el log de Grafana una línea de nivel errorPartial data response errorpor carga. 12.3.0 nunca envió la consulta de esa capa, con la tabla o sin ella (problema conocido). - Un
importcon sondeo desde 1.3.0 quitaba las consultas de un panel que faltaba, y Grafana 12.3.0 le da a un panel sin consultas una por defecto: el plugin de InfluxDB le respondióNo SQL statements were provided in the query string, como una insignia roja. 13.2.1 no envió nada por ese mismo panel. - Elasticsearch 9.5.3: la búsqueda de la variable Host, escrita hasta 1.3.0 como un objeto JSON,
salía de 13.2.1 y 13.2.2 como una consulta vacía respondida con 400
invalid query, missing metrics and aggregations, y 12.3.0 no la enviaba; abierto sin?var-host=, seis paneles del Overview fallaban conFailed to parse query [host.keyword:]. Escrita como la cadena JSON que analiza la fuente de datos, Host se llenó desde el índice y ningún panel mostró insignia en ninguna de las tres. - Un panel de InfluxDB que agrupa con
$__dateBincon un paso por debajo del segundo dibujó un bin de 0 segundos y volvió vacío, enchecky en un navegador con el zoom en unos pocos minutos, en 13.2.1 y 13.2.2.
- La fila no disponible tal como estaba en 1.3.0 envió cinco consultas y pintó cinco insignias
- 2026-09-25, el Grafana 13.2.2 de producción contra el almacén InfluxDB 3 de referencia, con una
compilación que oculta las consultas de la fila no disponible:
dashboards check --window 1h, con el sondeo y con--no-probe, dio 164 paneles con filas, 12 vacíos conocidos tolerados y 1 fallo, “Detections in the window”, porque el almacén no tenía ninguna detección en esa hora. Sin el sondeo, los cinco paneles no disponibles salen comonone … rows=0 frames=0sin texto de error, donde 1.3.0 imprimía400 … table … not found; los dos paneles de disparos respondieronmikroscope_, porque ese almacén no tiene tabla de disparos. El SQL de la anotación de detecciones devolvió 44 filas en 6 horas. Repetido más tarde ese día, después de que los ficheros sin sondeo de los otros cuatro almacenes recuperaran sus consultas de la fila no disponible, dio los mismos recuentos, y la capa de detecciones 32 filas en 6 horas; el fichero de InfluxDB comprobado era idéntico byte a byte al de la primera vez.trigger not found - 2026-09-25, batería de contenedores (Grafana 13.2.1, Prometheus 3.14.0, PostgreSQL 18.6, graphite-statsd 1.1.10-5, Elasticsearch 9.5.3): las consultas no disponibles de los ficheros del repositorio, contra almacenes que no tenían nada para ellas, respondieron todas 200 sin error, y en Elasticsearch todos los puntos fueron 0, tanto si otro router del mismo índice había mapeado el campo como si no. En PostgreSQL la consulta de la capa de detecciones respondió 200 sin filas sobre una ventana anterior a cualquier detección, y 10 filas sobre la de la propia ejecución. Las dos fueron consultas por la API de Grafana, no renderizados.
- La continuidad se deriva del número de secuencia de cada muestra, y encontró 4 493 ticks perdidos y un reinicio en la captura del 2026-09-11/12 de los que el registro de huecos del colector no decía nada.
- El rango por defecto es de 3 horas porque
now-15mabría 108 paneles vacíos con el agente parado, y con el agente en marcha dibujaba muros de ruido ilegibles de muestras de 100 ms (la fecha no consta).
Reglas de alerta
Sección titulada «Reglas de alerta»Solo la forma de InfluxDB 3 de las reglas se ha cargado en Grafana y se ha visto evaluarse, el 2026-09-21 contra el almacén del mantenedor; las formas de Prometheus y PostgreSQL nunca. Las reglas son 14 para InfluxDB 3, 15 para Prometheus y 10 para PostgreSQL.
- La carga del 2026-09-21, en Grafana 13.2.1 contra el almacén InfluxDB 3 en vivo, tenía las doce
reglas de InfluxDB de esa fecha y destapó dos defectos, los dos corregidos en 1.1.0.
coalesce()sobre el agregado sin signo que escribe el destino de InfluxDB devolvía HTTP 200 sin marcos, que Grafana lee como NoData y estas reglas como OK: siete de las doce no podían saltar nunca,mikroscope-l2-loopentre ellas, mientras el mismo SQL contra/api/v3/query_sqldevolvía 109 con la firma del bucle en vivo. Y la regla de conntrack nombrabalimit_objs, la columna del destino SQL, donde el destino de InfluxDB escribelimit; la página de reglas de alerta había predicho ese defecto antes de confirmarse. Tras la corrección las doce devolvieron un valor, ymikroscope-l2-looppasó a Alerting a las 16:58:50Z con la firmaown-addressen vivo; la lista de instancias de Grafana para esa regla seguía llevandoNormal (NoData)de las 16:56:50Z, de la ejecución anterior a la corrección. - Consultas ejecutadas a mano contra el almacén en vivo el 2026-09-21:
mikroscope-l2-loopdio 109 en su propia ventana de cinco minutos, con la firmaown-addressenether2corriendo sin parar a unos 0,5 registros/s desde el 2026-09-19;mikroscope-port-link-downdio 3 en la ventana que contiene una caída de enlace real enether7a las 16:33:49 y 4 en el grupo de cuatro deether4de las 09:19 del 2026-09-20. Las dos tienen umbral 0 congt, así que las dos condiciones se cumplieron. - Las dos reglas que añadió 1.2.0 no estaban en esa carga, y ningún Grafana las ha evaluado
desde entonces. Su SQL de InfluxDB se contrastó con datos pasados del almacén de referencia:
mikroscope-bridge-port-darkdevolvió 1 en tres ventanas dentro del bucle y 0 después, y marcósfp-sfpplus1en 204 intervalos de diez minutos yether2en 376 entre el 2026-09-19 11:13 y el 2026-09-23 22:44 UTC, las dos fases del bucle de capa 2 de esa semana, y ningún otro puerto.mikroscope-wakeup-stormdevolvió 0,94–0,95 en dos ventanas sanas, nunca pasó de 1,81 en 551 ventanas de diez minutos con un día completo detrás (del 2026-09-20 al 23), y se abrió en 35,7 con la tormenta de despertares del 2026-09-23; se apagó cuando la nueva tasa pasó a ser la base, al cabo de unas cuatro horas. Su PromQL solo se comprobó en su sintaxis. De la forma PostgreSQL de la regla de despertares no consta ninguna ejecución, y la regla del puerto oscuro no tiene forma PostgreSQL: la 1.2.1 la quitó, porque la tabla de contadores de interfaz del destino SQL no tiene las columnas que lee. - La regla de detecciones ya no salta con
microburstni conipc-collapse, que describen cómo lleva el tráfico un router sano: del 2026-09-23 10:30 al 2026-09-24 10:30 UTC en el RB5009 fueron 64 de 71 detecciones, y con ellas la regla saltó en 43 de 288 ventanas de cinco minutos; sin ellas, en 6. - La regla de salida: un puerto de 1 GbE hacia un servidor perdió 3 337 paquetes en seis ráfagas de un segundo a lo largo de 6,5 h, con picos de 436 paquetes/s (2026-09-19), visible en el panel de cola de salida y, con razón, sin ser una alerta.
- La regla térmica lee el punto de disparo crítico de la propia zona, 105 °C en el RB5009.
forward --grafana
Sección titulada «forward --grafana»forward --grafana se ha ejecutado contra el Grafana del mantenedor (2026-09-19, InfluxDB 3) y
contra el de la batería de contenedores para los cinco almacenes (2026-09-20, y con el código de la
1.5.0 el 2026-09-27). dashboards publish solo se ha ejecutado allí, el 2026-09-27, sobre lo que
forward --grafana acababa de crear. El 2026-09-20 se apuntó el colector a un Grafana real y a
cada uno de los cinco almacenes por turno, se le dejó crear la fuente de datos, y después
dashboards check pasó la consulta de cada panel por la API de Grafana contra la fuente de datos
que había construido el colector. Los cinco respondieron sin error de fuente de datos tal como lo
leía la prueba de esa fecha: buscaba flightsql: Unauthenticated, el error de TLS que se cita más
abajo y err con un espacio a cada lado, que no es ninguna marca que imprima check, así que un
error redactado de cualquier otra forma la pasaba. La misma ejecución encontró un defecto que
ninguna prueba unitaria tenía: un colector que escribía en un PostgreSQL vivo por --postgres y en
nada más no publicaba nada y decía «there is nothing to publish», porque la lista de almacenes solo
conocía --sql. Contra un almacén InfluxDB en HTTP plano, una fuente de datos sin insecureGrpc
respondía a todos los paneles
tls: first record does not look like a TLS handshake mientras el almacén estaba perfectamente
(medido el 2026-09-19).
El 2026-09-27 la prueba se ejecutó con el código de la 1.5.0 (el commit ffb934e, cuyo código Go es
el de la publicación; la ejecución 36344009521 de e2e.yml) contra Grafana 13.2.1, InfluxDB 3.11.2
Core, Elasticsearch 9.5.3, PostgreSQL 18.6, Prometheus 3.14.0 y graphite-statsd 1.1.10-5, y para
entonces fallaba con cualquier línea FAIL de check que llevara un error. Para cada almacén por
turno, forward --grafana creó la fuente de datos y publicó el dashboard, check pasó cada panel
contra esa fuente de datos sobre una ventana de 15 minutos, y dashboards publish, con las mismas
opciones de almacén y de Grafana, salió con código 0, dio la fuente de datos como unchanged e
imprimió la dirección del dashboard. Ningún panel que check cuenta como fallido llevaba un error;
un panel que se espera vacío se marca none cuando no devuelve filas o devuelve un error, y la
prueba solo lee esas líneas en busca de los dos errores de InfluxDB de arriba. La fuente de datos de
Elasticsearch fue la del colector, con @timestamp como campo de tiempo (la de la 1.4.0 nombraba
time, un campo que no lleva ningún documento), y su check salió con código 0; en InfluxDB,
PostgreSQL, Prometheus y Graphite, 5, 20, 33 y 4 paneles no devolvieron filas en la ventana, sin
error. No se ha probado en la batería: la cabecera Authorization que envía la fuente de datos de
Elasticsearch, porque su Elasticsearch funciona sin autenticación; una fuente de datos que lleve un
token o una contraseña, que ningún almacén de allí tiene; ni una ejecución que publique más de un
almacén, porque cada ejecución publicó uno.
uninstall --targets
Sección titulada «uninstall --targets»uninstall --targets retiró solo lo que escribió este proyecto en la batería de contenedores
(2026-09-20, y --targets data de nuevo con el código de la 1.5.0 el 2026-09-27), y no se ha
ejecutado contra el almacén de producción del mantenedor. La batería comprueba que una tabla que
este proyecto no escribió, en la misma base de datos y el mismo esquema, ni se lista ni se borra.
Ejecuta la orden solo con --targets data, contra PostgreSQL e InfluxDB 3, sin router y sin
Grafana. Lo que la 1.5.0 cambió en la orden fuera de ese camino solo tiene pruebas unitarias:
rechaza --grafana-dry-run, lista los objetivos de Grafana y de los almacenes antes de tocar el
router, se detiene ante un Grafana que no pudo leer, que la 1.4.0 contaba como uno sin nada que
retirar, y lee la dirección de Grafana de GRAFANA_URL cuando
MIKROSCOPE_GRAFANA_URL no está definida.
Baterías de pruebas
Sección titulada «Baterías de pruebas»Cuatro baterías no necesitan router: la unitaria y la de extremo a extremo se ejecutan en la CI en Linux, macOS y Windows contra árboles capturados y simulaciones, otra contra nueve almacenes reales en docker compose, completa por primera vez el 2026-09-16, y otra ejecuta la CLI y el agente contra un RouterOS virtual, en verde por primera vez el 2026-09-26 y ejecutada por primera vez en los runners de GitHub el mismo día. Qué demuestra cada una y cómo ejecutarla está en Baterías de pruebas.
- De extremo a extremo: los dos binarios contra un árbol
/proccapturado del RB5009 y un agente simulado, con un receptor por cada protocolo de destino que comprueba los bytes. No necesita router, ni Grafana, ni red, y se ejecuta en la CI tanto en macOS y Windows como en Linux, que es donde se notaría una diferencia en el nombre del ejecutable, en los ficheros que escriben los destinos de fichero y SQL, o en cómo se detiene un proceso hijo. Cada destino se prueba contra un receptor local desde el 2026-09-12, en el equipo de desarrollo amd64. La batería antes hacía scrape del agente y del colector, y ahora comprueba solo el colector. - Almacenes (
make test-e2e-docker): el colector, contra el mismo agente enlatado y con la capa de la API apagada, hacia Loki 3, el OpenTelemetry Collector, graphite-statsd, Elasticsearch 9, Telegraf 1.39 por HTTP, PostgreSQL 18 (con--sql, y con--postgresdesde que ese destino llegó el 2026-09-21), InfluxDB 3 y Prometheus, con el destino de fichero como el oráculo contra el que se comparan los demás. Cada almacén se vuelve a leer por su propia API, después se importan los cinco dashboards en Grafana y la consulta de cada panel pasa por la API de Grafana; la batería hace queforward --grafanapublique las cinco fuentes de datos y comprueba sus dashboards contra ellas, después, desde el 2026-09-27, ejecutadashboards publishcon las mismas opciones de almacén y de Grafana, que tiene que salir con código 0 y nombrar la fuente de datos y el dashboard de cada almacén, y vuelve a vaciar los almacenes conuninstall --targets data. Necesita Docker y ningún router: las muestras son enlatadas, así que la ejecución es reproducible en cualquier máquina. La primera ejecución completa, el 2026-09-16, encontró un panel que nombraba dos columnas que el almacén solo tiene cuando se ejecutó la capa de la API: la tabla de eventos de puerto nombralabelyrole, que el destino escribe en una fila del registro del kernel solo desde el inventario de la capa de la API, y en InfluxDB 3 una columna que no está en la tabla hizo fallar la consulta conSchema error: No field named label, así que el panel no podía dibujarse. Las páginas de destinos registran el colector escribiendo en estos almacenes desde el 2026-09-17. En la máquina de desarrollo, el 2026-09-16, la pila se levantó en 55 a 81 s con las imágenes ya descargadas, y la batería entera tardó de 75 a 100 s desde cero. La batería entró en la ruta de los pull requests el 2026-09-18. Hasta entonces se ejecutaba cada semana, a petición y antes de una publicación, y así llegó la 1.0.5 amaincon dos pruebas de la batería leyendo todavía el/metricsdel agente, que esa versión había quitado: todos los checks del pull request estaban en verde, y lo encontró la puerta de publicación. En la ejecución de publicación que falló tardó 2 min 37 s desde el inicio del trabajo hasta el resultado, contenedores incluidos; en el pull request #70, el 2026-09-27, 4 min 9 s. El OpenTelemetry Collector, que acepta JSON, es el único receptor OTLP real contra el que se ha ejecutado el destino. El 2026-09-20 los destinos SQL y PostgreSQL, ejecutados en paralelo hacia dos bases de datos, tenían 34 tablas coincidiendo byte a byte, cada columna de cada fila con un hash por fila sumado, más uninformation_idéntico para todo el esquema.schema. columns - Laboratorio virtual de RouterOS (
make test-lab): los verbos de despliegue de la CLI y el agente contra el Cloud Hosted Router 7.24.4 de MikroTik en QEMU, x86_64 y arm64 emulado: instalación por las dos vías de imagen, actualización, desinstalación,--ephemeralystart-on-boota través de un corte de corriente, y cada escenario termina comparando el/exportdel router con el de su inicio. Prueba que el instalador es correcto; no es una placa, y ninguna cifra de Coste del agente ni de Campañas sale de él. El laboratorio, sus tiempos y sus primeras ejecuciones en los runners de GitHub están en Laboratorio virtual, y sus escenarios en Baterías de pruebas. - Fixtures de los destinos, no un router: los tamaños de SQL, OTLP, Graphite, Elasticsearch y
Telegraf de Otros destinos salen de fixtures de pruebas de dos
núcleos del 2026-09-12. La cabecera SQL de las cuarenta y tres tablas, generada por el propio
header()del destino el 2026-09-19, ocupa 10 482 B, 13 966 B con las sentencias de hypertable de TimescaleDB. Doce renderizados de un mapa de 8 nombres dieron 7 órdenes (2026-09-12), registrado eninternal/.sinks/ telegraf.go - El equipo de desarrollo (amd64, kernel 6.12.107):
TestParsePressureReadsTheRunningKernelyTestParseSchedstatReadsTheRunningKernelanalizan el/proc/y elpressure/ {cpu, memory, io} /proc/schedstatdel propio equipo y los comparan con una segunda lectura de esos mismos bytes, y se saltan la prueba donde los ficheros no están, que es el caso del RB5009. En ese equipo pasan. Su/proc/pressure/cpulleva líneafull, toda a cero al volver a leerla el 2026-09-24: la documentación de PSI del kernel dice que elfullde CPU no está definido para el sistema entero y que se publica desde la 5.13 a cero, así que un kernel más antiguo no tiene esa línea y el analizador acepta las dos formas. Su PMU, registrada el 2026-09-21, tiene seis contadores,cycles,instructions,cache-references,cache-misses,branch-instructionsybranch-misses, multiplexados, cada uno funcionando en torno al 84 % del tiempo que estuvo habilitado. Un intervalo de 100,3 ms llevó allí 11 ticks (2026-09-11/12);sample_test.gocomprueba que la fracción de ocupación está limitada a 1. - El rearme del filtro de cambios, contra el árbol de fixtures el 2026-09-15: las familias de
medidores con suelo y
mikroscope_estaban presentes en 6 de 6 scrapes desde 5 s después del arranque. El comentario deslab_ limit_ objects ProcSource.ReArmeninternal/agent/source.goregistra la misma comprobación como cuatro scrapes desde t+5 s, 0 antes de la corrección y 4 de 4 después; no consta de qué ejecución es cada cuenta. - El generador de scripts, 2026-09-27:
pnpm run rsc:checkrenderiza en JavaScript los 20 casos de referencia de la especificación de pasos y compara byte a byte con la salida de Go cada script, las órdenes de cada paso, el orden de retirada, los valores y la línea de órdenes; un cambio de una línea en el renderizador le hizo informar de 72 fallos.pnpm test:generatorhizo 168 comprobaciones en Chromium sin interfaz (Playwright 1.63) contra el sitio compilado: los 20 casos puestos con los propios controles del formulario, los errores, el token, copiar, el uso solo con teclado, ninguna petición de red, y las descargas.rsc, que funcionan bajo la CSP meta del sitio. Una comparación puntual con el código de Go sobre 304 juegos de opciones coincidió en 301; los otros tres son entradas que la página rechaza y Go acepta (un prefijo/030, un umbralbusy>=.5y una dirección IPv6 con IPv4 mapeada). - El sitio, 2026-09-25: Chromium 153 sin interfaz pidió solo
favicon.svg, y resolvió unidde manifiesto./a la raíz del origen; en Chromium y WebKit sin interfaz, con los dos esquemas, tras elegir en el selector, tras una elección guardada y una recarga, tras el botón del teléfono y sin JavaScript, la etiquetatheme-colortuvo el color de la cabecera todas las veces, donde el par separado porprefers-color-schemeal que sustituye tenía el color del otro tema tras cada elección.
Rutas de instalación probadas
Sección titulada «Rutas de instalación probadas»| Ruta | RB5009UG+S+ | CHR x86_64, laboratorio | CHR arm64, laboratorio |
|---|---|---|---|
Descarga de Docker Hub, --remote-image |
2026-09-17, 7.24.2: /healthz a 2 ms; la imagen 1.0.1, enviada sin su host y descargada a través de registry-url. 2026-09-24, 7.24.4: la referencia con su host, con un /container/add escrito a mano, sin arrancar; ningún install completo |
2026-09-26: install en 9,6 s, descarga anónima con el /container/config de fábrica; 2026-09-27: S2, S4 y S5 |
2026-09-26: install en 10,3 y 10,2 s, descarga anónima; 2026-09-27: S2, S4 y S5 |
Descarga de GHCR, --remote-image |
2026-09-21, 7.24.4: falló, auth error |
2026-09-26: descarga sin credencial de registro y con el host en remote-image=, /healthz 5 s después de empezar la instalación; 2026-09-27: S18 y S5 |
2026-09-27: S18 y S5 |
plan --rsc, con /import |
2026-09-17, 7.24.2: /healthz a 15 ms en sus primeras muestras, sin CLI en la instalación |
2026-09-26: /healthz 14 s después de empezar la subida; 2026-09-27: S4, y los quince guiones de referencia que el laboratorio puede ejecutar (S5); el script por defecto pegado en el indicador ] >, y un script de tar sin su tar, que se detuvo antes de escribir nada |
2026-09-26: /healthz 9,1 y 9,5 s después de empezar la subida; el script era el de x86_64; 2026-09-27: S4 y S5 |
Tar de la imagen, --agent-tar |
2026-09-17, 7.24.2: el tar arm64 publicado, /healthz a 2 ms |
2026-09-26: el tar amd64 de la versión, 6 s; 2026-09-27: el tar de la rama, S3 y diez instalaciones seguidas; el tar amd64 de la versión comprobado con sha256sum y cosign verify-blob, y después instalado y actualizado |
2026-09-26: el tar arm64 de la versión, suma de comprobación como la publicada, 9,6 y 9,2 s; 2026-09-27: el tar de la rama, S3 y tres instalaciones seguidas |
| Generador de scripts | sin ejecutar | 2026-09-27: el script por defecto de la página, igual al de plan --rsc, y un script de tar con otros ajustes, cada uno descargado de la página compilada y pegado en el indicador ] >; el agente respondió cada vez, y el uninstall de la CLI y el script de desinstalación de la página dejaron cada uno el /export como estaba |
sin ejecutar |
| Instalación manual, terminal | sin ejecutar | 2026-09-27: las órdenes de la página una a una, descarga del registro y tar; /healthz respondió, status reconoció la instalación por su manifiesto, y la retirada de la página no dejó nada; de nuevo con las dos reglas de --expose, y con las dos pertenencias omitidas |
sin ejecutar |
| Instalación manual, WebFig | sin ejecutar | 2026-09-27: las dos vías de imagen, cada formulario enviado; /healthz 200 cada vez; la descarga retirada por WebFig, el tar por uninstall leyendo el manifiesto que escribió WebFig; el /export como estaba tras cada una |
sin ejecutar |
| Desde el repositorio | 2026-09-17, 7.24.2: /healthz a 2 ms; la ida y vuelta del 2026-09-12 |
sin ejecutar | sin ejecutar |
--expose |
2026-09-11: las dos reglas verificadas; 2026-09-23, 7.24.4: una instalación desechable expuesta, actualizada sin token y retirada | 2026-09-26: /healthz 200, /capabilities 401 sin el token y 200 con él; 2026-09-27: S8 y S14 |
2026-09-27: S8 y S14 |
uninstall |
2026-09-17: verificado por recuento de propiedad tras cada ruta; el /export tras las cuatro, idéntico byte a byte al de antes |
2026-09-26, 1.3.1: fallaron 5 de 15 primeros intentos; un segundo lo limpió todo cada vez. 2026-09-27: cada primer intento limpio, tras cada ruta (F4) | 2026-09-26, 1.3.1: 8 de 8 primeros intentos limpiaron; con un cliente en /stream falló. 2026-09-27: cada primer intento limpio, tras cada ruta (F4) |
Desliza en horizontal para ver todas las columnas
- En el laboratorio, el 2026-09-27, con el código posterior a la 1.3.1 (la sección 1.4.0
del registro de cambios): la batería entera del laboratorio en las dos arquitecturas, con todas las
pruebas superadas (Tiempos del laboratorio). Tras cada ruta, las de descarga y tar
de la CLI, una instalación desde el tar y después una actualización, un guion de
plan --rscimportado, cada guion de referencia que el laboratorio puede ejecutar e instalaciones hechas por la CLI 1.3.1 publicada,uninstalldejó el/exportigual al tomado antes de instalar y ninguna ruta de mikroscope en/file. La descarga de GHCR del 2026-09-26 registróregistry=ghcr.io, una capa de 3 093 207 bytes ydownload/extract done2 s después, con/container/configsinregistry-urlni usuario. - Las ejecuciones de las páginas de instalación, 2026-09-27, en el laboratorio x86_64, con el
código posterior a la 1.3.1 y la imagen y el tar publicados del agente 1.3.1:
- El script por defecto del generador respondió 8,8 s después de empezar a pegarlo. Su script de
tar (nombre
gen2,172.30.11.0/30, puerto 9200, las dos listasnone, cadencia 20, disparosbusy>=0.9,oom, un token generado en la página,--exposeen 192.168.88.1,--restart-max-count 3,--start-on-boot no) era idéntico byte a byte al deplan --rscpara la línea de órdenes de la página, respondió en172.30.11.2:9200y borró su tar tras la extracción. - El script por defecto de
plan --rsc, idéntico byte a byte apull-dockerhub.rsc, instaló un agente en marcha tanto pegado como subido y después con/import(Script file loaded and executed successfully). El script de tar sin el tar se detuvo conmikroscope: upload mikroscope.tar firsty no escribió nada. - Las órdenes de la página de instalación manual por terminal, cada una por separado: las dos vías
respondieron, la espera de la vía del tar borró el tar tras la extracción, y una instalación
manual con tar también la retiró
uninstall --yessin más. Un buscar y reemplazar de los marcadores que también reescribió las claves de la envlist hizo que la retirada dejara la envlist entera, sin avisar, y por eso la página dice que se reemplacen solo los valores. - La misma página otra vez, cuando ya escribía un manifiesto por vía de imagen y daba a
--exposeuna sección: una descarga del registro expuesta en192.168.88.1con token, una instalación con tar y una descarga del registro con las dos pertenencias omitidas. Cada manifiesto que escribieron sus órdenes fue idéntico byte a byte al de la CLI con los mismos ajustes (pull-dockerhub,expose-token,default-tar,lists-none);statusleyó cada uno de su manifiesto, el expuesto con sus dos reglas como de la instalación;/capabilitiesrespondió 401 sin el token y 200 con él; y la retirada de la página, primero las dos reglas, dejó la cuenta de sobrantes en 0 y/export, el residuo y/fileiguales a la referencia. - Una instalación por WebFig dejó un
/exportigual al que dejó el/importdel script de referencia, en las dos vías, salvo las dos direcciones MAC de la veth, que RouterOS elige al azar;statuslistó cada uno de sus objetos como de la instalación. - Las comprobaciones de la página sin conexión sobre los ficheros publicados de 1.3.1:
sha256sum --ignore-missing -c checksums.txtOK ycosign verify-blob(cosign v3.1.3)Verified OK. Despuésinstallyupgrade --agent-tarcon el tar amd64, 7 053 KiB subidos, y ununinstalllimpio. - Instalaciones hechas por la CLI publicada 1.3.1:
statusleyó su forma de las etiquetas,upgrade --remote-imageescribió un manifiesto, yuninstall --yeslo retiró todo, el directoriomikroscope/de 1.3.1 incluido. upgradesin--remote-imageni--agent-tarbuscó Go para compilar el agente: no toma la imagen del manifiesto. Un segundoinstallen un router ya instalado no creó nada (install done: 0 step(s) created).
- El script por defecto del generador respondió 8,8 s después de empezar a pegarlo. Su script de
tar (nombre
- Las ejecuciones de las páginas de configuración, 2026-09-27, laboratorio x86_64:
doctoren un CHR de serie marcó MISSING solo la lista de interfacesLAN, con una solución que ofrece--iface-list none, y con las dos listas ennonepasó cada comprobación. Las listas integradas se rechazaron antes de conectar. La comprobación de trampas contra los perfilesadvanced-firewallyadvanced-firewall-rangenombró la regla que descarta las respuestas del agente, y su solución. Una lista de direcciones que no existía la creó la entrada de la instalación y ya no estaba trasuninstall. La primera ida y vuelta del sondeo marcó de 1,02 a 1,03 s en tres de seis instalaciones y 2 ms en las otras tres, ystatusun segundo después de 1 a 2 ms. - En el RB5009, el 2026-09-17, las cuatro rutas se ejecutaron una tras otra, cada una con su
propio nombre, su veth y su
/30para no tocar nada de lo que ya había en el equipo, y cada una se retiró antes de la siguiente./healthzse leyó desde el equipo del colector. - GHCR, el 2026-09-21, una segunda instalación junto a la que estaba en marcha, con su propio
--name,--veth,--subnety--port. La CLI de esa fecha ponía enremote-image=solo el resto de la referencia, así queregistry-urlse apuntó ahttps://ghcr.iopara la ejecución y se restauró después;doctorse negó primero conMISSING registry-url is https://ghcr.io. Con el registro apuntando a GHCR el router creó el contenedor y falló la descarga:download/extract error: fetch manifest failed: getting https://.ghcr.io/ v2/ jmrplens/ mikroscope-agent/ manifests/1.0.9 failed: auth error /container/configguarda un único usuario y contraseña para todos los registros, y el del RB5009 es un login de Docker Hub. Desde el equipo del operador ese mismo día, contra el mismo paquete público, sin credencial devolvía 200 una vez obtenido el token anónimo, y con una credencial ajena 403 en el endpoint del token. La ejecución encontró además que una instalación con--remote-imageidentificaba su contenedor por la referencia del registro, la misma cadena en cualquier instalación, así que una segunda instalación en un router se negaba como si la primera fuera de otro; ahora se identifica por su veth. - Los límites de Docker Hub, leídos el 2026-09-24: 100 descargas anónimas cada 6 horas por
dirección IPv4 o
/64IPv6, y el token anónimo lleva las mismas 6 h (pull_limit_interval21600), mientras que la cabeceraratelimit-limitdel registro en unHEADdel manifiesto del agente decía100;w=3600. No se midió cuál de los dos aplica Docker. La cifra de una descarga por instalación sale de la regla de recuento de Docker y de una descarga hecha concurldesde el equipo del operador, no de una descarga de RouterOS. - Las fuentes de MikroTik sobre el registro por defecto, leídas el 2026-09-24: el changelog de 7.18
añade
registry-url=https://, el de 7.21.2 dice “changed default container registry to docker.io”, ningún changelog de 7.21.3 a 7.24.4 menciona el registro, y la documentación de contenedores sigue dandolscr.io https://lscr.io/. El CHR del laboratorio con 7.24.4 no teníaregistry-urlni usuario e informabaassumed-registry-url: docker.io.
Coste del agente
Sección titulada «Coste del agente»Con los valores por defecto de la instalación, 10 Hz, suelos por fuente por defecto y un anillo de 60 s, el agente cuesta 2,69 % de un núcleo y 13,2 MiB de RSS, leídos de su propio cgroup en régimen estacionario con el anillo lleno:
Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · · ventanas de 300 s en régimen estacionario (con el anillo ya lleno), conjunto completo de fuentes, la configuración que se envía —anillo de 60 s, límite de memoria derivado de él y el tope de contenedor de serie de 64M— con el colector reenviando a InfluxDB 3
| cadencia | suelos | CPU de un núcleo | µs/ | RSS | ticks retrasados | huecos / |
|---|---|---|---|---|---|---|
| 10 Hz (por defecto) | por defecto | 2,69 % | 2 685 | 13,2 MiB | 0 | 0 / 0 |
Desliza en horizontal para ver todas las columnas
Eso está por encima del presupuesto de 2 % de un núcleo y dentro
del de 16 MiB de RSS. La campaña del 2026-09-15 estaba por encima en los dos, con
un anillo de 300 s y un límite de memoria fijo, antes de que 1.0.6 trajera el anillo de 60 s y el
límite derivado. El presupuesto de imagen es 8 MiB; la imagen publicada de
1.2.1 para arm64 mide 6,38 MiB (image). El
presupuesto es orientativo, no un contrato: el coste depende del equipo, del conjunto de fuentes y
del tamaño del anillo.
Dos reglas mantienen honesta una cifra de coste. Espera primero a que se llene el anillo
(BUFFER_S): en el RB5009, con un límite blando de memoria de 14 MiB, una lectura tomada en el primer
minuto tras la instalación dio un 1,47 % de un núcleo frente a un 9,38 % en
régimen estacionario. Y lee el coste del /metrics del colector, o de cpu_us y rss en
mikroscope_self en el almacén que uses, en vez de un /snapshot grande, cuya respuesta de ~1,9 MB
tiene que serializar el agente. El procedimiento está en
Coste del agente.
Coste por configuración
Sección titulada «Coste por configuración»Todas las filas se midieron en el mismo RB5009 a 10 Hz, y cada una es una ventana sin dispersión registrada.
| Configuración | CPU de un núcleo | RSS | Medido | Nota |
|---|---|---|---|---|
| Cada fuente leída en cada tick | 2,43 % | no registrado | 2026-09-12 | por encima del presupuesto |
Anillo lleno, MEM_LIMIT_MB 14 |
9,38 % (9 374 µs/muestra) | no registrado | 2026-09-12 | un anillo de 300 s de líneas de unos 2,4 kB, la línea de esa fecha, ocupa ~7,3 MB; el GC de Go corre sin pausa |
Anillo lleno, --mem-limit-mb 40, --memory-max 64M |
1,39 % (1 388 µs/muestra) | 25,13 MiB | 2026-09-12 | 0 ticks retrasados |
Contadores PMU activados, un forward en marcha escribiendo en InfluxDB |
1,72 % | no registrado | 2026-09-12 | 0 ticks retrasados; 2 400 muestras reenviadas, 0 huecos, 0 descartes |
| Los valores por defecto de la instalación | 2,69 % | 13,2 MiB | 2026-09-18 | la cifra de arriba |
Desliza en horizontal para ver todas las columnas
Campañas
Sección titulada «Campañas»Cada campaña en una entrada: el equipo, la versión de RouterOS, la fecha y las condiciones, las cifras que citan de ella las guías y lo que encontró. Una cifra de una guía enlaza aquí su campaña.
Coste y cadencia
Sección titulada «Coste y cadencia»Cadencias con la configuración de serie
Sección titulada «Cadencias con la configuración de serie»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · · ventanas de 300 s en régimen estacionario (con el anillo ya lleno), conjunto completo de fuentes, la configuración que se envía —anillo de 60 s, límite de memoria derivado de él y el tope de contenedor de serie de 64M— con el colector reenviando a InfluxDB 3
read.under2ms97,7 %read.floorOver5ms1,45 %read.100hz.meanMs1,2 msread.100hz.worstMs17,9 msload.ordinary19 Mbit/srun.10hz.cpu2,69 %run.10hz.rss13,2 MiBrun.10hz.usPerSample2 685 µsrun.10hz.slippedPct0,000 %run.20hz.cpu4,61 %run.20hz.rss15,4 MiBrun.20hz.usPerSample2 303 µsrun.20hz.slippedPct0,000 %run.50hz.cpu9,63 %run.50hz.rss23,3 MiBrun.50hz.usPerSample1 926 µsrun.50hz.slippedPct0,000 %run.100hz.cpu16,83 %run.100hz.rss45,7 MiBrun.100hz.usPerSample1 684 µsrun.100hz.slippedPct0,017 %run.50hz-floor.cpu22,56 %run.50hz-floor.rss25,1 MiBrun.50hz-floor.usPerSample4 511 µsrun.50hz-floor.slippedPct0,027 %run.100hz-floor.cpu42,70 %run.100hz-floor.rss49,5 MiBrun.100hz-floor.usPerSample4 270 µsrun.100hz-floor.slippedPct0,593 %
Seis ventanas de 300 s, a 10, 20, 50 y 100 Hz y a 50 y 100 Hz con FLOOR_HZ, ninguna de las cuales
perdió una muestra: Techo de muestreo tiene la tabla. La WAN
llevaba de media unos 19 Mbit/s durante los 44 minutos de la campaña, con picos
de 933 Mbit/s.
Cadencias hacia tres destinos
Sección titulada «Cadencias hacia tres destinos»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · · ventanas de 60 s en régimen estacionario (con el anillo ya lleno), conjunto completo de fuentes, colector reenviando a la vez a fichero, a una exposición Prometheus y a InfluxDB 3
Cinco ejecuciones de cadencia a 10, 50 y 100 Hz con el colector escribiendo a la vez en un fichero,
en una exposición Prometheus y en InfluxDB 3; todos los destinos informaron de 0 huecos y 0
descartes. El valor por defecto de la instalación a 10 Hz de esa fecha costaba un 2,85 % de un núcleo
y 31,3 MiB de RSS, con un anillo de 300 s y un límite de memoria fijo de 40 MiB; 50 Hz necesitó
--memory-max 96M y 100 Hz 128M. La WAN llevaba unos 30 Mbit/s, por la tarde. La cifra de la
instalación por defecto que citan las guías es de rates-2026-09-18, no de esta campaña.
Límite de memoria y recolector
Sección titulada «Límite de memoria y recolector»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · · 10 Hz, anillo de 300 s lleno, las mismas fuentes en las dos ejecuciones; solo cambian los límites de memoria
gc.tight.cpu9,38 %gc.tight.us9 374 µsgc.roomy.cpu1,39 %gc.roomy.us1 388 µs
El mismo agente, anillo y fuentes con un límite blando de 14 MiB y después con margen: Coste por configuración tiene las dos filas.
Línea del anillo con todas las fuentes
Sección titulada «Línea del anillo con todas las fuentes»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · · una línea del anillo con todas las fuentes activas, privileged, 10 Hz, 4 núcleos, IRQ_TOP_K=8 —incluidos el PMU y la propia temporización del muestreador, que la medición del 2026-09-12 no tenía
ring.lineKB3,5 kBring.lineBytes3 230 Bring.lineChargedBytes3 456 Brelay.maxBatch13
3 230 B medidos, cobrados desde la clase de tamaño de 3 456 B de Go. Los 2 439 B del 2026-09-12 subestimaban el anillo un 35 %, y el agente funcionaba con 32,9 MiB de RSS donde bastaban 24,3. Una línea sin PMU cuesta un 35 % menos. El tamaño de las líneas con los suelos por fuente actuales no se ha medido.
Primera medición de la línea del anillo
Sección titulada «Primera medición de la línea del anillo»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · · la línea media precodificada del anillo con todas las fuentes de esa fecha, las lentas refrescadas a 1 Hz, privileged, 10 Hz, 4 núcleos, IRQ_TOP_K=8
La línea media antes de que llevara la PMU y la temporización del propio muestreador, redondeada a unos 2,4 kB en las guías de esa fecha.
Bucle de shell de busybox
Sección titulada «Bucle de shell de busybox»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · Linux 5.6.3 · · un bucle de shell de busybox leyendo a 10 Hz el conjunto de ficheros que leía entonces el agente, siete ficheros, con un fork por iteración, en un contenedor del router; dos ejecuciones de 60 s
busybox.cpu2,40–2,48 %procread.ms0,77 ms
Dos ejecuciones de 60 s, 2,40 y 2,48 % de un núcleo, del cpu.stat del cgroup frente a
/proc/uptime; las lecturas en sí tardaban unos 0,77 ms por muestra. No se ha vuelto a medir con el
conjunto de fuentes actual del agente:
Coste del agente.
Coste de una conexión SSH
Sección titulada «Coste de una conexión SSH»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.1 · · una conexión ssh, mientras dura
ssh.connectCpu20–27 %
Medido antes de que existiera el agente, con RouterOS 7.24.1. Con 7.24.2, el 2026-09-11, el mismo
coste apareció en /tool profile como un 17–33 % en una o dos instantáneas, no en una ventana medida:
Coste de SSH.
Perfil del router con la capa de la API
Sección titulada «Perfil del router con la capa de la API»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · · /tool profile duration=60s cpu=total, una vez con el colector parado y otra con él en marcha con --interfaces bridge,; descartadas las cinco primeras instantáneas de un segundo de cada perfil, porque llevan la conexión SSH que lo pidió
Un perfil de 60 s por condición, sin dispersión: Coste de la capa API.
Tamaño de la imagen publicada
Sección titulada «Tamaño de la imagen publicada»· tar de la imagen arm64 de la versión v1.2.1 publicada, el fichero que carga el router
image.size6,38 MiB
Medido con ls -l sobre el artefacto de la versión v1.2.1, con su suma de comprobación verificada
contra el checksums.txt firmado: 6 690 304 B, de los que el binario del agente ocupa 6 684 832 B.
Los tar de armv5 y armv7 miden 7 214 592 B y el de amd64 7 222 784 B. El trabajo agent-size de la CI
mantiene el binario del agente, que es todo lo que lleva la imagen, por debajo de 8 MiB en arm64,
armv7 y amd64.
Tamaño de la imagen en 1.0.0
Sección titulada «Tamaño de la imagen en 1.0.0»fecha no registrada · tamaño de la imagen del agente de la versión 1.0.0
image.size.v1006,1 MiB
La cifra que dan las notas de la versión 1.0.0; la v1.0.0 se etiquetó el 2026-09-16. Las imágenes entre ella y la 1.2.1 no tienen medida propia.
Kernel y fuentes
Sección titulada «Kernel y fuentes»Ficheros de contabilidad del kernel
Sección titulada «Ficheros de contabilidad del kernel»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · Linux 5.6.3 · · /proc/pressure y /proc/schedstat ausentes
La columna irq de /proc/stat vale siempre 0 en este kernel, así que el tiempo de IRQ hardware
está dentro de system. USER_HZ es 100, así que un tick son 10 ms y los escalones de ocupación de
las guías son aritmética a partir de él. Los ficheros que dentro del contenedor son del router se
establecieron ese mismo día (Vista desde el contenedor).
Contenedor de descubrimiento privilegiado
Sección titulada «Contenedor de descubrimiento privilegiado»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · Linux 5.6.3 · · un contenedor de descubrimiento privilegiado leyendo una vez el /proc del host, antes de que el agente leyera slabinfo
conntrack.slabDiscovery6 582
La ronda que no encontró ningún camino de trazado (Kernel y PMU), y cuyo slabinfo
es el de testdata/proc/rb5009: nf_conntrack 6 582 activos de 8 075.
Espacio de red con privileged
Sección titulada «Espacio de red con privileged»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · · privileged=yes no cambia el espacio de nombres de red
Dentro del contenedor /proc/net/dev contaba la veth, 4 paquetes mientras el router reenviaba
millones, con privileged=yes y sin él.
Cadencias de las fuentes en una noche
Sección titulada «Cadencias de las fuentes en una noche»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · Linux 5.6.3 · · una captura de 10,5 h a 50 Hz durante una noche en reposo, con el reloj fijo
thermal.quantumC0,42 °C
La captura que fijó el suelo de 6 Hz al que se ralentiza /proc/slabinfo, la frecuencia a la que
cambiaba su caché más rápida, nf_conntrack. Los niveles de memoria se movían unas 24 veces por
segundo. Es una placa, una noche en reposo, con el reloj fijado en el ajuste del mantenedor: «cpufreq
nunca cambió» significa que no cambió esa noche.
Ventana de promedio de `cpu-load`
Sección titulada «Ventana de promedio de `cpu-load`»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · Linux 5.6.3 · · /system/resource consultado a 1 Hz frente a la proporción de ocupación por núcleo del agente a 10 Hz, en dos horas distintas
cpuLoad.window11,0 scpuLoad.delay10,6 scpuLoad.r10,9825cpuLoad.samples13 499cpuLoad.window21,1 scpuLoad.delay20,1 scpuLoad.r20,9734cpuLoad.samples23 594
El mejor ajuste de cada hora: una media móvil de 1,0 s que llegó a la
API con 0,6 s de retardo (r = 0,9825
sobre 3 499 muestras de la API), y una media
de 1,1 s que llegó con 0,1 s de retardo
(r = 0,9734 sobre 3 594). /system/resource publica
cpu-load como un porcentaje entero, y la serie de la API se correlacionó con la proporción de
ocupación por núcleo del agente, los mismos jiffies de /proc/stat, para una serie de longitudes de
ventana y retardos. Ensanchar la ventana solo empeoró el ajuste: 1,5 s dio 0,955; 2 s, 0,919; 5 s,
0,822; y 8 s, 0,791. Una media de sesenta segundos queda descartada dos veces: su correlación es
0,238, y en el mayor salto de carga del día el kernel pasó de 5 % a 27 % en un segundo y cpu-load de
5 a 26 en ese mismo segundo, y de 22 % a 6 % al bajar con la misma rapidez. La
documentación de /system/resource
de MikroTik define cpu-load como el porcentaje de recursos de CPU usados, sumando todas las CPU, y
no nombra ninguna ventana (leída el 2026-09-24).
Grabación y transporte
Sección titulada «Grabación y transporte»Grabación de un bucle de script
Sección titulada «Grabación de un bucle de script»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · · un record de 60 s a 10 Hz, 600 muestras en 59,9 s, un bucle de script de RouterOS lanzado por ssh y el log del router añadido como marcadores
Exactamente 600 muestras, 0 huecos y un desfase de reloj de −7 ms. Un bucle de RouterOS por script
(:for … 400 000) se vio como la carga de un núcleo entero al 100 % de t = 21,0 a 25,8 s, con la
muestra de 25,8 s marcando alrededor del 60 %, y el inicio y el final resueltos a 100 ms. Los
marcadores del log del router explicaron una meseta de 2 s entre 15 y 17 s que nadie había provocado:
el planificador ensure-ipv6-nd-prefix. Las horas del log llegaron por la API como fechas completas
(verificado).
Grabación en reposo
Sección titulada «Grabación en reposo»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · · un record de 70 s a 10 Hz, 700 muestras en 69,9 s, el router por lo demás en reposo, tres notas escritas en el terminal de record
La grabación de la que sale el gráfico de Línea base en reposo.
Duración de una conexión `/stream`
Sección titulada «Duración de una conexión `/stream`»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.4 · · tres conexiones GET /stream contra el agente instalado a 10 Hz, abiertas desde el equipo del operador en la LAN y mantenidas hasta que el servidor las cerró
stream.lifetime30,01–30,06 sstream.lines304–306
Agente 1.0.9 a 10 Hz. Cada conexión terminó en el tiempo de escritura de 30 s del servidor, le
quedara lo que le quedara por enviar, así que quien consuma /stream reconecta con el último seq
que vio.
Límite del fetch del relay
Sección titulada «Límite del fetch del relay»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · Linux 5.6.3 · · /tool fetch output=user llamado por la API binaria; cada llamada tardó o unos 3 ms o alrededor de 1 s, y más o menos la mitad tardó 1 s
relay.replyMaxBytes64 512 B
/tool fetch output=user truncó el cuerpo sin avisar en 64 512 B con cuerpos de 64 K, 256 K, 1 M y
4 M.
Tamaño de una muestra en protocolo de líneas
Sección titulada «Tamaño de una muestra en protocolo de líneas»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · Linux 5.6.3 · · una muestra del kernel a 10 Hz renderizada en protocolo de líneas de InfluxDB, con el conjunto de fuentes que tenía el agente en esa fecha
Unos 1,2 KiB por muestra, la cifra a partir de la cual los destinos de InfluxDB y Telegraf dimensionan su presupuesto de bytes. No medido por encima de 10 Hz, ni vuelto a medir con el conjunto de fuentes actual.
Red y fallos
Sección titulada «Red y fallos»Lecturas de los casos reales
Sección titulada «Lecturas de los casos reales»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · Linux 5.6.3 · · agente a 10 Hz en un contenedor privilegiado efímero
loop.eventsBefore1,49 /sloop.eventsAfter0,03 /sloop.helloGap2,00–2,01 sconntrack.slab6 287
Las lecturas sobre las que se construyen los casos reales, de un
kernel aarch64 en una placa con 1 GB de RAM; donde se provocó un fallo, el caso real dice cómo. Tres
casos llevan además un gráfico del almacén InfluxDB de referencia, cuyo historial empieza el
2026-09-19: la vuelta del bucle, la comprobación cruzada de conntrack y el puerto que pierde tramas.
El puerto que pierde tramas es una campaña aparte, una semana después, leída en los contadores de
puerto de la capa de la API y no en el agente. time_squeeze no era cero ni siquiera en reposo.
Mientras el reflejo de capa 2 estaba activo, el log del kernel iba
a 1,49 /s, y una pareja «blocking state» y luego «learning state» llegaba
dentro de un mismo tick de 100 ms con el mismo nivel, así que su orden dentro del tick es la señal. La
tabla de conntrack tenía 6 287 entradas, un 0,65 % del techo de 966 656
que el kernel informó el 2026-09-14.
Distribución de los squeezes de softnet
Sección titulada «Distribución de los squeezes de softnet»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · · 3 738 704 muestras por CPU en 24 h a 10 Hz, time_squeeze de softnet por muestra, 0 descartes en toda la ventana
squeeze.backgroundOne11,2 %squeeze.backgroundTwo1,2 %squeeze.exactlyThree0,21 %
Las 24 h terminaron a las 07:00 UTC del 2026-09-16. time_squeeze era 0 en el 87,3 % de las muestras
por CPU, y una ventana móvil de esa distribución tiene un percentil 90 de 1, así que «por encima de
p90» lo cumple cualquier 2. El 2026-09-15 una condición de disparo que salta ante cualquier squeeze
saltó 92 veces en veinte minutos (RouterOS 7.24.2), y por eso squeeze no es un disparador por
defecto.
Reejecución de la regla de microrráfagas
Sección titulada «Reejecución de la regla de microrráfagas»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · · la regla reejecutada sobre 6 h de muestras almacenadas, 863 944 filas, 4 CPU
microburst.firesPerHourAtTwo77,7 /hmicroburst.firesPerHourAtThree0,5 /h
Con suelo 3 la regla siguió marcando 88 muestras para el contador de ráfagas y para derived.burst.
Cuenta de conntrack por la API
Sección titulada «Cuenta de conntrack por la API»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · Linux 5.6.3 · · la tabla de conexiones contada por la API binaria de RouterOS, /ip/, diez llamadas
conntrack.api6 212api.conntrackMs1,3 ms
La cuenta fue 6 212, el día antes de que el slab del agente marcara 6 287: el mismo orden de magnitud, que no dice nada de si las dos se siguen. Las diez llamadas tardaron una mediana de 1,3 ms, la más rápida 1,1 ms y la primera 71 ms, en frío; la hora no consta.
Contadores de puerto y de fast path
Sección titulada «Contadores de puerto y de fast path»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.2 · · contadores de puerto y de interfaz de RouterOS leídos por la API, acumulados desde el arranque o desde el último reinicio del contador de cada puerto
ether1, 2,5 GbE hacia un NAS, había recibido 255,8 GB por el cable (rx-bytes) y había entregado
29,7 GB de ellos a la CPU (driver-rx-byte) desde el último reinicio del contador del puerto; el
resto lo reenvió el chip de conmutación en hardware. Todos los puertos del switch daban una
proporción de fast path de alrededor del 100 %, con fp-rx-byte igual a driver-rx-byte con unos
pocos kB de diferencia. bridge había pasado por el fast path 211,9 GB de los 663,0 GB que llevó a la
CPU desde el arranque (32 %), y PPPoE_DIGI el 99,97 %. fp-tx-byte estaba a 0 en todas las
interfaces tras cientos de GB transmitidos (verificado).
Desbordamiento del puerto antes y después
Sección titulada «Desbordamiento del puerto antes y después»Medido en RB5009UG+S+ · 4 × 1,4 GHz Cortex-A72 · RouterOS 7.24.4 · · ether1, el puerto de 2,5 GbE del NAS, en intervalos de contador de 10 s; las cifras de antes son las tres horas previas al arreglo y las de después los 39 minutos siguientes, con la misma carga
overflow.shareBefore0,502 %overflow.perHourBefore5 399overflow.occupancy0,36 %overflow.burstRate8,96 Mbit/s
El caso real es Puerto que pierde tramas.
Medido sin campaña propia: el 2026-09-15 una ráfaga tuvo un pico de 736 paquetes en una muestra de 20 ms, una muestra a 50 Hz, frente a una mediana de 28.
Comportamiento de RouterOS verificado
Sección titulada «Comportamiento de RouterOS verificado»Hechos de sí o no sobre RouterOS en los que se apoyan las guías, cada uno comprobado una vez, con dónde y cuándo.
Un usuario read ve las envlists
Sección titulada «Un usuario read ve las envlists»Por la API binaria, /container/print devolvió todas las propiedades de todos los contenedores, cmd y envlist incluidas, a un usuario con solo read,api, el usuario mikroscope; solo se imprimieron los nombres de las propiedades, y no se comprobó si ese usuario lee los valores de /container/envs (RB5009UG+S+, RouterOS 7.24.2, ).
Política test para fetch y profile
Sección titulada «Política test para fetch y profile»/tool fetch y /tool profile exigen ambos la política test (RB5009UG+S+, RouterOS 7.24.2, ).
Valores entre comillas en find
Sección titulada «Valores entre comillas en find»En un find de RouterOS, los atributos de dirección y de puerto solo coinciden cuando su valor va entre comillas, y una palabra suelta se lee como nombre de variable: sobre las mismas 15 reglas dstnat (RouterOS 7.24.4, 2026-09-21), protocol=tcp encontró 0 y protocol="tcp" encontró 10 (RB5009UG+S+, RouterOS 7.24.2, ).
Las reglas de exposición llegan al agente
Sección titulada «Las reglas de exposición llegan al agente»Una regla dst-nat más una regla accept en forward llegan al agente desde la LAN, y las dos se retiran por su etiqueta (RB5009UG+S+, RouterOS 7.24.2, ).
La LAN llega a la veth
Sección titulada «La LAN llega a la veth»La LAN llega a la veth en cuanto la veth entra en la lista de interfaces LAN y el /30 en la lista de direcciones LANs (RB5009UG+S+, RouterOS 7.24.2, ).
El borrado del contenedor vuelve antes
Sección titulada «El borrado del contenedor vuelve antes»/container/remove vuelve antes de que el contenedor haya desaparecido, y un /file/remove lanzado mientras tanto no hace nada, sin avisar (RB5009UG+S+, RouterOS 7.24.2, ).
Borrar el tar vuelve a extraer
Sección titulada «Borrar el tar vuelve a extraer»Con ignore-remote-image-change=no, borrar el tar de la imagen hace que RouterOS detenga y elimine el contenedor y lo vuelva a extraer minutos después (RB5009UG+S+, RouterOS 7.24.2, ).
La ida y vuelta deja /export intacto
Sección titulada «La ida y vuelta deja /export intacto»doctor, install, status, upgrade y uninstall, en ese orden, dejaron el /export del router idéntico byte a byte, salvo sus líneas de cabecera #, comparado por hash en memoria y sin escribirlo nunca a disco (RB5009UG+S+, RouterOS 7.24.2, ).
Instalar en tmpfs no escribe en la NAND
Sección titulada «Instalar en tmpfs no escribe en la NAND»Un disco tmpfs aloja el tar de la imagen y la raíz del contenedor sin escribir en la NAND: write-sect-since-reboot se quedó en 58 279 durante la instalación, el funcionamiento y la retirada (RB5009UG+S+, RouterOS 7.24.2, ).
Privileged conserva red y PID
Sección titulada «Privileged conserva red y PID»privileged=yes quita el espacio de nombres de usuario del contenedor, pero no el de red ni el de PID (RB5009UG+S+, RouterOS 7.24.2, ).
Host del registro en la referencia
Sección titulada «Host del registro en la referencia»Un host de registro dentro de remote-image= manda sobre /container/, y docker.io se descarga como registry-1.docker.io: con registry-url=https://, una referencia en registry.invalid quedó registrada como registry=registry. y falló con resolving error, mientras que la imagen 1.2.2 del agente escrita como docker.io/… y como registry-1.docker.io/… quedó registrada como registry=registry-1. y terminó en download/extract done, con su capa arm64 de 2 799 648 bytes; /container/config quedó igual que antes. Los contenedores se crearon en una veth temporal, nunca se arrancaron y se retiraron después (RB5009UG+S+, RouterOS 7.24.4, ).
Descarga de Docker Hub sin login
Sección titulada «Descarga de Docker Hub sin login»Con el usuario y la contraseña de /container/config borrados, RouterOS descargó de Docker Hub la imagen 1.2.2 del agente de forma anónima, tanto como remote-image=registry-1. como sin host a través de registry-url=https://, y las dos terminaron en download/extract done 5 s después del alta; después se restauró la configuración y se comprobó que era idéntica (RB5009UG+S+, RouterOS 7.24.4, ).
Horas del log por la API
Sección titulada «Horas del log por la API»Por la API, /log/print devuelve el time de una entrada como fecha y hora completas y sin zona, 2026-09-12 02:21:24, y acepta ese formato en una consulta ?>time= (RB5009UG+S+, RouterOS 7.24.2, ).
Claves de pérdidas de monitor-traffic
Sección titulada «Claves de pérdidas de monitor-traffic»/interface/ devuelve rx-drops, tx-drops y tx-queue-drops por segundo y ninguna clave de errores (RB5009UG+S+, RouterOS 7.24.2, ).
rx-overflow solo en los contadores de puerto
Sección titulada «rx-overflow solo en los contadores de puerto»ether1 llevaba 652 364 sucesos rx-overflow, en aumento, en sus contadores de puerto mientras monitor-traffic no devolvía ninguna clave de errores para ese puerto: esa cuenta solo llega a un consumidor por los contadores de puerto (RB5009UG+S+, RouterOS 7.24.2, ).
Planos del puerto y del bridge
Sección titulada «Planos del puerto y del bridge»Un puerto ether de un bridge cuenta su cable, incluidas las tramas que el chip de conmutación reenvió por hardware, y el bridge cuenta su lado de CPU, así que ninguno es un subconjunto del otro: desde el último reinicio del contador del puerto, ether1 había recibido 255,8 GB por el cable (rx-bytes) y había entregado 29,7 GB de ellos a la CPU (driver-rx-byte) (RB5009UG+S+, RouterOS 7.24.2, ).
fp-tx-byte se queda a cero
Sección titulada «fp-tx-byte se queda a cero»fp-tx-byte marcaba 0 en todas las interfaces tras cientos de GB transmitidos, mientras fp-rx-byte sí contaba; no está establecido por qué RouterOS lo deja a 0 (RB5009UG+S+, RouterOS 7.24.2, ).
Rutas del host en un contenedor privilegiado
Sección titulada «Rutas del host en un contenedor privilegiado»Un contenedor privilegiado con /proc, /sys y / del host montados leyó cero PID en el /proc del host y no encontró class/net en su /sys, así que los espacios de nombres aguantaron; el / del host sí se montó, y expuso el sistema de ficheros de la flash de RouterOS, configuración y ficheros, secretos incluidos. Se hizo con el consentimiento del mantenedor (RB5009UG+S+, RouterOS 7.24.2, ).
La credencial va si el host coincide
Sección titulada «La credencial va si el host coincide»RouterOS presenta el usuario y la contraseña de /container/config para una referencia cuyo host es registry-url tal como está escrito: con una credencial errónea a propósito, la imagen del agente 1.3.1 nombrada como registry-1. falló con auth error con registry-url=registry-1., y se descargó de forma anónima con https://, el valor de los ejemplos de MikroTik, y con el mismo terminado en barra. Un router al que se dio una credencial no volvió a intentar la descarga de forma anónima (CHR x86_64, RouterOS 7.24.4, ).
WebFig no tiene campo para ignore-remote-image-change
Sección titulada «WebFig no tiene campo para ignore-remote-image-change»Los formularios New Container y de edición del contenedor de WebFig no muestran campo para ignore-remote-image-change, con File o Remote Image puestos o no; lo pone el terminal (CHR x86_64, RouterOS 7.24.4, ).
Un set del contenedor reinicia restart-policy
Sección titulada «Un set del contenedor reinicia restart-policy»Un /container/set que no nombra restart-policy (de ignore-remote-image-change, de comment, de logging) la devolvió de on-failure a always sin cambiar nada más de lo que muestra /container/print detail; un set que la nombra la conservó, igual que Apply u OK en el formulario de edición de WebFig. La CLI nunca ejecuta /container/set (CHR x86_64, RouterOS 7.24.4, ).
WebFig muestra los valores de env
Sección titulada «WebFig muestra los valores de env»WebFig muestra en claro el valor de una entrada de /container/envs, en la lista Envs y en su formulario, también con la clave TOKEN (CHR x86_64, RouterOS 7.24.4, ).
WebFig no tiene página Device Mode
Sección titulada «WebFig no tiene página Device Mode»El menú System de WebFig no tiene página Device Mode, así que el modo de dispositivo se pone desde el terminal (CHR x86_64, RouterOS 7.24.4, ).
fetch as-value devuelve el cuerpo
Sección titulada «fetch as-value devuelve el cuerpo»:put ([/tool/fetch url="http://172.30.10.2:9123/, ejecutado en el router, imprimió el JSON de /healthz del agente, en una sesión ssh, en el terminal de WebFig y al final de un script pegado (CHR x86_64, RouterOS 7.24.4, ).
La pregunta de la licencia se lleva las primeras líneas
Sección titulada «La pregunta de la licencia se lleva las primeras líneas»El primer inicio de sesión interactivo tras un reinicio pregunta Do you want to see the software license? [Y/n]: antes del indicador ] >. Un script pegado en esa pregunta perdió sus primeras líneas: una o dos líneas de comentario de la cabecera, y después un fragmento ejecutado como orden (bad command name . o syntax error); el bloque { … } del script de instalación se ejecutó igualmente e instaló, y el script de desinstalación retiró igualmente todo (CHR x86_64, RouterOS 7.24.4, ).
Sin probar
Sección titulada «Sin probar»Lo que no cubre aquí ninguna ejecución, medida ni comprobación. Una guía que afirma una de estas cosas como comportamiento esperado enlaza esta lista.
Hardware y versiones
Sección titulada «Hardware y versiones»- Una segunda placa de cualquier tipo. El hEX S (2025), RouterOS de 32 bits sobre un chip ARM64, que
es para lo que existe la compilación
linux/arm/v5del agente, no ha llegado, así que ni la ruta del desbordamiento de contadores de 32 bits ni ninguna de las dos imágenes ARM de 32 bits se han ejecutado en RouterOS. Un informe de placa desde otra placa es lo que cambia esto. - RouterOS x86 en hardware: la imagen amd64 solo se ha ejecutado en QEMU, en el CHR x86_64 del laboratorio y en RouterOS x86 instalado desde la ISO de MikroTik.
- Ningún RouterOS anterior a 7.24 más allá de la comprobación de versión de
doctor, que S17 ejecutó en un CHR con 7.23.7, y ninguna de las cifras de 7.24.2 vuelta a medir sobre 7.24.4. - Nada que necesite un reinicio del RB5009, que espera a una ventana de mantenimiento. Así que no está
probado en hardware que una instalación persistente sobreviva a un reinicio con
start-on-boot=yes. En el CHR del laboratorio volvió a responder en menos de 90 s tras un corte de corriente (S7, en las dos arquitecturas). - Qué ficheros están en un espacio de nombres en otra versión de RouterOS u otra placa: cada fila de Vista desde el contenedor se leyó en un único RB5009 con 7.24.2.
- Una placa con sensores hwmon, o un RouterOS posterior que construya los contenedores de otra manera: el conjunto de sensores, las 38 capacidades y la correspondencia de uid se leyeron en un único RB5009 con 7.24.2.
- La correspondencia de puertos en otra placa: el desplazamiento de uno, la posición de la jaula
SFP+ y la reutilización de
port 7se observaron en un RB5009UG+S+ con 7.24.2, y el agente no los aplica a ninguna otra placa. - Los caminos de PSI y
schedstaten un router: el kernel del RB5009 no tiene ninguno de los dos. El conjunto de contadores de la PMU solo se conoce en el Cortex-A72 del RB5009 y en el equipo de desarrollo amd64. - Cualquier cadencia de las fuentes en otro equipo o con otra carga: las cadencias son las del RB5009,
con 7.24.2. Vuelve a medirlas con
FLOOR_HZigual a la cadencia del muestreador. - Qué claves de pérdidas y qué contadores devuelve otra versión de RouterOS u otra placa.
- Lo que ahorra
--goarm 7frente a la compilación ARMv5: ningún hardware ARM ha ejecutado ninguna. - Las entradas de la envlist en un RouterOS anterior a 7.24: mikroscope escribe
key=, porquename=falló en el RB5009 con 7.24.2, y no se probó cómo toma una u otra una 7.x anterior. - Un tráfico mayor que la carga corriente del RB5009: unos 19 Mbit/s en la WAN durante la campaña del 2026-09-18. No se afirma ninguna cadencia en otra placa.
Instalación y actualización
Sección titulada «Instalación y actualización»- En el RB5009, una descarga de GHCR sin credencial de registro, y cualquier descarga de GHCR con el
host dentro de
remote-image=: su única ejecución contra GHCR tomó el host deregistry-url. El CHR del laboratorio hizo las dos con 7.24.4 (Rutas de instalación probadas). - Qué credencial presenta RouterOS a un host que solo se nombra en
remote-image=cuandoregistry-urlnombra otro. La única ejecución con un host distinto del deregistry-url, el 2026-09-24, nombrabaregistry.invalid, que nunca se resolvió. Con el mismo host, el laboratorio mostró que RouterOS solo la presenta cuandoregistry-urlse escribe como el host a secas (verificado). - En el RB5009: un
installo unupgradecompleto que envíe la referencia completa, unregistry-urlcon su valor de fábrica y la referencia completa en cualquier RouterOS que no sea 7.24.4. El CHR del laboratorio ejecutó las dos cosas con la 1.3.1 sobre 7.24.4. - Una descarga a través de un espejo o una caché intermedia nombrados en la referencia.
install,statusyuninstallde la 1.4.0 en adelante en cualquier hardware, y el script con sus guardas: solo se han ejecutado en los CHR del laboratorio. En el RB5009, elupgradede la 1.6.0 leyó del router el manifiesto de instalación y la arquitectura (--arch auto), y sudoctorejecutó todas las comprobaciones.--ssh-optionyMIKROSCOPE_SSH_OPTIONScontra cualquier router: la CLI del laboratorio se conecta con elssh_configpropio del laboratorio, y solo las pruebas unitarias pasan la opción.- Que
--extract-timeoutse agote, lo que conserva el tar, en cualquier router. - La comparación de hosts de registro de
doctorcontra un router real: solo se ha ejecutado contra respuestas de router falsas en los tests. - Si un usuario
read,apipuede leer los valores de la envlist en/container/envs. - La ida y vuelta idéntica byte a byte en hardware: en cualquier placa que no sea el RB5009, en el
RB5009 con cualquier RouterOS salvo 7.24.2, con
installyupgradesin--ephemeral, o con los ajustes actuales del contenedor (privileged=yes,memory-max=64M, las entradas de la envlistMEM_LIMIT_MB,CAPTURE_MB,TRIGGERSyFLOOR_HZ): en el RB5009 se hizo conmemory-max=32M. Desde entoncesinstall,statusyuninstallse han ejecutado allí en 7.24.4. En el CHR 7.24.4 del laboratorio,make roundtripla ejecuta con--ephemeral(2026-09-26); S2 y S3 ejecutaninstall,upgradeyuninstallsin él, conprivileged=yes,memory-max=64M,MEM_LIMIT_MByCAPTURE_MB, y S5 importa un script que además escribeTRIGGERSyFLOOR_HZ; cada uno termina con el/exportigual al de su inicio, salvo la líneakeymat-providerde RouterOS (las dos arquitecturas, 2026-09-27). - Cortafuegos distintos del del RB5009, donde el 2026-09-11 bastaron las dos pertenencias a listas, y
de los perfiles del laboratorio. Un cortafuegos con otras reglas de descarte en
raw,inputoforwardpuede descartar el tráfico del contenedor en otro punto, einstallno añade nada para eso más allá de las dos pertenencias. No se comprobó si la configuración de fábrica de un router lleva las dos reglas raw. --exposedesde fuera de la LAN: solo se probó una máquina de la LAN llegando a la dirección LAN del router. Si algo de fuera de la LAN llega a esa dirección depende del resto del cortafuegos, y no se probó ningún camino así.- Winbox: la página de instalación por WebFig dice que Winbox tiene los mismos menús y campos, y no se
ejecutó ningún Winbox. Las reglas de
--exposepor los formularios NAT y Filter Rules de WebFig, un script entero pegado en el terminal de WebFig o de Winbox, y WebFig en cualquier RouterOS salvo 7.24.4. - Los scripts del generador, la instalación manual por terminal y la instalación por WebFig en el laboratorio arm64 o en el RB5009.
Grabación y captura
Sección titulada «Grabación y captura»- Una grabación por encima de 10 Hz: las ejecuciones sin pérdidas a 20, 50 y 100 Hz fueron del colector, que usa el mismo tamaño de lote. Una grabación a través del relay, a cualquier cadencia.
- El rendimiento del relay. Con idas y vueltas de
/tool fetchde cerca de 1 s en la mitad de las llamadas y unos 3 ms en el resto (medido en el RB5009 con 7.24.2), la aritmética da del orden de 26 muestras por segundo, menos cuando las llamadas lentas se agrupan. El límite del relay y el aviso de arranque están leídos del código (2026-09-15), no medidos en un equipo. El límite del relay y su fracción de 1 s en cualquier RouterOS salvo 7.24.2. - El coste de un disparo en el equipo; 3 µs para una ventana de 10 s a 10 Hz es la estimación del diseño. Cómo se comporta el agente bajo una tormenta sostenida de disparos. Cualquier captura a 50 o 100 Hz. Los tamaños de captura de Captura por disparo son aritmética a partir del tamaño de línea, no tamaños de capturas tomadas en el RB5009.
Colector y destinos
Sección titulada «Colector y destinos»- Destinos alimentados desde el RB5009 hacia un backend en marcha: solo fichero, Prometheus e InfluxDB 3. Loki, un receptor OTLP, carbon, Elasticsearch, OpenSearch, Telegraf, PostgreSQL y TimescaleDB no han recibido muestras del router en ninguna ejecución registrada. OpenSearch, las hypertables de TimescaleDB y la salida estándar nunca se han probado contra un almacén real; solo los cubren las pruebas de contrato de bytes.
- Un Elasticsearch u OpenSearch que exija autenticación. El Elasticsearch de la batería de
contenedores funciona con la seguridad desactivada, así que la cabecera
Authorizationque se construye a partir deMIKROSCOPE_ELASTIC_AUTH, autenticación básica parauser:passwordyApiKeyen otro caso, no tiene ninguna ejecución registrada contra uno: ni desde el destino ni desde la fuente de datos de Elasticsearch que construyen--grafanaydashboards publish, que envía la misma cabecera desde la 1.5.0. Las pruebas unitarias fijan ambas formas, y la batería de extremo a extremo elApiKeydel destino contra un receptor simulado. Esa fuente de datos tampoco se ha ejecutado contra un OpenSearch, con autenticación o sin ella. - Un TimescaleDB real: las llamadas a
create_hypertablesiguen la firma documentada de TimescaleDB 2.x y no están verificadas. - El tamaño del destino SQL en un router. Las cifras del fixture (1 375 B de SQL para un evento del
kernel frente a 716 B de protocolo de líneas, 1 138 B para un evento de la API frente a 608 B, unos
14 KiB/s a 10 Hz más la capa de la API a 1 Hz tras una cabecera de 5,6 KiB, 2 749 B con las fuentes
privilegiadas) cubren dieciocho de las cuarenta y tres tablas que escribe el destino: once se
añadieron después del fixture, y
load,stat,buddy,mtd,api_ifcounter,api_ifinfo,trigger,derived,derived_iface,detectiony las cuatro tablasdeviceno se ejercitaron. Son anteriores a las columnasportykinddemikroscope_event. --sql - | psqlcon unpsqlque se queda atrás frente a un agente a 10 Hz, que bloquea el bucle de peticiones.- El presupuesto de la salida estándar para
json, cuyas líneas son más grandes que las del protocolo de líneas. - Un renderizado OTLP de una muestra de cuatro núcleos con un top-K real de interrupciones, una muestra de cuatro núcleos en el formato de Elasticsearch, y el presupuesto de Graphite por encima de 10 Hz.
- Una escritura en el
/api/v2/writede InfluxDB 2. El tamaño en protocolo de líneas por encima de 10 Hz o con el conjunto de fuentes actual. Si desactivar el reenvío propio del cliente HTTP evita los duplicados del 2026-09-13. - La entrega de Loki durante una tormenta del log del kernel.
- Cualquier intervalo de scrape de Prometheus que no sea 5 s, y cualquier Prometheus que no sea 3.14.
- Los 10 Hz constantes del colector frente a un agente más rápido: la referencia de ráfagas y la poda del top-K están leídas del código; el peso EWMA de 1/600 y el desalojo a las 36 000 muestras no se han visto ocurrir nunca, porque ninguna ejecución hizo que una línea de interrupción cayera del top-K y siguiera fuera.
- Los deltas a cero que se escriben junto a una proporción de fast path ausente (leído
en
internal/), y un cambio de techo o de cadencia sin cambio de hash que llega a los destinos en la siguiente repetición de cinco minutos (leído enderive/ derive.go capsHash). - El coste de PMU por paquete comparado entre dos configuraciones del router. Si los diez segundos de la referencia de ráfagas sirven en otra placa u otra mezcla de tráfico: se ajustó contra un RB5009 en un solo día. Una proporción de fast path de tx a partir de contadores en vivo.
- Detecciones provocadas con las reglas en marcha: ningún OOM kill en el contenedor, reinicio, flap de
enlace, vaciado o tormenta de conntrack, excursión térmica ni colapso de IPC. Si
rebootsaltó en el reinicio del 2026-09-19. Un flap provocado conlink-flapen marcha; los flaps del 2026-09-15 no lo estaban. - Si RouterOS calcula la ventana de un segundo de
cpu-loadsobre un reloj de pared o sobre jiffies. Si la cuenta de conntrack de la API y la del slab se siguen la una a la otra.
Otras herramientas
Sección titulada «Otras herramientas»- Ninguna de las seis herramientas de Comparado con alternativas se
ejecutó para esa página. Cada celda de sus filas es lo que dice su propia documentación o su
código, leído el 2026-09-24: mktxp en el commit
1e4412a(fechado el 2026-09-21), mikrotik-exporter en428dbfc(fechado el 2026-07-03), y el fichero MIB que MikroTik publica para RouterOS 7.24.4. No se midió lo que le cuesta a un router el sondeo SNMP, The Dude, Graphing, el Profiler, mktxp o mikrotik-exporter, con qué frecuencia puede sondearlo cada uno con utilidad, ni qué pone RouterOS enhrProcessorLoad.
Dashboards y alertas
Sección titulada «Dashboards y alertas»- Cualquier Grafana que no sea 12.3.0, 12.3.2, 13.2.1 o 13.2.2. En 12.3.0 los únicos renderizados son los del 2026-09-25; el resto del dashboard se comprobó allí solo por consulta.
dashboards publishcontra cualquier Grafana que no sea 13.2.1, y sobre algo que no sea lo queforward --grafanaacababa de crear allí: en la batería de contenedores, el 2026-09-27, se ejecutó una vez por almacén, después del colector, sin credenciales en ninguna fuente de datos, y encontró la carpeta y cada fuente de datos tal como las había dejado el colector, y las dio comounchanged. Condashboards publish, una ejecución de más de un almacén, un almacén que falla mientras los demás siguen, una fuente de datos que lleva un token o una contraseña (se escribe de nuevo en cada ejecución y se da comoupdated) y--grafana-dry-runsolo se han ejecutado en las pruebas unitarias, contra Grafanas simulados.- La altura del Overview de trece paneles en un navegador; el JSON del repositorio le da 31 unidades de cuadrícula.
- La regeneración byte a byte de los ficheros de dashboard añadidos después del 2026-09-15.
- Las anotaciones y capas de detecciones de Elasticsearch y Graphite en Grafana: solo se comprueba su JSON generado, con pruebas unitarias.
- Una pasada de renderizado sobre los dos paneles de eventos de puerto y la tabla de inventario de interfaces.
- Que una regla se resuelva: el bucle del RB5009 terminó el 2026-09-23, pero no se ha comprobado en el
historial de estados de Grafana la vuelta de
mikroscope-l2-loopa Normal. No se ha visto amikroscope-l2-loopni amikroscope-port-link-downpasar a pendiente, saltar y resolverse. - Las dos reglas que añadió 1.2.0 dentro de cualquier Grafana, su PromQL más allá de la sintaxis y el SQL de PostgreSQL de la regla de despertares.
- Los ficheros de alertas de Prometheus y PostgreSQL en cualquier Grafana, y cualquier consulta de alerta de PostgreSQL contra un PostgreSQL real: una prueba unitaria lee el esquema, no una base de datos.
- La entrega de avisos: no se configuró ningún punto de contacto, así que lo que se observó es el estado de cada regla.
- Un almacén al que le falta una tabla o una columna que lee una regla: se espera que la consulta
falle y que se aplique
execErrState: Erroren lugar de OK. Lo que hace entonces Grafana es su comportamiento de Error y No Data, no probado aquí.
Problemas conocidos
Sección titulada «Problemas conocidos»Contrastado con el código el 2026-09-24, y el flujo del resumen final otra vez con la 1.3.1 el 2026-09-26:
- El resumen final de
forwardva a stdout, el mismo flujo en el que el destino--stdoutescribe los registros, así queforward --stdout=lp | telegraftermina cada ejecución con líneas que el consumidor no puede analizar. - Un
--tokenerróneo no hace fallar la ejecución. Cada petición queda registrada como401 Unauthorized, y la ejecución termina en el plazo de--forcon código de salida 0 yforwarded 0 kernel samples. La comprobación de salud que haceforwardantes de empezar a pedir datos lee/healthz, que no necesita token, así que la supera. El mensaje es correcto; el código de salida no le dice nada a un fichero de unidad. - Números de secuencia duplicados en la ejecución nocturna del 2026-09-13. La ejecución a 50 Hz
escribió valores de
seqrepetidos en InfluxDB; los paneles llaman a esas filas “duplicate sample (seq repeated)”. La explicación más probable, sin verificar, es que el cliente HTTP de Go reenviaba un POST por una conexión reutilizada ya muerta después de que el servidor lo hubiera confirmado. Los destinos InfluxDB, Loki, OTLP, Elasticsearch y Telegraf rechazan ese reenvío, así que una conexión muerta es un error que el destino reintenta y contabiliza. Ninguna ejecución posterior a esa noche muestra si los duplicados han desaparecido. - Un tag negado dentro de un OR no devuelve nada, en silencio, en InfluxDB 3. El 2026-09-23, en el
almacén de referencia (InfluxDB 3 Enterprise desde el 2026-09-19; la versión no se anotó con la
consulta),
NOT (port='ether2' AND kind IN (…))sobremikroscope_kmsgdevolvió 0 filas donde coincidían 14, y lo mismo su forma de De Morgan y el OR explícito. Devolvió 14 en cuanto se filtró tambiénport='ether2'fuera del OR. Los paneles y las reglas que se distribuyen no usan ese patrón. - Grafana 12.3.0 nunca envía la consulta de la capa de detecciones de InfluxDB, con la tabla o sin ella: su interruptor se quedó con un indicador de carga, apagarlo, encenderlo y refrescar no envió nada, y no se dibujó ninguna marca, ni en el dashboard completo ni en una copia de un solo panel (2026-09-25). Grafana 13.2.1 la envió en el acto sobre el mismo almacén. Por qué, y si 12.3.2 hace lo mismo, no se ha investigado.
Encontrado en el laboratorio virtual
Sección titulada «Encontrado en el laboratorio virtual»Lo que encontraron la CLI y la imagen del agente 1.3.1 publicadas en el CHR del laboratorio, RouterOS 7.24.4, el 2026-09-26. Cada punto termina con lo que hace el código posterior a la 1.3.1, comprobado en el laboratorio el 2026-09-27; la 1.4.0 publica ese código, y la sección 1.4.0 del registro de cambios recoge cada cambio.
doctorcon sus valores por defecto falla tres comprobaciones en un CHR.--archvale arm64 por defecto, lo que falla solo en x86_64; la lista de interfacesLANno existe; y la comprobación «has entries» de la lista de direccionesLANsfalla con una lista vacía o inexistente, aunque su propio arreglo dice que una lista vacía está bien si no existe esa regla. Un router sin esa regla solo pasa dándole una entrada a la lista, o con--no-doctor, que se salta todas las demás comprobaciones. Tras la 1.3.1:--archvaleautopor defecto y lee la arquitectura del router, una lista de direcciones vacía ya no es un fallo, y una lista de interfaces que falta, todavía MISSING con los valores por defecto, tiene un arreglo que ofrece--iface-list none(S1).- Una lista de interfaces integrada como
static,allodynamicpasa la comprobación de existencia de doctor, y RouterOS se niega a añadirle un miembro. Tras la 1.3.1:--iface-listrechazaall,dynamicystatic; RouterOS respondecannot add to builtin list. --ephemeralnecesita un disco tmpfs, y un CHR no lista ningún disco. El arreglo de doctor,/disk/add type=tmpfs tmpfs-max-size=64M slot=tmpfs, funcionó, y la instalación fue atmpfs/conmikroscope/ mikroscope start-on-boot=no. Tras la 1.3.1: igual, ydoctoravisa además cuando se fuerza el arranque con el router sobre una raíz en un disco tmpfs, que un reinicio vacía.uninstallcompite con la parada del contenedor. Detiene el contenedor, espera 4 s fijos y lo elimina, y el agente tardó 0 s en pararse seis veces, 4 s cuatro veces y 5 s una (log de RouterOS, resolución de 1 s): 5 de 15 primeros intentos en x86_64 fallaron confailure: cannot remove running. Con un cliente en/streamfalló siempre en las dos arquitecturas, porque el cierre HTTP del agente lo espera hasta 5 s. Los pasos siguientes se ejecutaron igualmente, y un segundouninstalllo limpió todo cada vez. Tras la 1.3.1: la retirada espera hasta 30 s mientras el contenedor estárunningostopping, y cada primer intento quedó limpio (Tiempos del laboratorio).- Un directorio
mikroscopevacío se queda en/filedespués de cadauninstall: el padre del root-dir del contenedor, que el recuento de propiedad no incluye. Tras la 1.3.1: cada vía de instalación escribe un manifiesto de instalación, yuninstallquita lo que lista, y después el manifiesto y el directoriomikroscope/cuando no queda nada más en él; tras ninguna vía quedó una ruta de mikroscope en/file(F4). - El sondeo posterior a
installlee mal un contenedor en marcha sobre 7.24.4. Pregunta/container/find … status="running", ystatusno es una propiedad de/containerallí (/container/find status=runningrespondebad parameter status), mientras que la marcarunningvale 1. Así que cuando falló el sondeo, la CLI dijo “the container is not running on the router” con el agente en marcha y a punto de responder. Visto dos veces en arm64. Tras la 1.3.1: el sondeo lee la marcarunning. - El listado del plan nombraba un tar con
--remote-image:image=mikroscope.tar, un fichero queinstallnunca sube, e imprimía la subida o la descarga como un paso propio con el número del paso del contenedor, así que dos pasos compartían número. Tras la 1.3.1:image=nombra la referencia que descarga el router, y la descarga o la subida es una línea del paso del contenedor. - El token del agente viajaba en la línea de órdenes de ssh, donde la tabla de procesos del
anfitrión lo mostraba mientras la orden se ejecutaba: el código de la 1.3.1 lo mostró en dos líneas
de órdenes. Tras la 1.3.1 una orden que lo lleva va a ssh por la entrada estándar; leer la
tabla de procesos cada 2 ms durante una instalación y una actualización con
--exposeno lo encontró en ninguna, en las dos arquitecturas. - Las palabras de RouterOS se perdían cuando su ssh salía con 1: el error decía
ssh "<script>": exit status 1, y el mensaje de RouterOS, en las líneas siguientes, lo descartaba la línea de omisión de uninstall. El ssh de RouterOS salió con 1 o con 0 ante el mismo fallo, más o menos a partes iguales. Tras la 1.3.1 el error empieza con lo que imprimió RouterOS.
Fuentes sin recoger
Sección titulada «Fuentes sin recoger»Dos ficheros legibles del RB5009, leídos allí el 2026-09-15, no se recogen: /proc/cmdline, que lleva
board=5009 ver=7.24.1, una segunda identidad del equipo sin la API, y el watchdog hardware en
/sys/.