Grabar, marcar, dibujar
El colector mantiene un router vigilado; record es para la otra pregunta —
estoy a punto de cambiar algo, ¿qué hace de verdad? Esta página responde cómo
tomar una grabación desde tu máquina, qué contienen los cuatro ficheros que
escribe, cómo entran los marcadores y en qué reloj, cómo el log del router pasa
a formar parte de ella y qué dibuja plot.
Tres verbos
Sección titulada «Tres verbos»mikroscope record --for 5m --out cap # cap.jsonl, cap.csv, cap.markers.csv, cap.meta.json; escribe líneas para marcarmikroscope mark --out cap "queue tree applied" # una nota sellada con la hora actual (ver abajo)mikroscope mark --out cap --log-markers # las líneas del propio log del router, por la APImikroscope plot --in cap # cap.svg, deterministaLos tres verbos comparten un mismo juego de opciones, así que cada uno acepta todas las opciones de abajo; las notas dicen sobre qué verbo actúa cada una.
| Opción | Por defecto | Qué hace |
|---|---|---|
--out |
capture-<UTC time> |
Prefijo de salida: <out>.jsonl, .csv, .markers.csv, .meta.json. mark necesita el prefijo de una grabación existente. |
--for |
0 |
record: para tras este tiempo. 0 graba hasta Ctrl-C. |
--from-start |
desactivada | record: rellena todo lo que guarda el anillo del agente antes de pasar a directo. |
--poll |
500ms |
Cada cuánto se tira del anillo del agente. |
--batch |
0 |
Muestras por petición. 0 es el doble de lo que produce un intervalo de --poll a la cadencia del agente, con un mínimo de 20; el relay limita una petición a 18. |
--transport |
auto |
auto, direct (HTTP a la veth) o relay (/tool fetch por la API de RouterOS). |
--log-markers |
desactivada | record: añade las líneas del log del router de la ventana cuando termina la grabación. mark: añade las líneas del log de la ventana de la grabación. |
--topics |
system,interface,container |
Temas del log que se conservan como marcadores; añade firewall o script cuando sus líneas son la historia. |
--router-tz |
Local |
Zona IANA que muestra el reloj del router. Las horas del log de RouterOS no llevan zona. |
--api |
MIKROSCOPE_API_ADDR |
host:port de la API de RouterOS, para el relay y para --log-markers. |
--api-user |
MIKROSCOPE_API_USER |
El usuario de la API. La contraseña solo se lee de MIKROSCOPE_API_PASSWORD; no hay opción para ella. |
--token |
MIKROSCOPE_TOKEN |
El token bearer del agente. |
--port |
9123 |
El puerto HTTP del agente. |
--subnet |
MIKROSCOPE_SUBNET, si no 172.30.10.0/30 |
La /30 del agente; su dirección es la .2. |
--in |
ninguno | plot: un prefijo de grabación, o la ruta de un fichero .jsonl. |
--svg |
<in>.svg |
plot: el fichero de salida. |
--title |
el prefijo | plot: el título del gráfico. |
Desliza en horizontal para ver todas las columnas
Lo que se ha medido que entrega una grabación
Sección titulada «Lo que se ha medido que entrega una grabación»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
Esa grabación dio exactamente 600 muestras, 0 huecos y un desfase de reloj de −7 ms.
En ella, 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, y 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. Cinco minutos con un
router recorre record y plot de
principio a fin sobre otra captura: 70 s a 10 Hz con el router por lo demás en
reposo, con tres notas escritas en el terminal de record.
Cómo llega record al agente
Sección titulada «Cómo llega record al agente»--transport auto prueba primero el camino directo: un GET /healthz a
http://<.2 de --subnet>:<--port>. Si no responde, abre la API de RouterOS y
pide al router que haga él mismo la petición al agente. Si falta --api o
--api-user, se detiene con un error que nombra --api, --api-user y
MIKROSCOPE_API_PASSWORD y sugiere install --expose; si falta la contraseña,
aparece en su lugar un error de inicio de sesión, api <host:port>: …. La
sugerencia de --expose sirve a otros clientes HTTP, no a record: record
siempre llama a la .2 de --subnet y no tiene opción para la dirección LAN del
router. direct y relay fuerzan un camino y fallan en vez de recurrir al
otro.
- direct es HTTP plano de tu máquina a la veth. Envía
--tokencomo token bearer. - relay ejecuta
/tool fetch output=useren el router por la API binaria, así que el usuario de la API necesita las políticasread,api,test. Cada llamada por relay tarda o unos 3 ms o alrededor de 1 s. Una respuesta está limitada a 64 512 B, así que una petición por relay pide como mucho 18 muestras, y una respuesta que llega al límite se rechaza en vez de analizarse truncada. La petición desde el router no lleva cabecera: un agente instalado con token solo se puede grabar por el camino directo.
Llegar al agente explica qué camino permite una red. El usuario de la API se describe en su propia página.
Una vez conectado, record lee /healthz. El reloj de pared del agente menos
el de tu máquina es el desfase de reloj, que se imprime por stderr junto con
la versión del agente, la cadencia, el número de secuencia más reciente, el más
antiguo que aún guarda el anillo y el transporte. La grabación empieza entonces
en directo desde la muestra más reciente, o desde la más antigua que guarda el
anillo con --from-start.
Cada --poll pide /. Mientras una
petición vuelve llena, vuelve a pedir, hasta 100 veces por intervalo, así que un
anillo que se ha adelantado se vacía en vez de seguirse a ritmo fijo. Una
petición que falla se registra como pull: … y la grabación continúa; la
siguiente pide desde el mismo número de secuencia. Cuando vence --for o pulsas
Ctrl-C, una última petición recoge lo que llegó entretanto, y record imprime
cuántas muestras conservó, su rango de secuencia, los huecos, los marcadores, el
transporte y los ficheros.
Los cuatro ficheros
Sección titulada «Los cuatro ficheros»Cada fichero se crea con modo 0600, y un fichero existente con el mismo
prefijo se sobrescribe.
<out>.jsonl— cada línea de muestra tal como la envió el agente: deltas crudos de ticks y contadores, con todas las fuentes que tiene el agente. Esta es la grabación; los demás ficheros son vistas de ella.<out>.csv— una fila ancha por muestra, para una hoja de cálculo. El conjunto de columnas se dimensiona a partir de la primera muestra: un grupo por núcleo y uno por cola softnet.<out>.markers.csv—wall_, una fila por marcador.ns,wall_ utc,seq,kind,label <out>.meta.json— se escribe al principio, para quemarkyplotpuedan ejecutarse después:started_utc,skew_ns(reloj de pared del agente menos el del anfitrión),agent(su versión),rate_hz,transportycapabilities— lo que el agente estableció sobre la placa — cuando el transporte pudo obtenerlo.
El CSV guarda un subconjunto fijo de cada muestra. Todo lo demás que lleva una
muestra — eventos del log del kernel, contadores PMU, temperaturas,
interrupciones por línea y el resto — está solo en el .jsonl.
| Columnas | Contenido |
|---|---|
seq, wall_ns, wall_utc, dt_ns |
El número de secuencia de la muestra, el reloj de pared del agente y el intervalo real. |
busy_total |
La media de las proporciones de ocupación por núcleo, con tres decimales, calculada por la CLI a partir de los ticks. |
c<N>_busy, c<N>_user, c<N>_nice, c<N>_system, c<N>_idle, c<N>_iowait, c<N>_irq, c<N>_softirq |
Por núcleo: la proporción de ocupación y después los deltas crudos de ticks. |
ctxt, intr, irq_total |
Cambios de contexto e interrupciones de /proc/stat, y el delta sumado sobre todas las filas de /proc/interrupts. |
softnet<N>_processed, softnet<N>_dropped, softnet<N>_time_squeeze |
Por cola softnet, los deltas del camino de recepción. |
mem_free_kb, mem_available_kb, mem_cached_kb, mem_slab_kb |
Niveles de memoria, en kB. |
load1, threads_running, threads_total |
Carga media y recuento de hilos. |
pgfault, pgmajfault |
Deltas de fallos de página. |
self_cpu_us, self_rss_bytes |
El tiempo de CPU propio del agente durante la muestra, en µs, y su memoria residente en ese momento, en bytes. |
Desliza en horizontal para ver todas las columnas
La proporción de ocupación del CSV es el único número que calcula la CLI, y hereda el suelo del kernel: un tick dura 10 ms, así que en una muestra de 100 ms un núcleo se resuelve en escalones del 10 %. El suelo de resolución explica por qué, y por qué la proporción está limitada a 1.
Los marcadores, y en qué reloj están
Sección titulada «Los marcadores, y en qué reloj están»Un marcador es una fila de <out>.markers.csv de uno de tres tipos:
note— una línea de texto que añadiste tú. Mientrasrecordcorre en un terminal imprimetype a line and press Enter to add a marker; Ctrl-C stops, y cada línea no vacía que escribes se convierte en una nota. Cuando la entrada estándar no es un terminal, no se lee nada de ella.gap— se escribe cuando el agente informa de que unas muestras ya no estaban en su anillo, con la etiquetasamples <from>..<to> lost. Los mismos huecos aparecen en el resumen que imprimerecordal final.log— una línea del propio log del router, añadida con--log-markers(abajo).
Las notas y los huecos llevan la hora de tu máquina más el desfase medido al
principio, así que quedan sobre el eje de tiempo del agente, no del de tu
máquina. mark --out cap "text" hace lo mismo con el desfase guardado en
cap.meta.json: sella la hora actual en el reloj del agente, y ninguna opción
fija otra. Sobre una grabación terminada, la nota cae por tanto después de la
última muestra, y plot no la dibuja. mark necesita ese fichero y un
cap.markers.csv existente, y su fila lleva seq 0.
El propio log del router como marcadores
Sección titulada «El propio log del router como marcadores»El log explica a menudo un transitorio que no provocaste tú: ejecuciones del
planificador, errores, eventos de interfaz. --log-markers convierte las líneas
del log de la ventana de la grabación en marcadores log, con la etiqueta
<topics>: <message>.
export MIKROSCOPE_API_ADDR=192.168.88.1:8728 MIKROSCOPE_API_USER=mikroscope MIKROSCOPE_API_PASSWORD=…mikroscope record --for 60s --out burstmikroscope mark --out burst --log-markers --router-tz Europe/Madridmark --log-markersusa la ventana desdestarted_utcdel fichero meta, desplazado por suskew_nsal reloj del agente, hasta la última muestra del.jsonl, e imprime cuántas líneas añadió, la ventana y los temas.started_utcse guarda al segundo. Añade sin comprobar lo que ya hay: ejecutarlo dos veces vuelve a añadir las mismas líneas.record --log-markerspide el log cuando la grabación se ha detenido, para la ventana desde su inicio hasta su final en el reloj del agente, y añade las líneas por el mismo camino que usamark, así que acaban en<out>.markers.csvy el total de marcadores del resumen cuenta lo que contiene el fichero. Si la propia petición del log falla,recordimprimelog markers: …y conserva la grabación.
La CLI pide al router solo la ventana, con una consulta ?>time= que empieza un
segundo antes, y solo los campos time, topics y message: el RB5009 tenía
66 217 filas de log, porque su tema dns registra a disco. Después conserva las
líneas dentro de la ventana cuyos temas incluyen alguno de --topics.
Un router con varias acciones de registro sobre un mismo tema lleva cada evento
una vez por acción, precedido del nombre de la acción ([INFO]: …,
[SYSTEM]: …); el prefijo se elimina y los duplicados se conservan una sola
vez.
Las horas del log de RouterOS no llevan zona. RouterOS 7.24.2 imprime la fecha
completa por la API; el analizador acepta también las formas más cortas, sin año
o sin fecha, y las completa a partir del final de la ventana. Se leen en
--router-tz y se sellan como reloj de pared
del agente — el propio reloj del router — así que no se les aplica desfase. El
valor por defecto Local es la zona de tu máquina: si la del router es
distinta, pásala, o cada marcador de log caerá desplazado en esa diferencia. Las
horas del log tienen resolución de un segundo, así que un marcador de log sitúa
su evento al segundo, no a la muestra.
El gráfico
Sección titulada «El gráfico»plot --in cap lee cap.jsonl, y cap.markers.csv cuando existe, y escribe
cap.svg (o --svg). Imprime el nombre del fichero con sus recuentos de
muestras y marcadores. La misma entrada produce siempre los mismos bytes.
El gráfico mide 1 200 unidades de ancho, con un título (--title, o el prefijo)
y una línea con el número de muestras, la duración y el número de núcleos. Tres
paneles comparten un eje de tiempo, en segundos desde que empezó la grabación:
- CPU busy per core, % — de 0 a 100, una línea por núcleo, cada una etiquetada en su extremo. La paleta tiene ocho colores, así que se dibujan los ocho primeros núcleos.
- softnet per second, all CPUs —
droppedytime_squeeze, sumados sobre todas las colas y agrupados en segundos enteros. Los descartes se dibujan en rojo. - memory available, MiB —
MemAvailablepor muestra, con el eje y ajustado a los datos.
Cada marcador es una línea vertical discontinua que cruza los tres paneles, gris
para notas y líneas de log y roja para huecos, con una etiqueta encima del primer
panel. Las etiquetas se reparten en hasta seis filas para separarlas; una
etiqueta de más de 40 caracteres se acorta. Los marcadores de log consecutivos, en
orden de tiempo, que caen en el mismo segundo se pliegan en una sola etiqueta,
<count>× <topics>: <first message>, para que un planificador parlanchín no
entierre el gráfico; una nota o un hueco entre ellos corta el pliegue, y las
notas y los huecos nunca se pliegan. Los marcadores fuera del intervalo de tiempo
de la grabación no se dibujan. Con una sola muestra, el SVG dice
not enough samples to draw; sin ninguna, plot se detiene con
record: no samples y no escribe SVG.
La paleta es propia del gráfico, validada para su fondo claro: ΔE entre pares adyacentes con deficiencia de visión del color 9,1, con visión normal 22,9. No hay variante oscura.
plot también lee una captura que el agente guardó por un disparo: guarda
GET /captures/<id> en un fichero .jsonl y pásalo a --in. La línea de
cabecera de la captura no lleva número de secuencia y se salta.
Disparadores durante una grabación
Sección titulada «Disparadores durante una grabación»Cuando salta un disparador en el agente, una línea {"trigger":{…}} viaja en la
misma petición que las muestras, justo antes de la muestra en la que saltó. El
colector la reconoce; record no.
Captura por disparo explica qué salta y cómo traer la ventana a cadencia completa que el agente guardó a su alrededor.