Ir al contenido

Capa de la API de RouterOS

forward puede mantener una sesión persistente con la API binaria de RouterOS (una segunda cuando la propia capa del kernel llega por el relay) para leer lo que el contenedor no ve: el tráfico y los contadores por interfaz. Elige cuánto pregunta con --api-mode.

Casi todo lo que la capa de la API puede obtener lo lee el propio agente:

  • /system/resource y /system/resource/cpu son la media de un segundo que hace RouterOS de los mismos jiffies de /proc/stat que el agente diferencia a 10 Hz.
  • La temperatura de /system/health es /sys/class/thermal, legible desde el contenedor.
  • El número de conexiones es la caché slab global nf_conntrack, que el agente lee con privileged=yes; consulta Conntrack sin la API.

Lo que queda son los bytes y paquetes por interfaz. Viven en el espacio de nombres de red del router y quedan fuera de alcance se le dé lo que se le dé al contenedor; consulta Visibilidad del contenedor.

El cpu-load de RouterOS es una media móvil de más o menos un segundo del tiempo ocupado de /proc/stat del kernel, y llega a la API con una fracción de segundo de retardo (medido). 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. No puede resolver nada más corto que su propio segundo, que es la razón por la que mikroscope lee el kernel.

--api-mode elige un preajuste. Es full salvo que digas otra cosa, y un --api-every, --no-health o --conntrack-every explícito sigue mandando sobre él.

Modo Lo que hace Úsalo cuando
off sin capa de la API: --api-every 0 en producción, cuando el tráfico por interfaz ya viene de otro sitio
slow una ronda cada 10 s, sin /system/health y sin el número de conexiones; /system/resource, monitor-traffic y los contadores de puerto siguen ejecutándose en cada ronda en producción, cuando también quieres las tasas de las interfaces
full una ronda por segundo, con /system/health; contadores de puerto cada 10 s; el número de conexiones solo si --conntrack-every lo pide experimentos y ejecuciones cortas de forward

off renuncia al tráfico por interfaz; slow lo conserva a bajo coste. Con slow hay dos paneles vacíos por configuración y no por el equipo — /system/health y el número de conexiones de RouterOS — y nombran la opción que los rellena.

Cada orden de la capa de la API se ejecuta en la única sesión de esa capa, de una en una, con un tiempo de espera de 15 s cada una. Las cadencias más lentas se comprueban en cada ronda, así que ninguna se ejecuta más a menudo que --api-every.

Orden Pide Se ejecuta Apagada cuando
/system/resource/print cpu-load, free-memory, total-memory, free-hdd-space, uptime, version en cada ronda la capa está apagada
/system/resource/cpu/print cpu, load, irq, disk en cada ronda la capa está apagada
/system/health/print name, value en cada ronda --no-health, o slow
/interface/monitor-traffic con interface=<list> y once las cuatro tasas de tráfico y las tasas de pérdidas que devuelva el router en cada ronda, una llamada para todas las interfaces --interfaces está vacío
/interface/print con .proplist=name,default-name,type,comment,actual-mtu qué es cada interfaz: su nombre actual, el nombre de fábrica de la placa, su tipo, su comentario y su MTU al arrancar, antes de la primera extracción del kernel, y luego cada --labels-every (5 min) la capa está apagada
/interface/list/member/print con .proplist=list,interface qué listas de interfaces nombran cada interfaz, que es su rol con la lectura de arriba la capa está apagada
/interface/bridge/port/print con .proplist=interface,bridge a qué bridge pertenece cada puerto con la lectura de arriba la capa está apagada
/interface/ethernet/print stats y /interface/print stats-detail cada contador numérico de todas las interfaces cada --counters-every (10 s) --counters-every 0
/ip/firewall/connection/print count-only el número de conexiones cada --conntrack-every --conntrack-every 0, el valor por defecto
/log/print con .proplist=topics,message y ?buffer=memory las líneas que RouterOS escribió sobre el arranque en el que está (Log de arranque) una vez por reinicio, cuando cambió el identificador de arranque del kernel que da el agente la capa está apagada
  • Una orden que falla deja vacía su parte de la muestra y registra por qué; el resto de la ronda sigue en pie. Los fallos se registran en la salida de error como api tier: …, se escriben como líneas en Loki y filas en SQL, y se cuentan en OTLP — nunca se convierten en un valor.
  • Una lectura de /interface que falla conserva el inventario que ya tenía, así que un error transitorio no deja en blanco la etiqueta de todos los paneles, y se informa como inventory: …. Las lecturas de listas y de bridges son de mejor esfuerzo; sin ellas el inventario sigue llevando nombres, tipos y comentarios.
  • La muestra de la capa de la API se marca con el reloj del colector más el desfase medido frente al agente, así que cae en la línea temporal del agente.

Las tres lecturas del inventario dicen a qué pertenecen los números. De cada interfaz dan:

Campo Origen Ejemplo
nombre /interface/print el nombre actual
nombre por defecto /interface/print el ether5 de fábrica de un puerto físico; vacío en un bridge, una VLAN o un túnel
tipo /interface/print ether, bridge, vlan, pppoe-out, wg, veth, loopback
comentario /interface/print la etiqueta que muestra un panel
MTU /interface/print (actual-mtu) 9000
rol /interface/list/member/print las listas de interfaces, ordenadas y unidas por comas: WAN, LAN,VPN
bridge /interface/bridge/port/print el bridge del que es puerto
  • Un miembro de un bridge que no está en ninguna lista propia hereda las de su bridge, porque así es como lo empareja una regla de firewall de RouterOS. Un puerto de bridge que nombra una lista de interfaces en vez de una interfaz no se etiqueta.
  • Esto es configuración, no telemetría, así que se lee una vez al arrancar — antes de la primera extracción del kernel, para que un registro del log del kernel lleve etiqueta desde la primera línea — y luego con la cadencia lenta de --labels-every, nunca en cada sondeo. Un comentario editado, o un puerto que cambia de lista, llega al dashboard en minutos, y un comentario borrado en RouterOS desaparece también aquí: la lectura sustituye el inventario entero. Ninguna de las cinco propiedades que pide puede llevar un secreto.
  • Cada fila de tasas de monitor-traffic y cada fila de contadores por puerto llevan label (el comentario), type, role y bridge, para que un panel diga lo que hay enchufado en vez de un número de puerto, y qué números se pueden comparar.

Prometheus es la excepción a propósito: un comentario lo edita una persona, y una etiqueta que cambia crearía una serie nueva en cada edición, así que el /metrics del colector lleva una serie informativa por interfaz — mikroscope_api_interface_info{interface,label,type,role,bridge,default_name} 1, para cada interfaz tenga o no comentario — y una consulta las une:

mikroscope_api_interface_counter_total * on(interface) group_left(label, type, role) mikroscope_api_interface_info

El inventario también le da sus nombres al log del kernel. Un registro del kernel nombra un puerto como eth1, la tabla de puertos de la placa lo traduce al nombre por defecto de RouterOS y el inventario traduce ese nombre por defecto al actual, así que quien haya renombrado ether5 a WAN lee WAN en el panel, con la etiqueta y el rol del puerto al lado. Sin la capa de la API un registro del kernel conserva el nombre por defecto de la placa y no recibe etiqueta.

Opción Por defecto Significado
--api host:port MIKROSCOPE_API_ADDR la API binaria de RouterOS, p. ej. 192.168.88.1:8728
--api-user MIKROSCOPE_API_USER el usuario de la API; su contraseña solo desde MIKROSCOPE_API_PASSWORD
--api-mode full off, slow o full, como arriba
--api-every 1s la cadencia de la ronda; 0 desactiva la capa
--interfaces MIKROSCOPE_INTERFACES, vacío interfaces separadas por comas para monitor-traffic, p. ej. bridge,ether1
--counters-every 10s cada cuánto leer los contadores acumulados de cada puerto; 0 nunca
--labels-every 5m cada cuánto releer qué es cada interfaz — comentario, tipo, listas de interfaces, bridge; 0 significa el valor por defecto
--conntrack-every 0 cada cuánto pedir el número de conexiones; 0 nunca, porque es un recorrido de tabla
--no-health desactivada omite /system/health

Sin --api, --api-user y MIKROSCOPE_API_PASSWORD, forward ejecuta solo la capa del kernel. Si se dan pero la sesión no se puede abrir en 10 s, registra api tier: not connected yet, will keep trying: … y engancha el lector igualmente: una primera marcación fallida es un aviso, no una capa deshabilitada para toda la vida del proceso.

En cualquier modo las órdenes de la capa de la API son lecturas: basta un usuario con las políticas read y api. test solo hace falta para /tool fetch, que usa el transporte por relay y nada más de la capa de la API. El grupo, la restricción de dirección y por qué la credencial nunca vive en el router están en Usuario de la API.

La capa de la API guarda exactamente lo que devolvió el router y no se inventa nada para lo que no devolvió.

  • Tasas de pérdidas. monitor-traffic puede devolver rx-drops, tx-drops, tx-queue-drops, rx-errors y tx-errors por segundo, y un destino escribe cada una solo cuando volvió. Un router puede devolver las tres tasas de descartes y ninguna clave de errores (verificado).
  • Contadores de puerto. Los contadores por puerto son un mapa con los nombres de campo del propio RouterOS, no un conjunto fijo de campos, y solo se conservan los enteros sin signo simples que cuentan algo. mtu, actual-mtu, l2mtu, max-l2mtu y sfp-shutdown-temperature se leen como enteros pero son tamaños y configuración, y todo destino representa este mapa como una familia de contadores, así que se descartan aquí en vez de dejar que cada consumidor lo sepa; el MTU viaja en el inventario.
  • Dos órdenes, fusionadas por interfaz. /interface/ethernet/print stats aporta los errores tipados de la MAC, la familia de colisiones, los intervalos de tamaño de trama y los contadores del driver; /interface/print stats-detail aporta los contadores fp-* del fast path, link-downs, tx-queue-drop y los totales del lado del kernel. Una placa sin contadores de colisiones no produce entradas de colisiones en vez de una fila de ceros que se lee como «sin colisiones».
  • Errores que solo llevan los contadores. Un puerto puede contar rx-overflow mientras monitor-traffic no devuelve ninguna clave de errores para él, así que esa cuenta solo llega a un consumidor por los contadores de puerto (verificado).
  • Todas las interfaces. Los contadores cubren todas las interfaces que lista el router, no solo --interfaces: el puerto en el que vive una avería suele ser uno que nadie pensó en vigilar.
  • Acumulados. Los contadores van desde el arranque o desde el último reinicio del puerto, así que un consumidor los diferencia. Separan lo que un puerto de switch recibió en el cable (rx-bytes) de lo que llegó a la CPU (driver-rx-byte); el resto lo reenvió el chip de conmutación en hardware, y ningún contador de dentro del contenedor tiene un número para eso. El colector convierte los contadores del fast path que van al lado en una proporción del tráfico que cada interfaz entrega a la CPU.
  • Un puerto de switch y un bridge cuentan cosas distintas, y por eso el tipo viaja con cada fila. Un ether dentro de un bridge cuenta su cable, incluidas las tramas que el chip de conmutación reenvió sin la CPU; el bridge cuenta su propio lado de CPU; una VLAN o un enlace PPPoE cuentan lo que la CPU envió y recibió. Un puerto y su bridge son dos planos, ninguno subconjunto del otro: dibujados uno al lado del otro sin su tipo parecen iguales, y sumados cuentan dos veces. No los sumes nunca.
  • Etiquetas de interfaz. Con qué se etiqueta cada fila — el comentario, el tipo, el rol y el bridge — es el inventario de arriba, y una interfaz que el inventario no lista no lleva ninguna de ellas en vez de una identidad en blanco inventada.

La capa del kernel no puede ver el rx-overflow por construcción. Una trama que el chip de conmutación reenvía en hardware nunca llega a la CPU, así que ningún fichero de /proc del router tiene un número para ella; hacen falta los contadores por puerto, y solo la API los tiene. Puerto que pierde tramas recorre uno de esos puertos, desde el indicador del dashboard hasta el arreglo.

El proceso de la API hace de intermediario de cada orden hacia el subsistema que la responde (interface-mgmt, config-db), y ahí es donde se ve su coste. Los perfiles y el A/B de una ronda por segundo están en Coste del agente.

La API sigue siendo el camino caro. Los datos por puerto salen del contenedor siempre que el contenedor pueda verlos, y la configuración se lee al arrancar y con la cadencia lenta de las etiquetas, nunca en cada sondeo.

La capa mantiene un solo socket, así que cualquier cosa que se lleve al router se la lleva a ella: un reinicio, una actualización de RouterOS, un operador reiniciando el servicio de API. La capa reabre la conexión ella sola.

Fallo Reabre la conexión Por qué
error de transporte: EOF, una tubería rota, una conexión reiniciada, un tiempo de espera agotado sí, y reintenta ese comando sobre la conexión nueva el socket está acabado
!trap no el router está vivo y rechaza el comando; repetirlo solo gastaría su CPU
!fatal sí RouterOS lo envía al cerrar la sesión, como dice la documentación de la API de MikroTik
  • Los intentos van espaciados cinco segundos. Una ronda lanza cuatro o cinco comandos, así que a un router caído se le marcaría si no varias veces por segundo, y cada marcación lleva un inicio de sesión.
  • El inventario se descarta y se vuelve a leer tras una reconexión: una actualización es justo cuando una interfaz puede cambiar de nombre, tipo o puente, y etiquetas viejas sobre tasas nuevas serían peor que un hueco de un momento.
  • Un colector que arranca con el router caído es el mismo caso visto desde el otro lado: conecta en la primera ronda que el router responda.

Un socket destruido bajo un colector en marcha se reabre y el comando se reintenta dentro de la misma ronda (probado). El colector lo dice una vez por suceso y no una vez por comando fallido:

api tier: reconnected (1 since start)
api tier: recovered after 137 failed round(s)

y el informe por minuto lleva api: N failed round(s), N reconnect(s) mientras alguno no sea cero. api cuenta rondas intentadas, así que esas dos cuentas son lo que muestra una capa en la que fallan todos los comandos. Resolución de problemas cuenta cómo se ve eso en los dashboards.

Cuando cambia el identificador de arranque del kernel que da el agente, el router se reinició, y el colector pregunta una vez a RouterOS qué escribió sobre el arranque en el que está. Lee solo el buffer de memoria, que RouterOS vacía en cada arranque: en un router que también escribe el log a disco, /log/print devuelve además las líneas de arranques anteriores. Se queda con las líneas de system que empiezan por router rebooted o router was rebooted, y con cualquier línea que mencione el arranque anterior.

Cómo cayó La línea Topics
/system/reboot desde una sesión router rebooted by ssh-cmd:admin@192.168.88.10/reboot system,info
/system/reboot desde un script router rebooted by ssh-cmd:admin@…/script:rb/reboot system,info
/system/shutdown y después encendido router rebooted by ssh-cmd:admin@…/shutdown system,info
un corte de corriente, o un botón de reset router was rebooted without proper shutdown system,error,critical

La línea nombra la sesión y el usuario, o el script, que reinició el router, o dice que cayó sin apagarse (Probado en). La detección reboot la lleva, y el colector la registra:

router's boot log: "router was rebooted without proper shutdown"

La conexión murió con el router, así que la lectura se intenta al notar el reinicio y otra vez después de cada ronda hasta que la capa vuelve, durante un máximo de dos minutos; la detección reboot la espera ese tiempo. A un router que responde con un error no se le vuelve a preguntar: la detección dice entonces RouterOS's log could not be read (…). Cuando el buffer de memoria no tiene ninguna línea así, porque dio la vuelta o ninguna regla de logging manda el topic system a memoria, dice RouterOS's memory log holds no line about the boot.

--conntrack-every 10s pregunta /ip/firewall/connection/print count-only con esa cadencia; una llamada tardó 1,3 ms con 6 212 entradas. Está apagado por defecto porque es un recorrido de tabla sobre una sesión de API, y con privileged=yes la cuenta slab nf_conntrack del agente es la misma población leída de un fichero a la cadencia del muestreador. Las dos no coincidirán exactamente — se muestrean en instantes distintos, y el slab cuenta objetos que el asignador todavía retiene. Si se siguen no se ha medido: pide la cuenta y lee el slab en el mismo minuto en tu propio equipo para compararlas.

Las placas y versiones de RouterOS en las que ha funcionado la capa están en Equipos y versiones. Qué claves de pérdidas y qué contadores devuelve otra versión u otra placa lo tiene que decir ese router; los destinos llevan lo que vuelva y nada más.