Community discussions

MikroTik App
 
cmassey
just joined
Topic Author
Posts: 20
Joined: Fri Nov 08, 2019 8:06 am

Using [find] with the API

Mon Aug 07, 2023 11:58 pm

I am trying to use the API to get the speed of the ethernet interfaces. I am running the monitor command once for each interface because I don't think there's an easier way (easier being less requests). When I try to use find to get ether1, I get this:

'Error "no such item" executing command b\'/interface/ethernet/monitor =numbers=[find where name="ether1"] .tag=3\'', b'no such item'

If I just put in 0 instead of using the find function then that works, but I'd rather ask for the interface I care about. Otherwise I need to run interface/print first to get the interface numbers.

Also, is there a better way to get the interface speed? This would be 48 separate requests for a 48 port switch.
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 12597
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Using [find] with the API

Tue Aug 08, 2023 11:52 am

this
/interface/ethernet/monitor =numbers=[find where name="ether1"] .tag=3
is equivalent to
/interface/ethernet/monitor =numbers=[/interface/ethernet/monitor/find where name="ether1"] .tag=3

and /interface/ethernet/monitor/find etc. do not exist

"probably" must be
/interface/ethernet/monitor =numbers=[/interface/ethernet find where name="ether1"] .tag=3
 
pe1chl
Forum Guru
Forum Guru
Posts: 10534
Joined: Mon Jun 08, 2015 12:09 pm

Re: Using [find] with the API

Tue Aug 08, 2023 11:59 am

Also, is there a better way to get the interface speed? This would be 48 separate requests for a 48 port switch.
A fast way is to use:
snmpbulkwalk -v2c -c public 192.168.88.1 interfaces.ifTable.ifEntry.ifSpeed
 
User avatar
BrianHiggins
Forum Veteran
Forum Veteran
Posts: 720
Joined: Mon Jan 16, 2006 6:07 am
Location: Norwalk, CT
Contact:

Re: Using [find] with the API

Tue Aug 08, 2023 6:13 pm

If you mean get the current utilization speed you need to use the following:
/interface/monitor-traffic
=once=
=interface=ether1
=.proplist=rx-bits-per-second,tx-bits-per-second,name
I'm unaware of any other method that works via the API to get current utilization rate, and it only retrieves one interface per call.

If you want to get current link data such as ethernet link speed, duplex and similar:
/interface/ethernet/print
=.proplist=.id,name,auto-negotiation,advertise,full-duplex,speed,comment

Obviously you can tweak the proplist to suit your needs, Here's my example of interface settings getting displayed after being read through the API
interface settings.png
You do not have the required permissions to view the files attached to this post.
 
cmassey
just joined
Topic Author
Posts: 20
Joined: Fri Nov 08, 2019 8:06 am

Re: Using [find] with the API

Tue Aug 08, 2023 9:45 pm

Also, is there a better way to get the interface speed? This would be 48 separate requests for a 48 port switch.
A fast way is to use:
snmpbulkwalk -v2c -c public 192.168.88.1 interfaces.ifTable.ifEntry.ifSpeed
Thank you for this. It looks like I can run ifDescr to find out which interface I'm looking at and then I can make sense of ifSpeed. Do you know if I should check to make sure that ifDescr.3 is always ether1, for example, or should that always stay the same after I figure out what it is for that router?


If you mean get the current utilization speed you need to use the following:
/interface/monitor-traffic
=once=
=interface=ether1
=.proplist=rx-bits-per-second,tx-bits-per-second,name
I'm unaware of any other method that works via the API to get current utilization rate, and it only retrieves one interface per call.

If you want to get current link data such as ethernet link speed, duplex and similar:
/interface/ethernet/print
=.proplist=.id,name,auto-negotiation,advertise,full-duplex,speed,comment

Obviously you can tweak the proplist to suit your needs, Here's my example of interface settings getting displayed after being read through the API
interface settings.png
I mean the interface speed and not the rate. I do need the rate also but I am getting that in the way you mentioned already. 1 interface at a time unfortunately. If I was really cool I'd probably print the traffic that's gone through the interface, get it again a couple seconds later, and then do math or something like that. I'd have to be sure the time was correct though.

/interface/ethernet/print does not give speed for me. It looks like it did back in ROS6 but not in ROS7.

On a slightly related note, I'm assuming you're using proplist because it helps performance in some way? I've just been getting all the results back and then getting the information I need.
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 4398
Joined: Sun May 01, 2016 7:12 pm
Location: California
Contact:

Re: Using [find] with the API  [SOLVED]

Tue Aug 08, 2023 10:08 pm

Hold on here. Using the API, there is no "find" anywhere (at least since 2009)... See viewtopic.php?t=29173

With API... I think the idea is each interface monitor using a different =tag=, and the stream of tags is processed into your own data struct from the !re based on tags provided back from router.

Why SNMP seems like a better way if at all possible...
A fast way is to use:
snmpbulkwalk -v2c -c public 192.168.88.1 interfaces.ifTable.ifEntry.ifSpeed
Thank you for this. It looks like I can run ifDescr to find out which interface I'm looking at and then I can make sense of ifSpeed. Do you know if I should check to make sure that ifDescr.3 is always ether1, for example, or should that always stay the same after I figure out what it is for that router?

The OID does not change unless the the interface is removed and re-added. So for ether1...X, they won't change. At least on the same router... Between routers, however, it would be possible the OID for ether1 is not same as another, or especially SFP ports – since the OID depends on the order added. But once added, the OID is stable for a router.
 
cmassey
just joined
Topic Author
Posts: 20
Joined: Fri Nov 08, 2019 8:06 am

Re: Using [find] with the API

Tue Aug 08, 2023 10:24 pm

Hold on here. Using the API, there is no "find" anywhere (at least since 2009)... See viewtopic.php?t=29173
Ah, I could see "find" not existing for the API making find not work. Thank you. I originally wrote an application that used SSH for everything so I'm in the process of rewriting it using the API.

I'll just use snmp for this. I'll run ifDescr.3 to map interfaces to the correct numbers once per router and then just get the speed after that. It's unfortunate that it looks like /interface/ethernet/print use to work for this.

I plan on using the API and SNMP for everything I need from the routers depending on what responds faster and what takes less resources.
 
pe1chl
Forum Guru
Forum Guru
Posts: 10534
Joined: Mon Jun 08, 2015 12:09 pm

Re: Using [find] with the API

Tue Aug 08, 2023 11:22 pm



A fast way is to use:
snmpbulkwalk -v2c -c public 192.168.88.1 interfaces.ifTable.ifEntry.ifSpeed
Thank you for this. It looks like I can run ifDescr to find out which interface I'm looking at and then I can make sense of ifSpeed. Do you know if I should check to make sure that ifDescr.3 is always ether1, for example, or should that always stay the same after I figure out what it is for that router?
Well yes, that is unfortunately always an issue with SNMP...
"in practice" the ifDescr table will remain the same in RouterOS until you re-install (even when you load the same config afterwards it can be different). Usually for fixed interfaces like the ports of a switch, the numbering will remain the same. But when you have added more dynamic interfaces like a PPPoE or some tunnel, it will change.
In some other devices the table can change even after a reboot (with same version and config), but in RouterOS I have never seen that happen.

Depending on your programming environment and -experience, you can decide if you want to query ifDescr every time you want to query ifSpeed (and then build some mapping table from ifDescr to number which you use when interpreting ifSpeed), or if you trust that for the 48 switchports it will remain the same.
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 4398
Joined: Sun May 01, 2016 7:12 pm
Location: California
Contact:

Re: Using [find] with the API

Tue Aug 08, 2023 11:30 pm

I plan on using the API and SNMP for everything I need from the routers depending on what responds faster and what takes less resources.
If you end up testing both API and SNMP to get the interface speed data, be curious at which was faster myself... Hard to know actually...
 
cmassey
just joined
Topic Author
Posts: 20
Joined: Fri Nov 08, 2019 8:06 am

Re: Using [find] with the API

Tue Aug 08, 2023 11:45 pm

I'm working on a project that configures home routers (at least at first) and makes it so the support staff can change wireless settings, port forwarding, dhcp reservations, etc from a dashboard. The idea is that no one has to really know all the details of Mikrotik configuration because the program takes care of that for them. It will also give information and alert to possible problems (why I'm getting interface speed and rate and such).

I say all of that to say I'll be querying thousands of devices at a time and testing out different polling intervals/api vs snmp, etc. If I can avoid asking for ifDescr as much then that should help with the scalability (just a tiny bit but whatever). I'll plan on just doing it for each router once it's on-boarded and then test from there.

I should be able to get a good amount a data to let you know what performs better and responds faster. For interface speed specifically though, it looks like the only way to do it with 1 command is SNMP so I'll be using that.
 
User avatar
BrianHiggins
Forum Veteran
Forum Veteran
Posts: 720
Joined: Mon Jan 16, 2006 6:07 am
Location: Norwalk, CT
Contact:

Re: Using [find] with the API

Wed Aug 09, 2023 1:06 am


/interface/ethernet/print does not give speed for me. It looks like it did back in ROS6 but not in ROS7.

On a slightly related note, I'm assuming you're using proplist because it helps performance in some way? I've just been getting all the results back and then getting the information I need.

The screenshot I posted of my implementation using that data is a 7.10.2 router, and it does show speed, but only when the interface has auto-negotiation disabled. /interface/ethernet/monitor does give the current rate.
/interface/ethernet/monitor
=numbers=ether1,ether2
=once=

Output:

!re=name=ether1=status=link-ok=auto-negotiation=done=rate=1Gbps=full-duplex=true=tx-flow-control=false=rx-flow-control=false=advertising=10M-half,10M-full,100M-half,100M-full,1000M-half,1000M-full=link-partner-advertising=10M-half,10M-full,100M-half,100M-full,1000M-full
!re=name=ether2=status=no-link=auto-negotiation=done=advertising=10M-half,10M-full,100M-half,100M-full,1000M-half,1000M-full=link-partner-advertising=
!done
As for using the proplist, It definitely makes a difference on the router CPU vs when you are returning really large results, but also to a lessor degree on the bandwidth used and the time the API call takes to complete. For a small result set there's not much benefit, but I'm in the habit of doing it almost all the time now and I find it's also just easier to deal with when you're only retrieving the data you need, particularly if you've got to troubleshoot something and debug the results manually.