# mikroscope documentation > Sub-second kernel telemetry from inside a MikroTik router, with the cost of the observer measured rather than claimed. This is the index of the mikroscope documentation site. Every entry links one page and carries that page's own description. Source and issues live at https://github.com/jmrplens/mikroscope, and the releases page there carries the CLI archives, the agent image tars and the GHCR image. Home: [mikroscope](https://jmrplens.github.io/mikroscope/): Sub-second kernel telemetry from inside a MikroTik router, with the cost of the observer measured rather than claimed. ## Start here - [What it is](https://jmrplens.github.io/mikroscope/start/): An agent inside the router reading the shared kernel, a CLI outside it, and the four limits that cannot be engineered away. - [Five minutes with a router](https://jmrplens.github.io/mikroscope/start/walkthrough/): Get the CLI, install the agent, record a window while you change something, add the router’s own log as markers, and draw the chart — with a real recording from an RB5009. ## What it costs - [The cost of the observer](https://jmrplens.github.io/mikroscope/cost/): What the agent costs on an RB5009, measured from its own cgroup, and how to measure it on a device that is not this one. - [The rate ceiling](https://jmrplens.github.io/mikroscope/cost/rate-ceiling/): Five measured runs at 10, 50 and 100 Hz on an RB5009 — all of them lossless — and what sampling faster actually buys. - [What the numbers do not say](https://jmrplens.github.io/mikroscope/cost/limits/): The questions the measurements on this site cannot answer, and which metric to reach for instead of guessing. ## Install - [Installing the agent](https://jmrplens.github.io/mikroscope/install/): What `mikroscope install` does to a RouterOS device and in which order, and how `upgrade` and `uninstall` change or remove it without touching anything they did not create. - [Getting the CLI onto your machine](https://jmrplens.github.io/mikroscope/install/cli/): How to have the `mikroscope` command on Linux, macOS or Windows — which archive to download for your own computer as opposed to the router, how to verify it, where to put it so the shell finds it, and how to check it works. - [What the router needs](https://jmrplens.github.io/mikroscope/install/prerequisites/): The architecture, the container package and the device-mode step that needs a hand on the router, plus what your own host needs, and how `doctor` checks each one. - [Four ways to install](https://jmrplens.github.io/mikroscope/install/routes/): The four routes the agent image can take to the router — a Go checkout, the published tar, a registry the router pulls from, or a RouterOS script you paste in — what each one needs, what each one writes, and how to verify a downloaded release. - [The two firewall traps](https://jmrplens.github.io/mikroscope/install/firewall/): The two raw rules in the MikroTik default firewall that silently drop every packet a container sends, what `install` adds so they do not, and what to pass when your lists have other names. - [Where things go](https://jmrplens.github.io/mikroscope/install/layout/): Where each object `install` creates lives on the router, which disk holds the image and the root, what the envlist carries, and the container settings install writes. - [Reaching the agent](https://jmrplens.github.io/mikroscope/install/reaching-the-agent/): How the host running `record` or `forward` reaches an agent that listens only on its veth address, what the probe after `install` tells you when it cannot, and what direct, relay and `--expose` each cost. ## Record and capture - [Record, mark, plot](https://jmrplens.github.io/mikroscope/record/): How to pull a window of full-rate samples to your machine, mark the moments in it, add the router’s own log, and draw it as a deterministic SVG. - [Triggered capture](https://jmrplens.github.io/mikroscope/record/triggers/): How the agent keeps the full-rate samples around a condition you configured, what fires, how to fetch a capture, and why the set of captures is a sample of events rather than a census. ## Collector and sinks - [The collector](https://jmrplens.github.io/mikroscope/sinks/): What `mikroscope forward` does between the agent and your stores — pull, merge, derive, fan out — and what it promises when a store is slow. - [Prometheus](https://jmrplens.github.io/mikroscope/sinks/prometheus/): The collector’s own `/metrics` — every agent family recomputed from the samples, plus the API tier, the derive stage and the collector’s counters — and the two scrape jobs that go with it. - [InfluxDB 3](https://jmrplens.github.io/mikroscope/sinks/influxdb/): The InfluxDB 3 line-protocol sink — the write URL and token, how batches are delivered and dropped, every measurement it writes, and what InfluxDB 3 Core refuses. - [The file and the other sinks](https://jmrplens.github.io/mikroscope/sinks/other/): The JSONL file, standard output, SQL, Loki, OTLP, Graphite, Elasticsearch and Telegraf — what each one carries, how it delivers, and what its protocol cannot promise. - [The RouterOS API tier](https://jmrplens.github.io/mikroscope/sinks/api-tier/): What the collector still asks RouterOS over its binary API, why most of it is optional, and the flags and presets that decide how much to ask. - [What the collector derives](https://jmrplens.github.io/mikroscope/sinks/derive/): The values the collector computes beside the raw samples — memory pressure, per-packet PMU cost, packets per interrupt, the burst flag and the fast-path share — and when each one is withheld. - [Detections](https://jmrplens.github.io/mikroscope/sinks/detections/): The eleven rules the collector’s derive stage runs, each with its exact condition, the evidence it needs from the deployment, and what it may not claim. - [The device-info stream](https://jmrplens.github.io/mikroscope/sinks/device-info/): What the agent establishes about the board with no RouterOS API — identity, ceilings, cadences — and how the collector hands it to every sink as facts rather than samples. ## Dashboards - [Five dashboards, one panel list](https://jmrplens.github.io/mikroscope/dashboards/): What the InfluxDB 3, Prometheus, PostgreSQL, Graphite and Elasticsearch dashboards contain, section by section, in the order they are read, and why the five stores do not carry the same panels. - [Import and check](https://jmrplens.github.io/mikroscope/dashboards/import-and-check/): How to bind the dashboards to a datasource, what import and check ask the store first, and what check proves against a live Grafana and what it cannot see. - [Alert rules](https://jmrplens.github.io/mikroscope/dashboards/alerts/): The Grafana alert rules generated beside the dashboards, what each one fires on, where its threshold comes from, and what has not been tested about them. ## Reading the data - [How to read what it shows](https://jmrplens.github.io/mikroscope/playbooks/): Seven readings of kernel data from one RB5009 — a production fault found by accident, three events provoked on purpose, two that needed no provoking, and the idle shape they are read against. - [The shape of an idle router](https://jmrplens.github.io/mikroscope/playbooks/idle/): Sixty seconds of the reference RB5009 doing nothing in particular — the busy floor, the squeeze that is never zero, and the silence of a healthy kernel log. - [A loop only the kernel could see](https://jmrplens.github.io/mikroscope/playbooks/loop/): A layer-2 loop on the reference router’s production network that RouterOS’s log and port monitor never showed, found by the agent’s kernel-log source, diagnosed from a rate, and fixed with a firmware update confirmed two independent ways. - [A CPU-bound workload](https://jmrplens.github.io/mikroscope/playbooks/cpu/): A console loop that saturates one core of the reference RB5009 for a minute — why the device total reads 29 %, how the scheduler’s migration shows at 10 Hz, and what the temperature and frequency did. - [A packet flood](https://jmrplens.github.io/mikroscope/playbooks/packet-flood/): Ten seconds of ICMP flood at the reference RB5009’s own address — the switch interrupt that stands in for an interface counter, the one core that paid, and the time_squeeze counter worth watching. - [Flash wear](https://jmrplens.github.io/mikroscope/playbooks/flash-wear/): The reference RB5009 writes to its NAND at idle without being asked — how to see it in the YAFFS counters, trace it to a logging rule, and read the ECC counters that warn before a block is lost. - [Conntrack without the API](https://jmrplens.github.io/mikroscope/playbooks/conntrack/): The container’s own namespace reports zero tracked connections, but the global slab allocator does not — how to read the router’s real conntrack population and its ceiling from files, and why no storm was provoked to show it. ## Limits - [The resolution floor is the kernel’s](https://jmrplens.github.io/mikroscope/limits/): Why a CPU reading cannot be finer than the kernel’s 10 ms tick, the one source that reads beneath it, and how far back the agent can remember. - [The router’s CPU, the container’s network](https://jmrplens.github.io/mikroscope/limits/namespaces/): Which kernel files a RouterOS container sees as the router’s and which as its own, why privileged does not change that, and the conntrack count that gets through anyway. - [What privileged buys](https://jmrplens.github.io/mikroscope/limits/privileged/): Why the agent’s container runs with privileged=yes by default, the sources that setting makes readable, and the network, processes and sensors it still does not reach. - [Each source at its own floor](https://jmrplens.github.io/mikroscope/limits/source-floors/): Which sources the agent reads on every tick and which it reads or stores less often, the named reason each one reports, and FLOOR_HZ, the one setting that turns every floor off. ## Security - [What runs where](https://jmrplens.github.io/mikroscope/security/): Which piece of mikroscope runs on the router and which on your host, what each one reaches, and where every credential lives. - [The API user](https://jmrplens.github.io/mikroscope/security/api-user/): The dedicated RouterOS user the collector logs in as, the policy it needs for each command, and what that policy lets it read. - [What --expose opens](https://jmrplens.github.io/mikroscope/security/expose/): The two tagged firewall rules install --expose adds, who can reach the agent through them, and why the token becomes mandatory. - [What the installer refuses](https://jmrplens.github.io/mikroscope/security/installer/): The objects install will not build on, the values it will not put in a RouterOS command, and how uninstall proves it left nothing behind. ## Reference - [Commands and flags](https://jmrplens.github.io/mikroscope/reference/cli/): Every verb of the mikroscope CLI, every flag with its default, its range and the MIKROSCOPE_* variable that sets it, read from cmd/mikroscope. - [Environment variables](https://jmrplens.github.io/mikroscope/reference/environment/): The MIKROSCOPE_* variables the CLI reads, the credentials that exist only as variables, and the envlist variables the agent reads on the router. - [The agent’s HTTP endpoints](https://jmrplens.github.io/mikroscope/reference/http/): Every path the agent serves on the veth, its query parameters, what it returns, how the token guards it, and the line formats of /snapshot and /stream. - [Prometheus metric families](https://jmrplens.github.io/mikroscope/reference/metrics/): Every family on the agent’s /metrics and on the collector’s --prom exposition, grouped by source, with its type, its labels and when it is absent. - [InfluxDB and SQL measurements](https://jmrplens.github.io/mikroscope/reference/measurements/): Every measurement the InfluxDB line-protocol encoder writes and every table the SQL sink creates, with tags, fields, columns, keys, units and whether each value is a delta or a level. - [RouterOS ports and kernel names](https://jmrplens.github.io/mikroscope/reference/port-names/): The kernel log says eth5 where RouterOS says ether6 — how to measure the mapping on a dead port in one safe step, what the agent ships for the RB5009, and how much of that table was measured. - [When something does not work](https://jmrplens.github.io/mikroscope/reference/troubleshooting/): The symptoms this project produces, in the words you actually see — a RouterOS error, a container that exits, an empty panel, a sink that drops — with what each one means and the page that explains it. - [How the project tests itself](https://jmrplens.github.io/mikroscope/reference/testing/): The three layers of test — the bytes each sink puts on the wire, whether a real store accepts them, and whether the dashboards' own queries answer — what each one proves, what none of them prove, and the command for each. ## About - [Where the project stands](https://jmrplens.github.io/mikroscope/about/status/): What works end to end, what it costs on the one device it has run on, what was found and not fixed, and what the release publishes. - [The mark](https://jmrplens.github.io/mikroscope/about/brand/): Nine sample bars and the line of their own mean, why none of it is drawn at partial opacity, and the contrast each tone measures against its page. - [Lineage and licence](https://jmrplens.github.io/mikroscope/about/lineage/): Which parts of mikroscope came from cs-routeros-bouncer and from go-routeros, what changed on the way, and the MIT licence both arrive under. ## Machine-readable references - [Full documentation](https://jmrplens.github.io/mikroscope/llms-full.txt) (729 KB): every English page concatenated, in this order Every page listed above is also served as markdown at its own path with `index.md` appended, which is the cheapest way to read one page as text. ## Other languages - [Spanish documentation index](https://jmrplens.github.io/mikroscope/es/llms.txt): the same documentation in Spanish, page for page