Cinco minutos con un router
La pregunta para la que existe esta herramienta: estoy a punto de cambiar algo en el router; ¿qué hace de verdad, a una resolución en la que pueda verlo? Esta página es el camino más corto desde un router que nunca ha visto mikroscope hasta un gráfico que la responde: seis pasos con las órdenes tal cual son, y una grabación real del RB5009 leída línea a línea.
Antes de empezar
Sección titulada «Antes de empezar»El router necesita lo que la herramienta no le puede dar: RouterOS 7.24 o posterior con el paquete
container y device-mode container=yes, que MikroTik protege tras una pulsación del botón de
reset o un ciclo de alimentación. El suelo es 7.24 porque el paso del contenedor escribe
privileged=, un atributo que MikroTik añadió en esa versión; --privileged=false cambia su
valor, no si se escribe, así que una 7.x anterior rechaza la orden igualmente. Todo lo de esta
página se midió en 7.24.2. doctor informa de la versión del router en su primera línea, pero no
la condiciona. Lo que necesita el router tiene la lista
completa, y mikroscope doctor comprueba el resto en solo lectura y nombra el arreglo de lo que
falte.
La CLI no lee .env por sí misma, y solo algunas opciones toman su valor por defecto de una
variable MIKROSCOPE_*: las de conexión y nombres (ROUTER, SSH_PORT, SSH_KEY, NAME,
VETH, SUBNET, IFACE_LIST, ADDR_LIST, DISK, ARCH, TOKEN, LAN_ADDRESS), las de la API
(API_ADDR, API_USER, API_PASSWORD), las URL de los destinos como INFLUX_URL, INTERFACES
y HOST_TAG. El resto, entre ellas --ephemeral, --rate, --for, --topics y --prom, tiene
valores por defecto fijos, diga lo que diga el texto de uso de la CLI. Exporta las variables que
necesites, o copia .env.example a .env y carga el fichero con set -a; . ./.env; set +a;
variables de entorno las lista todas.
El camino
Sección titulada «El camino»-
Conseguir mikroscope.
Ventana de terminal tar xzf mikroscope_1.0.0_linux_x86_64.tar.gz # un .zip en Windows./mikroscope versionLa versión publicada trae la CLI como un archivo por plataforma —linux, macOS, Windows y FreeBSD en amd64, arm64 y arm— con
checksums.txt, las firmas de cosign y los SBOM al lado. El agente viaja aparte, como un tar de imagen por arquitectura (mikroscope-agent-arm64.,tar mikroscope-agent-arm.tar,mikroscope-agent-amd64.) y como imagen de registro, publicada tanto comotar jmrplens/en Docker Hub comomikroscope-agent:1. 0. 0 ghcr.en GHCR; el paso 2 toma uno de los dos.io/ jmrplens/ mikroscope-agent:1. 0. 0 Desde una copia del repositorio, en cambio:
Ventana de terminal git clone https://github.com/jmrplens/mikroscope && cd mikroscope && make buildEso necesita Go 1.27 y deja la CLI en
bin/mikroscope, que es como están escritas las órdenes de abajo. Es además el único camino que instala un agente construido desde tu propio árbol, porqueinstalllo compila de forma cruzada desde la raíz del módulo. -
Instalar, una vez.
Ventana de terminal export MIKROSCOPE_ROUTER=admin@192.168.88.1bin/mikroscope plan --ephemeralbin/mikroscope doctor --ephemeral && bin/mikroscope install --ephemeralplanimprime cada orden de RouterOS y no escribe nada.installpone la imagen del agente en el router, lista los objetos, vuelve a pasar la misma comprobación previa (--no-doctorse la salta), preguntawrite the objects above to the router? [y/N](--yesse salta la pregunta), escribe y después sondea el agente desde tu equipo.De dónde sale la imagen lo eliges tú, y es la única diferencia entre las tres instalaciones:
- tu toolchain de Go, como arriba: la CLI ejecuta
go build .con/ cmd/ mikroscope-agent CGO_ENABLED=0,GOOS=linuxyGOARCHtomado de--arch, por lo que tiene que ejecutarse desde la raíz del módulo; - el tar publicado,
--agent-tar mikroscope-agent-arm64.: sin toolchain de Go y sin copia del repositorio. La CLI lee el tar antes de subirlo —tiene que ser una imagen del agente de mikroscope y su arquitectura tiene que coincidir contar --arch—, o el verbo se detiene y nombra el fichero que hay que descargar; - el registro,
--remote-image jmrplens/: el router se descarga la imagen él mismo, no se sube nada ymikroscope-agent:1. 0. 0 uninstallno tiene ningún fichero del que responder. RouterOS toma el host del registro del ajuste global/, que mikroscope nunca escribe porque lo comparten todos los contenedores del equipo, y que viene puesto encontainer/ config registry-url https:/: por eso la referencia de Docker Hub de arriba funciona tal cual en un router sin tocar. La referencia de GHCR,/ registry-1. docker. io ghcr., nombra un host propio:io/ jmrplens/ mikroscope-agent:1. 0. 0 doctorcompara el ajuste con él e imprime/cuando no coincide, o remite acontainer/ config/ set registry-url=https:/ / ghcr. io --agent-tar. La descarga necesita que el router llegue al registro y que haya RAM libre para las capas.
--archvale por defectoarm64, la del RB5009; no se detecta a partir del router, perodoctorla compara con la arquitectura que informa el router y nombra el valor de--archcon el que volver a ejecutar si no coinciden.En un router al que solo llegas por WinBox o WebFig hay una cuarta vía, sin CLI de tu lado:
mikroscope plan --rsc --remote-image jmrplens/escribe las mismas órdenes, en el mismo orden y con las mismas etiquetas, como un script de RouterOS para pegar en el terminal o hacerlemikroscope-agent:1. 0. 0 --out install.rsc /import. Instalar el agente tiene esa vía y sus dos advertencias al completo.--ephemeralpone el tar de la imagen y la raíz del contenedor en el disco RAM tmpfs del router y crea el contenedor constart-on-boot=no, así que el agente no vuelve tras un reinicio.installborra el tar en cuanto el contenedor lo ha extraído. No se escribió nada en la flash:write-sect-since-rebootse quedó en 58 279 durante la instalación, la ejecución y la retirada (verificado en RB5009UG+S+, RouterOS 7.24.2, ). Quítalo para una instalación persistente. El disco tmpfs tiene que existir; el RB5009 tiene uno, ydoctor --ephemerallo comprueba e imprime el/disk/addque lo crea si no existe. Pasa--ephemeraltambién adoctor: sin él,doctorcomprueba en su lugar la flash libre.installtermina sondeando al agente desde tu equipo, e imprime una línea:direct transport ok: agent 1.0.0 (9ddd760) built 2026-09-16T08:38:27Z, 10 Hz, seq 29, 0 slipped, 7ms round tripEl primer campo es la identidad de compilación del agente: la versión, que una publicación graba desde el fichero
VERSION, y después el commit y la fecha de compilación. Ungo buildsin grabar dentro de una copia del repositorio informa de esa misma versión con el commit y la hora que registra la toolchain de Go, así que el campo nunca dicedevni un hash a secas. Un agente que sale del tar o del registro informa de lo que grabó la compilación publicada; uno queinstallconstruye desde tu árbol lleva la marca de la propia CLI, así que ambos informan de la misma cadena. El resto de la línea es el sondeo: la cadencia del muestreador, la secuencia a la que había llegado el agente, los ticks que se le escaparon y el tiempo de ida y vuelta. En el RB5009 el sondeo respondió a los tres segundos con 7 ms de ida y vuelta, y con 5 ms tras unupgradeese mismo día (2026-09-12).El sondeo espera hasta 30 s. Si tu equipo no llega a la /30 del agente, primero pregunta al router si el contenedor está en marcha y solo entonces sugiere alternativas; consulta llegar al agente.
- tu toolchain de Go, como arriba: la CLI ejecuta
-
Grabar mientras haces el cambio.
Ventana de terminal bin/mikroscope record --for 70s --out burstEscribe una línea y pulsa Intro cada vez que hagas algo que merezca recordarse; se convierte en un marcador con la marca de tiempo del agente. Funciona cuando la entrada estándar es un terminal, y la CLI lo dice:
type a line and press Enter to add a marker; Ctrl-C stops. Desde otra shell,Ventana de terminal bin/mikroscope mark --out burst "queue tree applied"hace lo mismo:
markañade al final de<prefijo>.markers.csvmientrasrecordmantiene el fichero abierto, así que una nota desde un segundo terminal y otra escrita en el del grabador acaban en el mismo fichero.--for 0, el valor por defecto, graba hasta Ctrl-C. Al finalrecordimprime el número de muestras, el rango de secuencia, los huecos, los marcadores y el transporte que usó, y nombra cualquier tramo de muestras que ya no estaba en el anillo del agente. -
Añadir el propio log del router.
Este paso habla con la API de RouterOS, no con el agente, así que necesita una cuenta en el router con la que hablar. Basta una de solo lectura, y el usuario de la API trae las dos órdenes que crean el grupo y el usuario; la CLI no necesita
adminpara esto.Ventana de terminal export MIKROSCOPE_API_ADDR=192.168.88.1:8728 MIKROSCOPE_API_USER=mikroscope MIKROSCOPE_API_PASSWORD=…bin/mikroscope mark --out burst --log-markers --router-tz Europe/Madrid(O pon esas tres en
.env—cp .env.example .env— y carga el fichero, como arriba.)Cada línea de log de la ventana de la grabación (desde su inicio hasta su última muestra, en el reloj del agente) cuyo tema sea
system,interfaceocontainerse convierte en un marcador; añadefirewalloscriptcon--topicscuando sus líneas sean la historia. El router informa ahí de errores y de ejecuciones del planificador, y el log a menudo explica un transitorio que no provocaste tú.MIKROSCOPE_API_ADDRtiene la opción--apiyMIKROSCOPE_API_USERla opción--api-user; la contraseña no tiene opción.--router-tzes la zona IANA que muestra el reloj del router, porque las horas del log de RouterOS no llevan zona; por defecto es la de tu máquina.record --log-markershace lo mismo al final de una grabación, ymark --log-markerslo hace después, como aquí (el propio log del router como marcadores). -
Mirar.
Ventana de terminal bin/mikroscope plot --in burstEsto escribe
burst.svg: tres paneles sobre un mismo eje de tiempo (proporción de ocupación por núcleo, descartes de softnet y time squeezes por segundo, memoria disponible) con cada marcador como una vertical discontinua dibujada panel a panel, de modo que ningún título de panel queda tachado. Los marcadores del log que caen en el mismo segundo se pliegan en una sola línea cuya etiqueta diceN×y el primer mensaje; un hueco en las muestras se dibuja como una línea roja; una etiqueta de más de 40 caracteres se corta a 37 y unos puntos suspensivos, y una etiqueta a la que no le queda sitio se acorta más hasta que cabe en vez de montarse sobre la de al lado, y se queda solo con su vertical cuando ya no queda nada legible; un marcador fuera del intervalo de la grabación no se dibuja. La misma grabación produce siempre los mismos bytes.--titlefija el encabezado y--svgotra ruta de salida. -
Dejarlo en marcha (opcional).
Ventana de terminal bin/mikroscope forward --prom :9124 --influx "$MIKROSCOPE_INFLUX_URL" --interfaces bridge,ether1Esto ejecuta el colector: la capa del kernel desde el agente y, con las variables
MIKROSCOPE_API_*del paso 4 en el entorno, la capa de la API de RouterOS a su lado. Con el--api-mode fullpor defecto esa capa lee/system/resource,/system/resource/cpu,/system/health,monitor-trafficcada segundo para las interfaces nombradas en--interfaces, los contadores acumulados de cada puerto cada 10 s y qué es cada interfaz —su comentario, su tipo, sus listas de interfaces, su bridge y su MTU— al arrancar y cada 5 min; la capa de la API de RouterOS dice cuáles de ellos puede leer el propio agente. Sin esas variables la capa de la API queda desactivada con un aviso y la capa del kernel sigue funcionando. Ambas van a una exposición de Prometheus en:9124y a InfluxDB 3. A partir de ahí, importar y comprobar monta los dos paneles de Grafana, el campo del origen de datos que necesita una importación de InfluxDB 3 y los dos trabajos de scrape de Prometheus.
Lo que muestra el gráfico
Sección titulada «Lo que muestra el gráfico»Abre el gráfico a tamaño completo (SVG, 1200 × 754) para leer sus
etiquetas en un móvil. Los rótulos de los paneles van en inglés porque plot los escribe así:
el título lo pones tú con --title, el resto es el vocabulario del kernel.
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
Es una grabación real de un router en reposo, la forma contra la que se lee todo lo demás. Las tres
líneas discontinuas son las notas escritas en el terminal de record durante ella; las etiquetas
las llevan enteras porque caben, y una más larga se acorta en vez de montarse sobre la siguiente.
- t = 12 s,
baseline, router idle. No pasa nada, y los paneles lo dicen: cada núcleo promedia menos del 10 % en toda la grabación, y en el tramo tranquilo que sigue a esta nota los cuatro juntos promedian un 3,9 %. - t = 30 a 50 s, entre
dashboards check startedycheck finished. Un navegador cargando los dos paneles de Grafana contra el colector de este mismo router. Los cuatro núcleos juntos promedian un 5,0 % en ese tramo, y el trabajo llega en dos ráfagas cortas justo después de la nota: el núcleo 0 al 50 % o por encima durante 0,6 s desde los 32,3 s, y otros 0,3 s a los 33,2 s. - El trabajo está en excursiones cortas. 76 de las 700 muestras tienen un núcleo al 50 % o por encima, en 46 tramos separados; 38 de ellos duran una sola muestra, y el más largo dura 1,4 s, al principio de la grabación y antes de la primera nota. El planificador del kernel pone cada excursión en el núcleo que esté libre. Una muestra aislada —un núcleo al 100 % durante 100 ms— mueve una media de un segundo sobre cuatro núcleos en un 2,5 %.
- softnet:
droppedplano en cero,time_squeezeentre 0 y unos 20 por segundo. No se perdió nada en 70 s. Los squeezes son el fondo de este equipo, no un suceso; lo que el colector llama microburst es un racimo de ellos —tres muestras marcadas en un mismo núcleo dentro de 60 s—, y nunca uno solo. - Memoria disponible, de 662 a 671 MiB. Unos 9 MiB de vaivén normal en toda la grabación, sin ningún escalón en ninguno de los dos extremos de la comprobación de los paneles.
El propio cpu-load de RouterOS, a 1 s, da este minuto por un puñado plano de puntos porcentuales.
La grabación muestra de qué está hecho ese puñado: qué núcleo se llevó cada excursión, cuánto duró
y dónde caen las notas frente a ella.
Lo que escribió el paso 2, y cómo quitarlo
Sección titulada «Lo que escribió el paso 2, y cómo quitarlo»Lo que install escribe en tu router
- una veth
- una dirección
- una pertenencia a lista de interfaces
- una entrada de address-list
- una envlist
- el tar de la imagen, salvo que
--remote-imagehaga que el router se la baje - el contenedor
Cada objeto lleva el comentario mikroscope:<name> (managed by mikroscope)
mikroscope plan imprime cada orden antes de escribir nada.
uninstall elimina por etiqueta exacta más identidad, nunca por patrón, y falla nombrando el paso si queda algo.
bin/mikroscope uninstall --ephemeralPasa los mismos --ephemeral, --disk y --name con los que instalaste: uninstall y status
reconstruyen el plan a partir de sus propias opciones, y sin --ephemeral buscan el tar de la
imagen en la flash en lugar de en tmpfs. uninstall deshace cada paso del plan en orden inverso, por etiqueta exacta, luego cuenta lo que
queda en el router a nombre de mikroscope y falla, nombrando los objetos, si queda algo.
bin/mikroscope status --ephemeral imprime esos mismos recuentos de propiedad en cualquier momento, más la
salud del agente cuando se puede llegar a él.