Zabbix – how to monitor clients on Mikrotik Capsman

Hello, I want to share my solution for monitoring connected clients to CapMan interfaces on Mikrotik in the Zabbix monitoring system.

First, for the Zabbix server part, to get data from Mikrotik Capsman we will use the Python script to communicate with Mikrotik API. The Zabbix server needs access to the Mikrotik API, so if you have any problem first check your firewall on Mikrotik and also if you have enabled API service (/IP/Services).

Zabbix server part

Place the Python script on your Zabbix server, I use path /home/zabbix/zabbix_capsman_interfaces_no_macro.py

from routeros_api import RouterOsApiPool, exceptions
import sys
import json

# Replace these with your router's details

def get_capsman_client_count(host,username,password):
    try:
        api_pool = RouterOsApiPool(host, username=username, password=password, port=8728,plaintext_login=True)
        api = api_pool.get_api()

        # Access the /caps-man/registration-table and run the count-only command
        interface = api.get_resource('/caps-man/registration-table')
        interfaces = interface.get()      

        interface_counts = {}
        
        for registration in interfaces:
            if registration["interface"] in interface_counts:
                interface_counts[registration["interface"]] += 1
            else:
                interface_counts[registration["interface"]] = 1

        output = []
        for interface,noc in interface_counts.items():
            output.append({"CAP":interface,"NOC":noc})
        #print(output)
        print(json.dumps(output))
        api_pool.disconnect()    
    except exceptions.RouterOsApiConnectionError:
        print("Failed to connect to the MikroTik router.")
        return None
    except exceptions.RouterOsApiError as e:
        print(f"An error occurred: {e}")
        return None

if __name__ == '__main__':
    n = len(sys.argv)
    if(n != 4):
        print("zabbix_capsman_interfaces.py host,username,password")
        quit()
    
    host = sys.argv[1]
    username = sys.argv[2]
    password = sys.argv[3]
    get_capsman_client_count(host,username,password)

You need the router_api Python library. The easiest way to install it is via python pip.

pip install routeros_api

Also, it is necessary to edit the /etc/zabbix/zabbix_agent2.conf on the server where the script runs to allow the run of this script.

AllowKey=system.run[*zabbix_capsman_interfaces*]

This rule allows to run the script that contains the zabbix_capsman_interfaces in name. You can make the rule more strict, see the Zabbix config file documentation.

The Zabbix part

Create a host under the Data collection -> Hosts

  • Host name: by your choice
  • Host group: by your choice
  • Interface: Agent -> IP is the IP of the server that calls the script and where you upload the script

Next, create the Macros under Macros tab:

  • {$CAPS_HOST}: IP of Mikrotik with Capsman -> type Text
  • {$CAPS_PASS}: password for mikrotik -> use the secret text
  • {$CAPS_USER}: user for mikrotik

Then save the Host, edit the Host item and manually create the new Item in the host.

  • Name: by your choice (capsman.discovery)
  • Type: Zabbix agent
  • Key: system.run[python3 /home/zabbix/zabbix_capsman_interfaces_no_macro.py {$CAPS_HOST} {$CAPS_USER} {$CAPS_PASS}]
  • Type information: Text
  • Update interval: 1m (it depends on how often you want to get information about capsman)

The next step is to prepare the discovery rules, so select the Discovery rules and create the discovery rule.

  • Name: by your choice (Cap interface discovery)
  • Type: Dependent item
  • Key: capsman.discovery
  • Type information: Text
  • Master item: is the created item (capsman.data)

    Next setup the LLD macros for this discovery rule, in the tab LLD macros create this macros:

LLD macroJSONPath
{#INT}$.CAP
{#NOC}$.NOC

Then save the discovery interface.

The next step is to create an item prototype under the newly created. So create item prototype.

  • Name: Cap {#INT}
  • Type: Dependent item
  • Key: capsman.discovery[{#INT}]
  • Type information: numeric (unsigned)
  • Master item: is the created item (capsman.data)

In the Preprocessing tab add a new step.

  • Type: JSONPath
  • Parameters: $..[?(@.CAP=='{#INT}’)].NOC.first()
  • Custom on fail: Set value to 0

Then you can save the item prototype. Now you have all prepared, after some time Zabbix should create an Item for every Capsman interface on Capsman, the value of the item is the number of currently connected clients. The next step is to create some fancy graphs and visualise data. It only depends on your needs.