Ir al contenido

En qué punto está

Esta página responde a lo que necesita saber primero quien está decidiendo si probar mikroscope: qué partes funcionan de extremo a extremo, en qué hardware se demostró, cuánto cuesta hoy el observador, qué defectos se conocen y siguen abiertos, y si hay algo que descargar. Está contrastada con el código a fecha del 2026-09-16.

Todo lo siguiente, salvo las baterías de pruebas y los siete destinos señalados como tales, se ha ejecutado contra el RB5009 de referencia (RouterOS 7.24.2), y no solo contra simulaciones:

  • El agente 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; medidos 10, 50 y 100 Hz), guarda las muestras en un anillo y las sirve: /healthz, /capabilities, /snapshot, /stream, /metrics, y los endpoints de captura por disparo /captures y /capture.
  • La CLI de despliegue lo instala, lo actualiza y lo retira — doctor, plan, install, status, upgrade, uninstall — listando cada escritura antes de hacerla y verificando cada retirada por recuento de propiedad. El 2026-09-12, doctorinstallstatusupgradeuninstall dejó el /export del router idéntico byte a byte, comparado por hash en memoria y sin escribirlo nunca a disco. El agente respondió 3 s después de la instalación, con un tiempo de ida y vuelta de 5–7 ms. El 2026-09-17 se ejecutaron las cuatro rutas de instalación contra el mismo equipo, una tras otra y cada una retirada antes de la siguiente: la compilación desde el checkout, el tar del agente publicado, la descarga que el propio router hizo desde Docker Hub y el script de plan --rsc importado en el router sin CLI ninguna en la instalación misma. El agente respondió en todas, y el /export posterior a las cuatro era idéntico byte a byte al anterior a ellas.
  • record, mark y plot funcionan de extremo a extremo. Una grabación de 60 s a 10 Hz el 2026-09-12 dio exactamente 600 muestras, 0 huecos y −7 ms de desfase de reloj.
  • forward, el colector, une la capa del kernel con la capa de la API de RouterOS y escribe en diez destinos. Fichero, Prometheus e InfluxDB 3 se han ejecutado desde el RB5009; por Loki, OTLP, Graphite, Elasticsearch, SQL, Telegraf y stdout todavía no han pasado muestras del router, pero todos ellos escriben ya en el producto real — InfluxDB 3, PostgreSQL, Elasticsearch, Graphite, Loki, un OpenTelemetry Collector, Telegraf y Prometheus en contenedores — y la batería vuelve a leer cada uno por su propia API (2026-09-16). Su etapa de derivación añade valores derivados y eventos de detección junto a las filas en bruto, y emite un flujo de datos del equipo una vez por cada hash de capacidades.
  • Cinco dashboards de Grafana, uno por almacén —InfluxDB 3, Prometheus, PostgreSQL, Graphite y Elasticsearch—, generados a partir de una sola lista de paneles, con reglas de alerta para los tres cuyo lenguaje de consulta es el de las reglas. A los dos almacenes SQL se les hace la misma pregunta en dos dialectos: los paneles de PostgreSQL son los de InfluxDB reescritos, y las 209 consultas las planifica un PostgreSQL real en la batería de contenedores. Graphite y Elasticsearch llevan menos paneles a propósito (41 y 30 frente a 171): Graphite no tiene etiquetas y Elasticsearch no tiene documentos anidados, así que lo que no pueden expresar está ausente en vez de equivocado. Los cinco se importan en un Grafana real sobre los almacenes que llenó la batería, y se le pregunta a cada panel: el 2026-09-17 devolvieron datos 57, 98, 136, 35 y 28 paneles, y no falló ninguno. El 2026-09-16, en Grafana 13.2.1, contra el RB5009 con los disparadores por defecto y un forward de 30 minutos hacia los dos almacenes, dashboards check dio por buenos 171 paneles de InfluxDB (0 fallidos, 10 vacíos conocidos tolerados) y 133 paneles de Prometheus (0 fallidos, 9 vacíos conocidos tolerados). El recorrido sin interfaz, fila a fila, de los dos dashboards — 0 insignias de error y 0 “No data” — es del 2026-09-15 y cubre 168 y 130 paneles; no se ha repetido para los dos paneles de eventos de puerto ni para la tabla de inventario de interfaces, que no cubre. Un recorrido del 2026-09-14, contra una captura de 10,5 h del mismo equipo, renderizó 140 paneles de InfluxDB con el mismo resultado.
  • Una batería de extremo a extremo compila los dos binarios y los ejecuta contra un árbol /proc capturado del equipo de referencia y contra 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.
  • Una segunda batería contra los almacenes mismos (make test-e2e-docker) levanta nueve de ellos con docker compose, ejecuta el mismo colector contra el mismo agente simulado con todos los destinos apuntando a ellos y luego le pregunta a cada almacén por su propia API: SQL contra InfluxDB 3, psql contra el guion que escribió el destino SQL, una búsqueda contra Elasticsearch, query_range contra Loki, render contra Graphite, el OTLP que el colector decodificó, el protocolo de línea que Telegraf analizó y un scrape del exportador almacenado en Prometheus. Después importa los dos dashboards en Grafana y pasa la consulta de cada panel por la propia API de Grafana. Necesita Docker y ningún router: las muestras son las mismas 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.

Con los valores por defecto de la instalación — 10 Hz, suelos por fuente por defecto, un anillo de 300 s — el agente cuesta 2,85 % de un núcleo y 31,3 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 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

Las ejecuciones medidas
cadenciasuelosCPU de un núcleoµs/muestraRSSticks retrasadoshuecos / descartes
10 Hz (por defecto)por defecto2,85 %2 85631,3 MiB00 / 0

Eso está por encima del presupuesto de 2 % de un núcleo y 16 MiB de RSS. El presupuesto es orientativo, no un contrato: el coste depende del equipo, del conjunto de fuentes y del tamaño del anillo. El presupuesto de imagen es 8 MiB; el único tamaño de imagen registrado es 6,1 MiB, y no lleva fecha.

Dos reglas mantienen honesta la cifra de coste: esperar a que se llene el anillo (BUFFER_S) antes de citar una cifra de régimen estacionario — 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 leer el coste de /metrics en vez de un /snapshot grande, cuya respuesta de ~1,5 MB tiene que serializar el agente.

Todas las filas se midieron en el mismo RB5009 a 10 Hz, y cada una es una ventana sin dispersión registrada. Son los ajustes que un lector puede elegir, así que la tabla dice lo que cuesta cada uno, no lo que valía el número en algún momento anterior.

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 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,85 % 31,3 MiB 2026-09-15 la cifra de arriba

Todas las cifras tomadas en el equipo que aparecen en esta documentación vienen de un único RB5009UG+S+ con RouterOS 7.24.2, el router de producción del propietario. No hay equipo de laboratorio.

Contrastado con el código a fecha de esta página:

  • El resumen final de forward va a stdout, el mismo flujo en el que el destino --stdout escribe los registros, así que forward --stdout=lp | telegraf termina cada ejecución con líneas que el consumidor no puede analizar.
  • Un --token erróneo no hace fallar la ejecución. Cada petición queda registrada como 401 Unauthorized, y la ejecución termina en el plazo de --for con código de salida 0 y forwarded 0 kernel samples. La comprobación de salud que hace forward antes 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 seq repetidos 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.
  • Graphite nombra las zonas térmicas por índice. El índice es deliberado — la cadena type de una zona no es única entre zonas — pero la lista de rutas al principio de internal/sinks/graphite.go dice thermal.<zone>.

Dos ficheros legibles del equipo de referencia, 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/class/watchdog/watchdog0.

La versión actual es la v1.0.0 — la que hay en VERSION, compilada en los dos binarios y que devuelve mikroscope version. Una etiqueta v* lanza la configuración de GoReleaser, que publica:

  • Archivos de la CLI para linux, darwin, windows y freebsd en amd64, arm64 y arm: .tar.gz, y .zip en Windows, cada uno con LICENSE y README.md.
  • Archivos del agente para linux en esas mismas tres arquitecturas, para quien quiera el binario pelado en lugar de una imagen.
  • Tar de imagen del agente para cargar a mano, uno por arquitectura — mikroscope-agent-arm64.tar, mikroscope-agent-arm.tar, mikroscope-agent-amd64.tar —, que es lo que install --agent-tar sube al router.
  • La imagen del agente en dos registros, jmrplens/mikroscope-agent:1.0.0 en Docker Hub y ghcr.io/jmrplens/mikroscope-agent:1.0.0 en GHCR, cada una un único manifiesto sobre linux/amd64, linux/arm64 y linux/arm/v7, que install --remote-image hace descargar al router. RouterOS toma el host del registro del ajuste global /container/config registry-url, que viene puesto en https://registry-1.docker.io, así que la referencia de Docker Hub no necesita fijar nada en el equipo y la de GHCR necesita cambiar antes ese ajuste.
  • checksums.txt, que cubre todos los archivos y todos los tar de imagen, una firma cosign sin claves sobre él y un SBOM SPDX por archivo, firmado a su vez.

Instalar desde una versión publicada no necesita ni toolchain de Go ni copia del repositorio. Con una copia del repositorio y Go 1.27 se instala en cambio un agente compilado desde tu propio árbol: make build para la CLI y make build-agent para el agente, que install e image compilan también por su cuenta. Las cuatro maneras de llevar el agente a un router, y lo que necesita cada una, están en Instalar el agente.

Lo que la versión publica para linux/arm y linux/amd64 está compilado de forma cruzada y comprobado en CI. De las tres arquitecturas, solo arm64 se ha ejecutado en hardware: en el único RB5009 de arriba.