Berik Ashimov // senior.it.engineer
Download CV
POSTS / MIKROTIK

Monitoring RouterOS 7: SNMPv3, Prometheus, and the Metrics That Actually Matter

// series · MikroTik RouterOS 7 Guide part 26 of 35
  1. ... 23 earlier
  2. Scheduler and Event-Driven Automation on RouterOS 7: Scripts That Run Themselves
  3. Automating RouterOS 7 with the REST API and Ansible: Desired State, Finally
  4. Monitoring RouterOS 7: SNMPv3, Prometheus, and the Metrics That Actually Matter
  5. RouterOS 7 Logging and Audit: Syslog, Firewall Logs, and NetFlow Without the Noise
  6. Backup, Export and Upgrades on RouterOS 7: Recoverable by Design
  7. ... 7 later
view the full series →

Most MikroTik deployments I audit have exactly one form of monitoring: someone opens WinBox when users complain. The router that carried traffic flawlessly for 400 days gets zero graphs, and then one day conntrack fills up, or a single CPU core pins at 100% while the average looks fine, and nobody can say when it started because nothing was recording.

Routers fail gradually before they fail completely. Interface errors creep up as an SFP dies. Connection counts climb toward max-entries during a slow UDP flood. CPU core 0 saturates while cores 1–3 idle. Every one of these is visible days in advance — if something is looking.

RouterOS 7 gives you three ways to get data out: SNMP (universal, boring, works), the API (what the good Prometheus exporters use), and the REST API (7.1+, easiest for ad-hoc scripting). This article sets up all three and — more importantly — tells you which metrics deserve alerts.

What Actually Matters

Before tooling, the signal list. These are the metrics that predict MikroTik outages in practice:

MetricWhyWhere
CPU per core, not averageIRQ-bound work pins one core; average hides it/system resource cpu print
Conntrack count vs maxTable full = new connections silently dropped/ip firewall connection tracking print
Interface errors / dropsDying SFPs, duplex mismatch, overruns/interface ethernet print stats
Wireless signal / CCQClient experience degrades long before disassocregistration table
Temperature, voltage, fansHardware death foretold/system health print
Memory freeSlow leaks in long-running 7.x versions happen/system resource print
Firmware/version driftFleet consistency/system routerboard print

The per-core point deserves emphasis. A CCR2004 showing “25% CPU” may actually be one core at 100% handling all PPPoE or IPsec interrupts. Check it directly:

Terminal window
/system resource cpu print
# Columns: cpu, load, irq, disk — watch for one core loaded while others idle
# Find what's eating it
/tool profile duration=10s

Conntrack is the other classic silent killer. When the table is full, the router drops new flows and existing sessions keep working — so it looks like “the internet is flaky” rather than “the router is down”:

Terminal window
/ip firewall connection tracking print
# total-entries vs max-entries — alert at 70%

SNMPv3: The Baseline

SNMP is still the lowest-friction path into Zabbix, LibreNMS, or PRTG. RouterOS ships with SNMP disabled and a default public community — enable the service, but never use that community. v1/v2c is cleartext; use SNMPv3 with authentication and encryption (security=private in MikroTik terms, authPriv in SNMP terms).

Terminal window
# Enable SNMP, set identity info
/snmp set enabled=yes contact="noc@example.com" location="rack-12-hel1"
# Neutralize the default public community
/snmp community set [find default=yes] name=not-public read-access=no addresses=127.0.0.1
# SNMPv3 user: SHA1 auth + AES privacy, restricted to the monitoring host
/snmp community add name=monitor security=private \
authentication-protocol=SHA1 authentication-password=Str0ngAuthPass \
encryption-protocol=AES encryption-password=Str0ngPrivPass \
addresses=10.0.20.10/32 read-access=yes write-access=no

Both passwords must be at least 8 characters. The addresses= restriction matters: SNMP runs on UDP 161 and has no lockout mechanism, so scope it to your collector and firewall it on the input chain anyway (the management-plane article later in this series covers the firewall side).

Verify from the collector:

Terminal window
snmpwalk -v3 -l authPriv -u monitor \
-a SHA -A 'Str0ngAuthPass' -x AES -X 'Str0ngPrivPass' \
10.0.20.1 1.3.6.1.2.1.1

Traps exist too (/snmp set trap-target=10.0.20.10 trap-version=3 trap-community=monitor trap-generators=interfaces), but I treat SNMP traps as best-effort — polling plus syslog covers the same ground more reliably.

Prometheus: mktxp Is the Answer

If you run Prometheus and Grafana, skip SNMP exporters and generic scripts. The community has converged on mktxp — a Python exporter that talks the RouterOS API (TCP 8728), supports many routers concurrently, and ships with a genuinely good Grafana dashboard (ID 13679). The older Go mikrotik-exporter still works but sees far less maintenance; for new deployments use mktxp.

First, a dedicated read-only API user on each router:

Terminal window
/user group add name=monitoring policy=api,read
/user add name=mktxp group=monitoring password=GeneratedLongPassword \
address=10.0.20.10/32

The address= on the user means those credentials are useless from anywhere but the monitoring host — cheap defense in depth.

Then mktxp.conf on the collector:

/home/mktxp/mktxp/mktxp.conf
[edge-router-1]
hostname = 10.0.20.1
port = 8728
username = mktxp
password = GeneratedLongPassword
use_ssl = False
health = True
interface = True
firewall = True
connections = True # conntrack count — the alert you actually want
route = True
wireless = True
capsman = True
dhcp = True

And the Prometheus scrape job:

Terminal window
# prometheus.yml
scrape_configs:
- job_name: 'mikrotik'
static_configs:
- targets: ['mktxp-host:49090']

Alert rules worth having from day one: conntrack above 70% of max, any interface error counter increasing, per-core CPU above 85% for 5 minutes, temperature above the platform’s spec, and mktxp scrape failures themselves (a router that stops answering its API is a signal, not a gap).

REST API: Polling Without an Exporter

RouterOS 7.1+ exposes a REST API over the www-ssl service — every console command mapped to a URL under /rest/. It uses HTTP basic auth against normal router users. Do not enable plain www for this; put a certificate on www-ssl and restrict the service address.

Terminal window
/ip service set www-ssl disabled=no certificate=mgmt-cert address=10.0.20.0/24

Then anything you can print, you can GET:

Terminal window
# Full resource state
curl -sk -u mktxp:GeneratedLongPassword \
https://10.0.20.1/rest/system/resource
# Just the fields you care about
curl -sk -u mktxp:GeneratedLongPassword \
"https://10.0.20.1/rest/interface?.proplist=name,rx-error,tx-error,running"
# Health sensors
curl -sk -u mktxp:GeneratedLongPassword \
https://10.0.20.1/rest/system/health

All values come back as JSON strings, and commands time out at 60 seconds. REST is perfect for a cron job that checks 50 routers for version drift, or for wiring a quick check into a CI pipeline before and after config pushes. It is not a streaming interface — there is no long-poll or subscribe; you poll.

Hardware Health

On physical RouterBOARD and CCR hardware, /system health exposes temperature, voltage, fan speeds, and on some models PSU state and power consumption:

Terminal window
/system health print
# Columns: name, value, type
# e.g. temperature 41 C, voltage 24.2 V, fan1 4980 RPM

What to watch:

  • Voltage on PoE- or DC-fed devices. A slowly sagging supply (24.2 → 22.1 V over weeks) is a failing PSU or corroding connector. Sudden reboots with no log entries are almost always power.
  • Temperature. Note that via SNMP and the API some platforms report temperature multiplied by 10 (415 = 41.5 °C) while the CLI shows the real value — normalize in your collector, or your “critical: 415 degrees” alert will cause a fun morning.
  • Fans on CCRs. A dead fan gives you weeks of margin in January and none in July.

CHR instances and x86 installs have no health subsystem — monitor the hypervisor instead.

Wireless: CCQ and Its Successors

On the legacy /interface wireless driver, CCQ (Client Connection Quality) is the one number that summarizes client experience — it factors retransmissions and rate degradation. Watch it per client:

Terminal window
/interface wireless registration-table print stats
# tx-ccq / rx-ccq below ~70% = investigate interference or coverage

The newer /interface/wifi driver (wifi-qcom packages on ax hardware) does not expose CCQ. There you monitor signal per registration plus tx/rx PHY rates:

Terminal window
/interface/wifi registration-table print
# signal worse than -75 dBm or rates stuck at minimums = same conversation

mktxp’s wireless and capsman collectors pick both variants up, so the Grafana dashboard shows per-client signal history — which turns “WiFi was weird yesterday” tickets into answerable questions.

Verification: Prove the Pipeline Works

Monitoring that has never fired is untested code. After setup:

Terminal window
# Generate interface counter movement and watch it appear in Grafana
/tool bandwidth-test address=10.0.20.10 direction=both duration=30s
# Confirm SNMP answers only from the collector (this should time out elsewhere)
# From a non-collector host: snmpwalk -v3 ... 10.0.20.1 -> timeout
# Watch what the exporter's user is doing
/user active print
/log print where message~"logged in"

Then pull the power on a test AP and time how long until you get paged. If the answer is “we didn’t,” fix that before trusting anything else.

Closing Thoughts

Minimum viable RouterOS monitoring: mktxp + Prometheus + the 13679 dashboard, SNMPv3 only if a legacy NMS requires it, and alerts on per-core CPU, conntrack percentage, interface errors, and temperature. That covers perhaps 90% of the failures these boxes actually have.

Two habits complete the picture. First, monitor the monitoring — scrape failures are first-class alerts. Second, keep retention long enough to answer “when did this start?” — 30 days minimum, because the interesting degradations are slow.

Metrics tell you that something happened. The next article covers logging and NetFlow — which tell you what happened. I covered the equivalent stack for VyOS in the VyOS Guide’s observability article; the philosophy is identical, only the tooling changes.

// share