MikroTik Dashboard Creation with InfluxDB and Grafana: Complete Setup Guide
1. Introduction: Why Monitor Your MikroTik Network?
This guide teaches you to build professional MikroTik monitoring dashboards using the TIG stack:
- Telegraf: Metrics collection agent
- InfluxDB: Time-series database
- Grafana: Visualization platform
What You Will Learn
- Configure SNMP on MikroTik RouterOS devices
- Install and configure InfluxDB 2.x for network metrics
- Set up Telegraf to collect MikroTik SNMP data
- Build comprehensive Grafana dashboards
- Create alerts for proactive monitoring
- Scale the solution for multi-site deployments
Prerequisites
| Requirement | Details |
|---|---|
| MikroTik Device | RouterOS 6.x or 7.x with admin access |
| Linux Server | Ubuntu 22.04 LTS (2 CPU, 4GB RAM minimum) |
| Network Access | UDP 161 (SNMP) from server to MikroTik devices |
| Knowledge | Basic Linux CLI and MikroTik RouterOS familiarity |
2. Understanding the MikroTik Monitoring Architecture
2.1 Components Overview
| Component | Role | Port |
|---|---|---|
| MikroTik RouterOS | Data source (SNMP responder) | UDP 161 |
| Telegraf | Metrics collection and forwarding | N/A (outbound only) |
| InfluxDB | Time-series data storage | TCP 8086 |
| Grafana | Visualization and alerting | TCP 3000 |
2.2 Why Choose This Stack for MikroTik Monitoring?
| Advantage | Description |
|---|---|
| Cost | 100% open-source with no licensing fees |
| Scalability | Monitor 1 to 10,000+ devices |
| Flexibility | Custom dashboards tailored to your needs |
| Integration | Works with existing monitoring infrastructure |
| Alerting | Enterprise-grade notification capabilities |
| Community | Large ecosystem of pre-built dashboards and plugins |
Comparison with MikroTik The Dude
| Feature | TIG Stack | The Dude |
|---|---|---|
| Historical Data | Unlimited retention | Limited |
| Custom Dashboards | Fully customizable | Limited customization |
| Multi-Vendor Support | Yes | MikroTik-focused |
| API Access | Full REST API | Limited |
| Clustering | Supported | Not supported |
3. Setting Up InfluxDB for MikroTik Metrics Storage
3.1 InfluxDB Installation on Ubuntu 22.04
System Requirements
| Scale | Devices | CPU | RAM | Storage |
|---|---|---|---|---|
| Small | 1-50 | 2 cores | 4 GB | 50 GB SSD |
| Medium | 50-500 | 4 cores | 16 GB | 200 GB SSD |
| Large | 500+ | 8+ cores | 32+ GB | 500+ GB SSD |
Installation Steps
# Step 1: Add InfluxDB repository key
wget -q https://repos.influxdata.com/influxdata-archive_compat.key
echo '393e8779c89ac8d958f81f942f9ad7fb82a25e133faddaf92e15b16e6ac9ce4c influxdata-archive_compat.key' | sha256sum -c && cat influxdata-archive_compat.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null
# Step 2: Add InfluxDB repository
echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main' | sudo tee /etc/apt/sources.list.d/influxdata.list
# Step 3: Update and install InfluxDB
sudo apt update
sudo apt install influxdb2 -y
# Step 4: Start and enable InfluxDB service
sudo systemctl start influxdb
sudo systemctl enable influxdb
# Step 5: Verify installation
sudo systemctl status influxdb
influx version
3.2 Initial InfluxDB Configuration
Method 1: CLI Setup
# Run initial setup
influx setup \
--username admin \
--password YourSecurePassword123! \
--org NetworkMonitoring \
--bucket mikrotik_metrics \
--retention 90d \
--force
# Expected output:
# User Organization Bucket
# admin NetworkMonitoring mikrotik_metrics
Method 2: Web UI Setup
- Open browser:
http://YOUR_SERVER_IP:8086 - Click “Get Started”
- Enter username:
admin - Enter password:
YourSecurePassword123! - Enter organization:
NetworkMonitoring - Enter bucket name:
mikrotik_metrics - Set retention:
90 days - Click “Continue”
3.3 Creating API Tokens
Create Token for Telegraf (Write Access)
# Create write-only token for Telegraf
influx auth create \
--org NetworkMonitoring \
--description "Telegraf write token" \
--write-bucket mikrotik_metrics
# Save the token output - you will need it for Telegraf configuration
# Example output: xXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXxX==
Create Token for Grafana (Read Access)
# Create read-only token for Grafana
influx auth create \
--org NetworkMonitoring \
--description "Grafana read token" \
--read-bucket mikrotik_metrics
# Save this token for Grafana data source configuration
3.4 Creating Additional Buckets
# Create bucket for long-term storage (downsampled data)
influx bucket create \
--name mikrotik_metrics_longterm \
--org NetworkMonitoring \
--retention 365d
# Create bucket for high-frequency data
influx bucket create \
--name mikrotik_metrics_realtime \
--org NetworkMonitoring \
--retention 7d
3.5 InfluxDB Security Configuration
Enable HTTPS (Recommended for Production)
# Generate self-signed certificate (or use your CA-signed cert)
sudo mkdir -p /etc/influxdb/ssl
sudo openssl req -x509 -nodes -days 365 \
-newkey rsa:2048 \
-keyout /etc/influxdb/ssl/influxdb.key \
-out /etc/influxdb/ssl/influxdb.crt \
-subj "/CN=influxdb.yourdomain.local"
# Set permissions
sudo chown influxdb:influxdb /etc/influxdb/ssl/*
sudo chmod 600 /etc/influxdb/ssl/*
Update InfluxDB Configuration
# Edit /etc/influxdb/config.toml
sudo nano /etc/influxdb/config.toml
# /etc/influxdb/config.toml
[http]
bind-address = ":8086"
https-enabled = true
https-certificate = "/etc/influxdb/ssl/influxdb.crt"
https-private-key = "/etc/influxdb/ssl/influxdb.key"
# Restart InfluxDB
sudo systemctl restart influxdb
4. Configuring MikroTik SNMP for Metric Export
4.1 Enabling SNMP on MikroTik RouterOS
Basic SNMP Configuration (SNMPv2c)
# MikroTik RouterOS Terminal Commands
# Enable SNMP with community string
/snmp set enabled=yes
# Configure SNMP community
/snmp community set [ find default=yes ] name=public read-access=yes write-access=no
# Create a secure community (recommended)
/snmp community add name=M0n1t0r1ng2024! read-access=yes write-access=no addresses=10.0.0.50/32
# Set system information
/snmp set contact="noc@yourcompany.com" location="DataCenter-Rack5" trap-community=M0n1t0r1ng2024!
Secure SNMP Configuration (SNMPv3) – Recommended
# Create SNMPv3 user with authentication and encryption
/snmp community remove [find]
/snmp set enabled=yes trap-version=3
/snmp community add \
name=v3secure \
security=private \
authentication-protocol=SHA1 \
authentication-password=AuthPass123! \
encryption-protocol=AES \
encryption-password=EncryptPass123! \
read-access=yes \
write-access=no \
addresses=10.0.0.50/32
4.2 Firewall Rules for SNMP Security
# Allow SNMP only from monitoring server
/ip firewall filter add \
chain=input \
action=accept \
protocol=udp \
dst-port=161 \
src-address=10.0.0.50 \
comment="Allow SNMP from monitoring server"
# Add before drop rule - adjust position as needed
/ip firewall filter move [find comment="Allow SNMP from monitoring server"] 0
4.3 Essential MikroTik SNMP OIDs
System OIDs
| Metric | OID | Description |
|---|---|---|
| System Name | 1.3.6.1.2.1.1.5.0 | Device hostname |
| System Uptime | 1.3.6.1.2.1.1.3.0 | Time since last reboot |
| System Description | 1.3.6.1.2.1.1.1.0 | RouterOS version info |
| CPU Load | 1.3.6.1.2.1.25.3.3.1.2 | CPU utilization percentage |
| Total Memory | 1.3.6.1.2.1.25.2.3.1.5.65536 | Total RAM in units |
| Used Memory | 1.3.6.1.2.1.25.2.3.1.6.65536 | Used RAM in units |
Interface OIDs (IF-MIB)
| Metric | OID | Type |
|---|---|---|
| Interface Name | 1.3.6.1.2.1.2.2.1.2 | String |
| Interface Status | 1.3.6.1.2.1.2.2.1.8 | Integer (1=up, 2=down) |
| Bytes In | 1.3.6.1.2.1.31.1.1.1.6 | Counter64 |
| Bytes Out | 1.3.6.1.2.1.31.1.1.1.10 | Counter64 |
| Packets In | 1.3.6.1.2.1.2.2.1.11 | Counter32 |
| Packets Out | 1.3.6.1.2.1.2.2.1.17 | Counter32 |
| Errors In | 1.3.6.1.2.1.2.2.1.14 | Counter32 |
| Errors Out | 1.3.6.1.2.1.2.2.1.20 | Counter32 |
| Interface Speed | 1.3.6.1.2.1.31.1.1.1.15 | Gauge (Mbps) |
MikroTik-Specific OIDs
| Metric | OID | Description |
|---|---|---|
| RouterOS Version | 1.3.6.1.4.1.14988.1.1.4.4.0 | Firmware version string |
| Board Name | 1.3.6.1.4.1.14988.1.1.7.8.0 | Hardware model |
| Serial Number | 1.3.6.1.4.1.14988.1.1.7.3.0 | Device serial |
| Temperature | 1.3.6.1.4.1.14988.1.1.3.10.0 | CPU temperature (if supported) |
| Voltage | 1.3.6.1.4.1.14988.1.1.3.8.0 | Input voltage |
| Wireless Clients | 1.3.6.1.4.1.14988.1.1.1.3.1.6 | Connected wireless clients |
4.4 Testing SNMP Connectivity
# Install SNMP tools on monitoring server
sudo apt install snmp snmp-mibs-downloader -y
# Enable MIBs
sudo sed -i 's/mibs :/# mibs :/' /etc/snmp/snmp.conf
# Test SNMPv2c connectivity
snmpwalk -v2c -c M0n1t0r1ng2024! 10.0.0.1 1.3.6.1.2.1.1.1.0
# Expected output:
# SNMPv2-MIB::sysDescr.0 = STRING: RouterOS RB4011iGS+
# Test SNMPv3 connectivity
snmpwalk -v3 -l authPriv \
-u v3secure \
-a SHA -A AuthPass123! \
-x AES -X EncryptPass123! \
10.0.0.1 1.3.6.1.2.1.1.1.0
# Get interface list
snmpwalk -v2c -c M0n1t0r1ng2024! 10.0.0.1 1.3.6.1.2.1.2.2.1.2
# Get CPU utilization
snmpwalk -v2c -c M0n1t0r1ng2024! 10.0.0.1 1.3.6.1.2.1.25.3.3.1.2
4.5 Complete MikroTik SNMP Configuration Script
# Complete SNMP Configuration Script for MikroTik
# Copy and paste into RouterOS terminal
/snmp
set enabled=yes contact="noc@company.com" location="DC1-Rack5" trap-version=2
/snmp community
remove [find]
add name=M0n1t0r1ng2024! addresses=10.0.0.50/32 read-access=yes write-access=no security=none
/ip firewall filter
add chain=input action=accept protocol=udp dst-port=161 src-address=10.0.0.50 comment="SNMP Monitoring"
/system logging
add topics=snmp action=memory
5. Deploying Telegraf as the Metrics Collector
5.1 Telegraf Installation
# Telegraf uses the same repository as InfluxDB
# If not already added:
wget -q https://repos.influxdata.com/influxdata-archive_compat.key
echo '393e8779c89ac8d958f81f942f9ad7fb82a25e133faddaf92e15b16e6ac9ce4c influxdata-archive_compat.key' | sha256sum -c && cat influxdata-archive_compat.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null
echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main' | sudo tee /etc/apt/sources.list.d/influxdata.list
# Install Telegraf
sudo apt update
sudo apt install telegraf -y
# Stop Telegraf before configuration
sudo systemctl stop telegraf
5.2 Telegraf Configuration Structure
# Backup default configuration
sudo mv /etc/telegraf/telegraf.conf /etc/telegraf/telegraf.conf.backup
# Create new configuration
sudo nano /etc/telegraf/telegraf.conf
5.3 Complete Telegraf Configuration for MikroTik
# /etc/telegraf/telegraf.conf
# Telegraf Configuration for MikroTik SNMP Monitoring
# Global Agent Configuration
[agent]
interval = "60s"
round_interval = true
metric_batch_size = 1000
metric_buffer_limit = 10000
collection_jitter = "5s"
flush_interval = "10s"
flush_jitter = "5s"
precision = "0s"
hostname = ""
omit_hostname = false
###############################################################################
# OUTPUT PLUGINS #
###############################################################################
[[outputs.influxdb_v2]]
urls = ["http://localhost:8086"]
token = "YOUR_TELEGRAF_TOKEN_HERE"
organization = "NetworkMonitoring"
bucket = "mikrotik_metrics"
## Optional: Enable gzip compression
# content_encoding = "gzip"
###############################################################################
# INPUT PLUGINS #
###############################################################################
# MikroTik System Information
[[inputs.snmp]]
name = "mikrotik"
agents = [
"10.0.0.1:161",
"10.0.0.2:161",
"10.0.0.3:161"
]
timeout = "10s"
retries = 3
version = 2
community = "M0n1t0r1ng2024!"
## Agent host tag
agent_host_tag = "source"
## System Information
[[inputs.snmp.field]]
name = "hostname"
oid = "RFC1213-MIB::sysName.0"
is_tag = true
[[inputs.snmp.field]]
name = "uptime"
oid = "DISMAN-EXPRESSION-MIB::sysUpTimeInstance"
[[inputs.snmp.field]]
name = "system_description"
oid = "SNMPv2-MIB::sysDescr.0"
## CPU Utilization
[[inputs.snmp.field]]
name = "cpu_load"
oid = "HOST-RESOURCES-MIB::hrProcessorLoad.1"
## Memory - Total
[[inputs.snmp.field]]
name = "memory_total"
oid = "1.3.6.1.2.1.25.2.3.1.5.65536"
## Memory - Used
[[inputs.snmp.field]]
name = "memory_used"
oid = "1.3.6.1.2.1.25.2.3.1.6.65536"
## MikroTik Specific
[[inputs.snmp.field]]
name = "ros_version"
oid = "1.3.6.1.4.1.14988.1.1.4.4.0"
[[inputs.snmp.field]]
name = "board_name"
oid = "1.3.6.1.4.1.14988.1.1.7.8.0"
[[inputs.snmp.field]]
name = "serial_number"
oid = "1.3.6.1.4.1.14988.1.1.7.3.0"
## Temperature (if supported)
[[inputs.snmp.field]]
name = "cpu_temperature"
oid = "1.3.6.1.4.1.14988.1.1.3.10.0"
## Voltage
[[inputs.snmp.field]]
name = "voltage"
oid = "1.3.6.1.4.1.14988.1.1.3.8.0"
# MikroTik Interface Statistics
[[inputs.snmp]]
name = "mikrotik_interfaces"
agents = [
"10.0.0.1:161",
"10.0.0.2:161",
"10.0.0.3:161"
]
timeout = "10s"
retries = 3
version = 2
community = "M0n1t0r1ng2024!"
agent_host_tag = "source"
[[inputs.snmp.field]]
name = "hostname"
oid = "RFC1213-MIB::sysName.0"
is_tag = true
## Interface Table
[[inputs.snmp.table]]
name = "interface"
inherit_tags = ["hostname"]
[[inputs.snmp.table.field]]
name = "ifName"
oid = "IF-MIB::ifName"
is_tag = true
[[inputs.snmp.table.field]]
name = "ifAlias"
oid = "IF-MIB::ifAlias"
is_tag = true
[[inputs.snmp.table.field]]
name = "ifOperStatus"
oid = "IF-MIB::ifOperStatus"
[[inputs.snmp.table.field]]
name = "ifAdminStatus"
oid = "IF-MIB::ifAdminStatus"
[[inputs.snmp.table.field]]
name = "ifHighSpeed"
oid = "IF-MIB::ifHighSpeed"
[[inputs.snmp.table.field]]
name = "ifHCInOctets"
oid = "IF-MIB::ifHCInOctets"
[[inputs.snmp.table.field]]
name = "ifHCOutOctets"
oid = "IF-MIB::ifHCOutOctets"
[[inputs.snmp.table.field]]
name = "ifInUcastPkts"
oid = "IF-MIB::ifInUcastPkts"
[[inputs.snmp.table.field]]
name = "ifOutUcastPkts"
oid = "IF-MIB::ifOutUcastPkts"
[[inputs.snmp.table.field]]
name = "ifInErrors"
oid = "IF-MIB::ifInErrors"
[[inputs.snmp.table.field]]
name = "ifOutErrors"
oid = "IF-MIB::ifOutErrors"
[[inputs.snmp.table.field]]
name = "ifInDiscards"
oid = "IF-MIB::ifInDiscards"
[[inputs.snmp.table.field]]
name = "ifOutDiscards"
oid = "IF-MIB::ifOutDiscards"
# MikroTik Wireless Statistics (Optional - for devices with wireless)
[[inputs.snmp]]
name = "mikrotik_wireless"
agents = [
"10.0.0.10:161"
]
timeout = "10s"
retries = 3
version = 2
community = "M0n1t0r1ng2024!"
agent_host_tag = "source"
[[inputs.snmp.field]]
name = "hostname"
oid = "RFC1213-MIB::sysName.0"
is_tag = true
## Wireless Registration Table
[[inputs.snmp.table]]
name = "wireless_clients"
inherit_tags = ["hostname"]
[[inputs.snmp.table.field]]
name = "interface"
oid = "1.3.6.1.4.1.14988.1.1.1.2.1.1"
is_tag = true
[[inputs.snmp.table.field]]
name = "mac_address"
oid = "1.3.6.1.4.1.14988.1.1.1.2.1.2"
[[inputs.snmp.table.field]]
name = "signal_strength"
oid = "1.3.6.1.4.1.14988.1.1.1.2.1.3"
[[inputs.snmp.table.field]]
name = "tx_rate"
oid = "1.3.6.1.4.1.14988.1.1.1.2.1.8"
[[inputs.snmp.table.field]]
name = "rx_rate"
oid = "1.3.6.1.4.1.14988.1.1.1.2.1.9"
[[inputs.snmp.table.field]]
name = "uptime"
oid = "1.3.6.1.4.1.14988.1.1.1.2.1.11"
# BGP Session Monitoring (Optional - for BGP routers)
[[inputs.snmp]]
name = "mikrotik_bgp"
agents = [
"10.0.0.1:161"
]
timeout = "10s"
retries = 3
version = 2
community = "M0n1t0r1ng2024!"
agent_host_tag = "source"
[[inputs.snmp.field]]
name = "hostname"
oid = "RFC1213-MIB::sysName.0"
is_tag = true
[[inputs.snmp.table]]
name = "bgp_peer"
inherit_tags = ["hostname"]
[[inputs.snmp.table.field]]
name = "peer_address"
oid = "BGP4-MIB::bgpPeerRemoteAddr"
is_tag = true
[[inputs.snmp.table.field]]
name = "peer_state"
oid = "BGP4-MIB::bgpPeerState"
[[inputs.snmp.table.field]]
name = "peer_as"
oid = "BGP4-MIB::bgpPeerRemoteAs"
[[inputs.snmp.table.field]]
name = "prefixes_received"
oid = "BGP4-MIB::bgpPeerInUpdateElapsedTime"
5.4 SNMPv3 Configuration Alternative
# SNMPv3 Configuration Example
[[inputs.snmp]]
name = "mikrotik"
agents = ["10.0.0.1:161"]
timeout = "10s"
retries = 3
## SNMPv3 Settings
version = 3
sec_name = "v3secure"
sec_level = "authPriv"
auth_protocol = "SHA"
auth_password = "AuthPass123!"
priv_protocol = "AES"
priv_password = "EncryptPass123!"
# ... rest of configuration
5.5 Start and Verify Telegraf
# Test configuration syntax
sudo telegraf --config /etc/telegraf/telegraf.conf --test
# Start Telegraf
sudo systemctl start telegraf
sudo systemctl enable telegraf
# Check status
sudo systemctl status telegraf
# View logs for errors
sudo journalctl -u telegraf -f
# Verify data in InfluxDB
influx query 'from(bucket: "mikrotik_metrics") |> range(start: -5m) |> limit(n: 10)'
6. Alternative Data Collection Methods
6.1 MikroTik Traffic Flow (NetFlow/IPFIX)
Traffic Flow provides detailed flow-level data. Use it for bandwidth analysis by IP, protocol, or application.
When to Use Traffic Flow
- Per-IP traffic accounting
- Application/protocol analysis
- Top talkers reports
- Security analysis
MikroTik Traffic Flow Configuration
# Enable Traffic Flow
/ip traffic-flow
set enabled=yes interfaces=ether1,ether2 cache-entries=16384
# Configure flow target (Telegraf server)
/ip traffic-flow target
add dst-address=10.0.0.50 port=2055 version=9
Telegraf NetFlow Input Configuration
# Add to telegraf.conf
[[inputs.netflow]]
service_address = "udp://:2055"
## Protocol version (9 = NetFlow v9, 10 = IPFIX)
protocol = "netflow v9"
6.2 MikroTik API-Based Collection
The MikroTik API provides access to metrics not available via SNMP.
RouterOS Script to Push Metrics to InfluxDB
# MikroTik RouterOS Script: Push metrics to InfluxDB
# Schedule this script to run every minute
:local influxHost "10.0.0.50"
:local influxPort "8086"
:local influxOrg "NetworkMonitoring"
:local influxBucket "mikrotik_metrics"
:local influxToken "YOUR_TOKEN_HERE"
:local hostname [/system identity get name]
:local cpuLoad [/system resource get cpu-load]
:local freeMemory [/system resource get free-memory]
:local totalMemory [/system resource get total-memory]
:local uptime [/system resource get uptime]
:local data "mikrotik_api,host=$hostname cpu_load=$cpuLoad,free_memory=$freeMemory,total_memory=$totalMemory"
/tool fetch mode=https \
url="https://$influxHost:$influxPort/api/v2/write?org=$influxOrg&bucket=$influxBucket" \
http-method=post \
http-header-field="Authorization: Token $influxToken,Content-Type: text/plain" \
http-data=$data \
output=none
Schedule the Script
# Add scheduler
/system scheduler add name=push-metrics interval=1m \
on-event="/system script run push-to-influxdb"
6.3 Comparison of Collection Methods
| Method | Best For | CPU Impact | Data Granularity |
|---|---|---|---|
| SNMP | Interface stats, system health | Low | Counter-based |
| Traffic Flow | Per-flow analysis | Medium | Flow-level |
| API | Custom metrics, configuration data | Low | On-demand |
7. Installing and Configuring Grafana
7.1 Grafana Installation
# Add Grafana repository
sudo apt install -y apt-transport-https software-properties-common wget
sudo mkdir -p /etc/apt/keyrings/
wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | sudo tee /etc/apt/keyrings/grafana.gpg > /dev/null
echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" | sudo tee -a /etc/apt/sources.list.d/grafana.list
# Install Grafana
sudo apt update
sudo apt install grafana -y
# Start and enable Grafana
sudo systemctl start grafana-server
sudo systemctl enable grafana-server
# Verify status
sudo systemctl status grafana-server
7.2 Initial Grafana Setup
- Open browser:
http://YOUR_SERVER_IP:3000 - Login with default credentials:
- Username:
admin - Password:
admin
- Username:
- Set new admin password when prompted
7.3 Connecting Grafana to InfluxDB
Add InfluxDB Data Source
- Navigate to: Configuration → Data Sources
- Click “Add data source”
- Select “InfluxDB”
- Configure as follows:
| Setting | Value |
|---|---|
| Name | InfluxDB-MikroTik |
| Query Language | Flux |
| URL | http://localhost:8086 |
| Organization | NetworkMonitoring |
| Token | [Your Grafana read token] |
| Default Bucket | mikrotik_metrics |
- Click “Save & Test”
- Verify “Data source is working” message
7.4 Enable HTTPS for Grafana (Production)
# Generate certificate (or use your CA-signed cert)
sudo mkdir -p /etc/grafana/ssl
sudo openssl req -x509 -nodes -days 365 \
-newkey rsa:2048 \
-keyout /etc/grafana/ssl/grafana.key \
-out /etc/grafana/ssl/grafana.crt \
-subj "/CN=grafana.yourdomain.local"
# Set permissions
sudo chown grafana:grafana /etc/grafana/ssl/*
sudo chmod 600 /etc/grafana/ssl/*
# Edit Grafana configuration
sudo nano /etc/grafana/grafana.ini
# /etc/grafana/grafana.ini
[server]
protocol = https
cert_file = /etc/grafana/ssl/grafana.crt
cert_key = /etc/grafana/ssl/grafana.key
http_port = 3000
# Restart Grafana
sudo systemctl restart grafana-server
8. Building Your MikroTik Dashboard: Step-by-Step
8.1 Creating Dashboard Variables
Device Selector Variable
- Create new dashboard: Dashboards → New Dashboard
- Click gear icon → Variables → Add variable
- Configure:
| Setting | Value |
|---|---|
| Name | device |
| Type | Query |
| Data source | InfluxDB-MikroTik |
Variable Query (Flux)
import "influxdata/influxdb/schema"
schema.tagValues(
bucket: "mikrotik_metrics",
tag: "hostname"
)
Interface Selector Variable
import "influxdata/influxdb/schema"
schema.tagValues(
bucket: "mikrotik_metrics",
tag: "ifName",
predicate: (r) => r.hostname == "${device}"
)
8.2 Essential Dashboard Panels
Panel 1: CPU Utilization Gauge
Panel Type: Gauge
from(bucket: "mikrotik_metrics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r._measurement == "mikrotik")
|> filter(fn: (r) => r.hostname == "${device}")
|> filter(fn: (r) => r._field == "cpu_load")
|> last()
Panel Settings:
- Min: 0, Max: 100
- Unit: Percent (0-100)
- Thresholds: Green (0-60), Yellow (60-80), Red (80-100)
Panel 2: Memory Usage Gauge
Panel Type: Gauge
from(bucket: "mikrotik_metrics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r._measurement == "mikrotik")
|> filter(fn: (r) => r.hostname == "${device}")
|> filter(fn: (r) => r._field == "memory_used" or r._field == "memory_total")
|> last()
|> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
|> map(fn: (r) => ({ r with _value: (float(v: r.memory_used) / float(v: r.memory_total)) * 100.0 }))
Panel 3: System Uptime
Panel Type: Stat
from(bucket: "mikrotik_metrics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r._measurement == "mikrotik")
|> filter(fn: (r) => r.hostname == "${device}")
|> filter(fn: (r) => r._field == "uptime")
|> last()
|> map(fn: (r) => ({ r with _value: float(v: r._value) / 8640000.0 }))
Unit: days
Panel 4: Interface Traffic (Bits per Second)
Panel Type: Time series
// Inbound Traffic
from(bucket: "mikrotik_metrics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r._measurement == "interface")
|> filter(fn: (r) => r.hostname == "${device}")
|> filter(fn: (r) => r.ifName == "${interface}")
|> filter(fn: (r) => r._field == "ifHCInOctets")
|> derivative(unit: 1s, nonNegative: true)
|> map(fn: (r) => ({ r with _value: r._value * 8.0 }))
|> yield(name: "Inbound")
// Outbound Traffic (Add as second query)
from(bucket: "mikrotik_metrics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r._measurement == "interface")
|> filter(fn: (r) => r.hostname == "${device}")
|> filter(fn: (r) => r.ifName == "${interface}")
|> filter(fn: (r) => r._field == "ifHCOutOctets")
|> derivative(unit: 1s, nonNegative: true)
|> map(fn: (r) => ({ r with _value: r._value * 8.0 * -1.0 }))
|> yield(name: "Outbound")
Panel Settings:
- Unit: bits/sec (SI)
- Fill opacity: 20
- Series 1 (Inbound): Green
- Series 2 (Outbound): Blue, Negative Y
Panel 5: Interface Status Table
Panel Type: Table
from(bucket: "mikrotik_metrics")
|> range(start: -5m)
|> filter(fn: (r) => r._measurement == "interface")
|> filter(fn: (r) => r.hostname == "${device}")
|> filter(fn: (r) => r._field == "ifOperStatus" or r._field == "ifHighSpeed")
|> last()
|> pivot(rowKey:["ifName"], columnKey: ["_field"], valueColumn: "_value")
|> map(fn: (r) => ({
r with
Status: if r.ifOperStatus == 1 then "Up" else "Down",
Speed: string(v: r.ifHighSpeed) + " Mbps"
}))
|> keep(columns: ["ifName", "Status", "Speed"])
Panel 6: Interface Errors
Panel Type: Time series
from(bucket: "mikrotik_metrics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r._measurement == "interface")
|> filter(fn: (r) => r.hostname == "${device}")
|> filter(fn: (r) => r._field == "ifInErrors" or r._field == "ifOutErrors")
|> derivative(unit: 1m, nonNegative: true)
Panel 7: Top Interfaces by Traffic
Panel Type: Bar gauge
from(bucket: "mikrotik_metrics")
|> range(start: -1h)
|> filter(fn: (r) => r._measurement == "interface")
|> filter(fn: (r) => r.hostname == "${device}")
|> filter(fn: (r) => r._field == "ifHCInOctets")
|> derivative(unit: 1s, nonNegative: true)
|> map(fn: (r) => ({ r with _value: r._value * 8.0 }))
|> mean()
|> group()
|> top(n: 10)
Panel 8: RouterOS Version Info
Panel Type: Stat
from(bucket: "mikrotik_metrics")
|> range(start: -5m)
|> filter(fn: (r) => r._measurement == "mikrotik")
|> filter(fn: (r) => r.hostname == "${device}")
|> filter(fn: (r) => r._field == "ros_version")
|> last()
Panel 9: CPU Temperature
Panel Type: Gauge
from(bucket: "mikrotik_metrics")
|> range(start: -5m)
|> filter(fn: (r) => r._measurement == "mikrotik")
|> filter(fn: (r) => r.hostname == "${device}")
|> filter(fn: (r) => r._field == "cpu_temperature")
|> last()
|> map(fn: (r) => ({ r with _value: float(v: r._value) / 10.0 }))
Unit: Celsius
Thresholds: Green (0-60), Yellow (60-75), Red (75-100)
8.4 Multi-Device Overview Dashboard
All Devices Status Table
from(bucket: "mikrotik_metrics")
|> range(start: -5m)
|> filter(fn: (r) => r._measurement == "mikrotik")
|> filter(fn: (r) => r._field == "cpu_load" or r._field == "uptime" or r._field == "memory_used")
|> last()
|> pivot(rowKey:["hostname"], columnKey: ["_field"], valueColumn: "_value")
|> map(fn: (r) => ({
r with
uptime_days: float(v: r.uptime) / 8640000.0,
memory_mb: float(v: r.memory_used) / 1048576.0
}))
|> keep(columns: ["hostname", "source", "cpu_load", "uptime_days", "memory_mb"])
Dashboard Links Configuration
Add links to navigate between dashboards:
- Dashboard Settings → Links
- Add new link:
| Setting | Value |
|---|---|
| Type | Dashboard |
| Title | Device Details |
| Include Variables | Yes |
9. Advanced MikroTik Grafana Dashboard Techniques
9.1 Calculated Metrics
Interface Utilization Percentage
from(bucket: "mikrotik_metrics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r._measurement == "interface")
|> filter(fn: (r) => r.hostname == "${device}")
|> filter(fn: (r) => r.ifName == "${interface}")
|> filter(fn: (r) => r._field == "ifHCInOctets" or r._field == "ifHighSpeed")
|> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
|> map(fn: (r) => ({
r with
_value: if r.ifHighSpeed > 0 then
(derivative(columns: ["ifHCInOctets"]) * 8.0) / (float(v: r.ifHighSpeed) * 1000000.0) * 100.0
else 0.0
}))
Memory Percentage with Transformation
from(bucket: "mikrotik_metrics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r._measurement == "mikrotik")
|> filter(fn: (r) => r.hostname == "${device}")
|> filter(fn: (r) => r._field == "memory_total" or r._field == "memory_used")
|> pivot(rowKey:["_time"], columnKey: ["_field"], valueColumn: "_value")
|> map(fn: (r) => ({
r with
memory_percent: (float(v: r.memory_used) / float(v: r.memory_total)) * 100.0,
memory_free_mb: float(v: r.memory_total - r.memory_used) / 1048576.0
}))
9.2 Threshold-Based Visualization
Status Panel Configuration
Create a status panel showing device health:
from(bucket: "mikrotik_metrics")
|> range(start: -5m)
|> filter(fn: (r) => r._measurement == "mikrotik")
|> filter(fn: (r) => r._field == "cpu_load")
|> last()
|> map(fn: (r) => ({
r with
status: if r._value < 60 then 0
else if r._value < 80 then 1
else 2
}))
Value Mappings:
- 0 → “Healthy” (Green)
- 1 → “Warning” (Yellow)
- 2 → “Critical” (Red)
9.3 Annotations for Network Events
Create Annotation Query
- Dashboard Settings → Annotations
- Add new annotation:
// Detect device reboots (uptime resets)
from(bucket: "mikrotik_metrics")
|> range(start: v.timeRangeStart, stop: v.timeRangeStop)
|> filter(fn: (r) => r._measurement == "mikrotik")
|> filter(fn: (r) => r.hostname == "${device}")
|> filter(fn: (r) => r._field == "uptime")
|> difference()
|> filter(fn: (r) => r._value < 0)
9.4 Custom Color Schemes
Use consistent colors across dashboards:
| Metric Type | Color (Hex) | Usage |
|---|---|---|
| Inbound Traffic | #73BF69 | Green |
| Outbound Traffic | #5794F2 | Blue |
| Errors | #F2495C | Red |
| CPU | #FF9830 | Orange |
| Memory | #B877D9 | Purple |
10. Setting Up Grafana Alerts for MikroTik Monitoring
10.1 Alert Rule Configuration
High CPU Alert
- Navigate to: Alerting → Alert rules → New alert rule
- Configure:
| Setting | Value |
|---|---|
| Name | MikroTik High CPU |
| Folder | Network Alerts |
| Evaluate every | 1m |
| For | 5m |
Alert Query
from(bucket: "mikrotik_metrics")
|> range(start: -5m)
|> filter(fn: (r) => r._measurement == "mikrotik")
|> filter(fn: (r) => r._field == "cpu_load")
|> mean()
|> group()
Alert Condition
- Condition: WHEN avg() OF query(A) IS ABOVE 80
Interface Down Alert
from(bucket: "mikrotik_metrics")
|> range(start: -5m)
|> filter(fn: (r) => r._measurement == "interface")
|> filter(fn: (r) => r._field == "ifOperStatus")
|> filter(fn: (r) => r.ifName =~ /ether1|sfp1|bridge/)
|> last()
|> filter(fn: (r) => r._value != 1)
High Memory Alert
from(bucket: "mikrotik_metrics")
|> range(start: -5m)
|> filter(fn: (r) => r._measurement == "mikrotik")
|> filter(fn: (r) => r._field == "memory_used" or r._field == "memory_total")
|> last()
|> pivot(rowKey:["hostname"], columnKey: ["_field"], valueColumn: "_value")
|> map(fn: (r) => ({ r with _value: (float(v: r.memory_used) / float(v: r.memory_total)) * 100.0 }))
|> filter(fn: (r) => r._value > 90)
10.2 Notification Channels
Email Notification Setup
# Edit /etc/grafana/grafana.ini
[smtp]
enabled = true
host = smtp.yourcompany.com:587
user = grafana@yourcompany.com
password = your_smtp_password
from_address = grafana@yourcompany.com
from_name = Grafana Alerts
Slack Notification Setup
- Navigate to: Alerting → Contact points → New contact point
- Select: Slack
- Configure:
| Setting | Value |
|---|---|
| Webhook URL | https://hooks.slack.com/services/YOUR/WEBHOOK/URL |
| Channel | #network-alerts |
| Username | Grafana |
PagerDuty Integration
| Setting | Value |
|---|---|
| Integration Key | Your PagerDuty integration key |
| Severity | critical |
10.3 Alert Best Practices
- Use “For” duration: Prevents flapping alerts (minimum 5 minutes)
- Group related alerts: Use labels for routing
- Set appropriate severity: Critical, Warning, Info
- Include context: Add device name and metric values in alert message
- Document runbooks: Link to troubleshooting guides in alert annotations
Alert Message Template
{{ define "alert_message" }}
Device: {{ .Labels.hostname }}
Metric: {{ .Labels.__name__ }}
Value: {{ .Values.A }}
Time: {{ .StartsAt }}
Dashboard: https://grafana.yourcompany.com/d/mikrotik?var-device={{ .Labels.hostname }}
Runbook: https://wiki.yourcompany.com/network/alerts/{{ .Labels.__name__ }}
{{ end }}
11. Pre-Built MikroTik Grafana Dashboards
11.1 Community Dashboard Resources
Grafana Dashboard Repository
| Dashboard | ID | Description |
|---|---|---|
| MikroTik SNMP | 14420 | Comprehensive SNMP dashboard |
| MikroTik Router | 10529 | Basic router monitoring |
| Network Device Overview | 1860 | Multi-vendor SNMP dashboard |
How to Import a Dashboard
- Navigate to: Dashboards → Import
- Enter Dashboard ID (e.g., 14420)
- Click “Load”
- Select your InfluxDB data source
- Click “Import”
11.2 Customizing Imported Dashboards
- Update variable queries to match your tag names
- Adjust time ranges and refresh intervals
- Add your organization’s branding
- Remove unused panels
- Add custom panels for specific metrics
11.3 Exporting Your Dashboard
# Export via API
curl -H "Authorization: Bearer YOUR_API_KEY" \
"http://localhost:3000/api/dashboards/uid/YOUR_DASHBOARD_UID" \
| jq '.dashboard' > mikrotik-dashboard.json
12. Scaling Your MikroTik Monitoring Solution
12.1 Multi-Site Deployment Strategies
Centralized Collection
- Single Telegraf instance polls all sites
- Requires network connectivity to all devices
- Simpler management
- Suitable for: <100 devices, low latency networks
Distributed Collection
- Telegraf instance at each site
- All instances write to central InfluxDB
- Resilient to WAN outages (local buffering)
- Suitable for: 100+ devices, multiple locations
Distributed Telegraf Configuration
# Site-specific telegraf.conf
[agent]
hostname = "telegraf-site-nyc"
[global_tags]
site = "NYC"
region = "US-East"
[[outputs.influxdb_v2]]
urls = ["https://influxdb-central.yourcompany.com:8086"]
token = "SITE_SPECIFIC_TOKEN"
organization = "NetworkMonitoring"
bucket = "mikrotik_metrics"
12.2 Tagging Strategy for Large Deployments
| Tag | Purpose | Example Values |
|---|---|---|
| site | Physical location | NYC, LAX, LHR |
| region | Geographic region | US-East, EU-West |
| role | Device function | core, distribution, access |
| environment | Network segment | production, lab, dmz |
| model | Hardware type | CCR1036, RB4011, hAP |
12.3 InfluxDB Retention and Downsampling
Create Downsampling Task
// InfluxDB Task: Downsample to 5-minute averages
option task = {name: "downsample_mikrotik", every: 5m}
from(bucket: "mikrotik_metrics")
|> range(start: -10m)
|> filter(fn: (r) => r._measurement == "interface")
|> aggregateWindow(every: 5m, fn: mean)
|> to(bucket: "mikrotik_metrics_longterm")
12.4 Performance Optimization
Polling Interval Guidelines
| Device Count | Recommended Interval | Interfaces per Device |
|---|---|---|
| 1-50 | 30 seconds | Unlimited |
| 50-200 | 60 seconds | <50 |
| 200-500 | 120 seconds | <30 |
| 500+ | 300 seconds | <20 |
Dashboard Query Optimization
- Use
|> limit(n: 1000)for table queries - Avoid
|> group()on high-cardinality tags - Use
|> aggregateWindow()for long time ranges - Set appropriate refresh intervals (30s minimum for production)
13. Troubleshooting Common Issues
13.1 No Data in Grafana
Diagnostic Checklist
- Verify SNMP connectivity from Telegraf server:
snmpwalk -v2c -c M0n1t0r1ng2024! 10.0.0.1 1.3.6.1.2.1.1.1.0 - Check Telegraf logs:
sudo journalctl -u telegraf -f --since "5 minutes ago" - Verify data in InfluxDB:
influx query 'from(bucket: "mikrotik_metrics") |> range(start: -5m) |> limit(n: 5)' - Test Grafana data source connection
- Check time synchronization:
timedatectl status
Common Causes
| Symptom | Cause | Solution |
|---|---|---|
| Telegraf timeout errors | Firewall blocking UDP 161 | Check MikroTik firewall rules |
| Authentication errors | Wrong community string | Verify SNMP community on device |
| Data in InfluxDB but not Grafana | Wrong bucket or query syntax | Check data source configuration |
| Partial data only | SNMP address restriction | Add Telegraf IP to SNMP community addresses |
13.2 Inaccurate Metrics
Counter Rollover Issues
32-bit counters roll over at 4.29 GB. Use 64-bit counters (HC = High Capacity):
# Use ifHCInOctets instead of ifInOctets
[[inputs.snmp.table.field]]
name = "ifHCInOctets"
oid = "IF-MIB::ifHCInOctets" # 64-bit counter
Interface Index Changes
MikroTik interface indexes can change after reboot. Use interface names as tags:
[[inputs.snmp.table.field]]
name = "ifName"
oid = "IF-MIB::ifName"
is_tag = true # Use as tag, not field
13.3 Performance Issues
Slow Dashboard Loading
- Reduce time range: Query last 6 hours instead of 7 days
- Add aggregation:
|> aggregateWindow(every: 5m, fn: mean) - Limit data points:
|> limit(n: 500)
High InfluxDB CPU Usage
- Reduce polling frequency
- Add downsampling tasks
- Increase server resources
- Review and optimize expensive queries
13.4 Telegraf Debug Mode
# Run Telegraf in debug mode
sudo telegraf --config /etc/telegraf/telegraf.conf --debug
# Test specific input
sudo telegraf --config /etc/telegraf/telegraf.conf --input-filter snmp --test
14. Best Practices and Recommendations
14.1 Naming Conventions
| Item | Convention | Example |
|---|---|---|
| Dashboard names | [Category] – [Scope] – [Type] | Network – MikroTik – Overview |
| Panel titles | Metric – Context | CPU Load – Per Device |
| Variable names | lowercase_underscore | device, interface_name |
| Alert names | [Severity] – [Device Type] – [Condition] | Critical – MikroTik – CPU High |
14.2 Security Hardening Checklist
- ☐ Use SNMPv3 instead of SNMPv2c
- ☐ Restrict SNMP access by IP address
- ☐ Enable HTTPS on InfluxDB and Grafana
- ☐ Use strong passwords (16+ characters)
- ☐ Create read-only API tokens for Grafana
- ☐ Enable Grafana authentication (LDAP/OAuth)
- ☐ Regularly rotate API tokens
- ☐ Implement network segmentation for monitoring traffic
- ☐ Enable audit logging
14.3 Backup Strategy
Grafana Backup
# Backup Grafana database
sudo cp /var/lib/grafana/grafana.db /backup/grafana-$(date +%Y%m%d).db
# Backup dashboards via API
for uid in $(curl -s -H "Authorization: Bearer $API_KEY" \
http://localhost:3000/api/search | jq -r '.[].uid'); do
curl -s -H "Authorization: Bearer $API_KEY" \
"http://localhost:3000/api/dashboards/uid/$uid" \
| jq '.dashboard' > "/backup/dashboards/${uid}.json"
done
InfluxDB Backup
# Full backup
influx backup /backup/influxdb-$(date +%Y%m%d) \
--org NetworkMonitoring \
--token YOUR_ADMIN_TOKEN
14.4 Documentation Requirements
- Device inventory with SNMP community strings (secured)
- Dashboard purpose and audience
- Alert escalation procedures
- Maintenance windows and procedures
- Change log for configuration updates
14.5 Regular Maintenance Tasks
| Task | Frequency |
|---|---|
| Review alert effectiveness | Weekly |
| Check disk space usage | Weekly |
| Verify backup integrity | Monthly |
| Update software versions | Monthly |
| Review and clean unused dashboards | Quarterly |
| Audit API token usage | Quarterly |
| Rotate SNMP community strings | Annually |
15. Conclusion
Summary
This guide covered the complete process of building MikroTik monitoring dashboards for your network:
- Installing and configuring InfluxDB 2.x for metric storage
- Enabling SNMP on MikroTik RouterOS with security best practices
- Deploying Telegraf to collect SNMP metrics
- Building comprehensive Grafana dashboards with Flux queries
- Configuring alerts for proactive monitoring
- Scaling the solution for enterprise deployments
Next Steps
- Start small: Monitor 1-2 devices first
- Iterate on dashboards: Add panels based on operational needs
- Expand coverage: Add more devices and metrics over time
- Automate deployment: Use Ansible or similar tools for configuration management
Advanced Topics to Explore
- Log aggregation: Add Loki for MikroTik syslog collection
- Synthetic monitoring: Use Telegraf ping/http plugins for uptime checks
- Configuration management: Automate MikroTik SNMP setup with Ansible
- Capacity planning: Build trending dashboards for growth prediction
16. Additional Resources
Official Documentation
- MikroTik SNMP Documentation
- InfluxDB 2.x Documentation
- Telegraf Documentation
- Grafana Documentation
- Flux Query Language Reference
MikroTik MIB Files
Community Resources
Check our list of MikroTik guides