How it works
mikroscope is two programs. An agent runs in a container on the router and samples the kernel it shares with RouterOS; a CLI on your machine installs it, records from it and runs the collector that writes to your stores.
Components
Section titled “Components”mikroscope-agentis a static Go binary in a scratch container. It samples on a fixed ticker at 1 to 100 Hz, 10 Hz by default, keeps the last 60 s in a ring, and serves them over HTTP on its veth address. It opens no outbound connection and holds one secret at most: the token it asks of whoever reads it, which sits in the container’s envlist.mikroscope, the CLI, runs on your machine. It installs, upgrades and removes the agent over ssh; records a window with markers and plots it as an SVG; and runsforward, the collector.- The router’s own objects: a veth with a /30, the router’s address on it, two list
memberships, an envlist, the container, and an install manifest that lists them. Every one
carries the tag
mikroscope:<name> (managed by mikroscope), anduninstallremoves them all.
The release publishes the CLI as an archive per platform (Linux and FreeBSD on amd64, arm64 and
arm; macOS and Windows on amd64 and arm64), and the agent as one image tar per architecture and as
a registry image, jmrplens/ on Docker Hub and
ghcr.io/ on GHCR. The collector is also an image,
jmrplens/mikroscope and ghcr.io/ (linux/amd64, linux/arm64), and the
directory deploy/ has two compose stacks that pair it with InfluxDB 3 or Prometheus and
Grafana. That image’s default command is forward, and dashboards runs in it too; the install
commands need ssh and scp, which it leaves out. Both programs are under the MIT licence,
in LICENSE.
Data path
Section titled “Data path”- The agent reads the kernel on each tick and appends a sample to its ring.
forward, orrecord, pulls new samples from the agent over HTTP: directly to the veth address through the router, through the RouterOS API relay, or on the router’s LAN address with--expose(Network access).- The collector asks the RouterOS API, once a second, for what the kernel cannot show the container, and stamps both tiers in the agent’s clock.
- It derives ratios, rates and detections from the merged samples and writes them to every sink you name (Run the collector).
ssh is never on this path. The CLI uses it to install and check, and batches each read into one connect, because each connect costs the router CPU for its duration (SSH cost).
What the agent reads
Section titled “What the agent reads”A RouterOS container shares the router’s kernel, so /proc inside it is the router’s own:
/proc/statper core,/proc/interrupts,/proc/softirqsand/proc/net/softnet_stat;/proc/meminfo,/proc/vmstat,/proc/diskstatsand/proc/loadavg;- with the container privileged:
/dev/kmsg, the kernel log;/proc/slabinfo, which holds the router’s real connection count; the flash’s ECC counters; and the CPU’s PMU counters, system-wide, throughperf_event_open.
The container runs privileged by default; Privileged mode lists what each setting gives. The agent ships raw counter deltas, CPU time as ticks, never a percentage, so the reader chooses the window. It reports at start which sources this kernel has, and a source the kernel lacks is absent from the output rather than zero. Prometheus metrics lists every series.
What the collector adds
Section titled “What the collector adds”- The RouterOS API tier: per-interface traffic and error counters,
cpu-loadper core,/system/health, and what each interface is (its comment, type, lists, bridge and MTU). The container cannot read these: its network namespace is its own. RouterOS API tier has the modes. - One clock: every record is stamped in the agent’s clock, so kernel and API samples line up.
- Derived values: busy ratios, rates and shares, computed from the raw deltas (Derived values).
- Detections: a layer-2 loop, a link flap, a microburst and the other rules, each written as an event (Detection rules).
- Sinks: file, Prometheus, InfluxDB 3, Loki, OTLP, Graphite, Elasticsearch and OpenSearch, SQL, PostgreSQL, Telegraf and standard output.
Limitations
Section titled “Limitations”- RouterOS 7.24 or later, with a container. The agent needs the
containerpackage anddevice-mode container=yes, which takes a button press or a power cycle at the router. MIPS, TILE and PPC routers have nocontainerpackage. - The kernel’s resolution, not the tool’s.
/proc/statcounts CPU time inUSER_HZticks, 100 a second, so a 100 ms window resolves one core in steps of 10 % (Resolution limits). - PSI and schedstat only where the kernel has them. The agent reads both when they exist; a RouterOS kernel may be built without them.
- The container’s network is its own.
/proc/net/dev,/proc/net/snmpandnf_conntrack_countdescribe the container, not the router; the conntrack count from the slab, when privileged, is the exception. Interface counters come from the RouterOS API and are merged, never estimated (Container visibility). - It merges with the RouterOS API and does not replace it. Without an API user the kernel tier still runs, and the interface panels stay empty.
- No percentages from the agent. It never computes one, so it never decides what a percentage means; the collector and the dashboards derive them.
- The observer has a cost. At 10 Hz the agent takes 2.69 % of one core; Agent cost has the table and how to measure it on your router.