Picture of NOC
|

MikroTik Dashboard Creation with InfluxDB and Grafana: Complete Setup Guide

Network blind spots cost enterprises thousands of dollars per hour during outages. MikroTik routers and switches power critical infrastructure worldwide. Yet many organizations lack visibility into their MikroTik device performance.

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

  1. Open browser: http://YOUR_SERVER_IP:8086
  2. Click “Get Started”
  3. Enter username: admin
  4. Enter password: YourSecurePassword123!
  5. Enter organization: NetworkMonitoring
  6. Enter bucket name: mikrotik_metrics
  7. Set retention: 90 days
  8. 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

  1. Open browser: http://YOUR_SERVER_IP:3000
  2. Login with default credentials:
    • Username: admin
    • Password: admin
  3. Set new admin password when prompted

7.3 Connecting Grafana to InfluxDB

Add InfluxDB Data Source

  1. Navigate to: Configuration → Data Sources
  2. Click “Add data source”
  3. Select “InfluxDB”
  4. 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
  1. Click “Save & Test”
  2. 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

  1. Create new dashboard: Dashboards → New Dashboard
  2. Click gear icon → Variables → Add variable
  3. 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:

  1. Dashboard Settings → Links
  2. 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

  1. Dashboard Settings → Annotations
  2. 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

  1. Navigate to: Alerting → Alert rules → New alert rule
  2. 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

  1. Navigate to: Alerting → Contact points → New contact point
  2. Select: Slack
  3. 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

  1. Navigate to: Dashboards → Import
  2. Enter Dashboard ID (e.g., 14420)
  3. Click “Load”
  4. Select your InfluxDB data source
  5. 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

  1. Verify SNMP connectivity from Telegraf server:
    snmpwalk -v2c -c M0n1t0r1ng2024! 10.0.0.1 1.3.6.1.2.1.1.1.0
  2. Check Telegraf logs:
    sudo journalctl -u telegraf -f --since "5 minutes ago"
  3. Verify data in InfluxDB:
    influx query 'from(bucket: "mikrotik_metrics") |> range(start: -5m) |> limit(n: 5)'
  4. Test Grafana data source connection
  5. 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

  1. Start small: Monitor 1-2 devices first
  2. Iterate on dashboards: Add panels based on operational needs
  3. Expand coverage: Add more devices and metrics over time
  4. 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 MIB Files

Community Resources


Check our list of MikroTik guides

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *