🔌 Script to periodically check link-speed of Ethernet ports

A rather common issue is negotiated Ethernet link-speeds dropping due to cable issues, bad electrical connections etc. (a very common case is link-speeds dropping to 100 Mbps).
Often such network degradation take a lot of time to be noticed (especially if no packet loss is observed, especially on less-utilized links).
Here is a simple script that checks link-speed of Ethernet/SFP interfaces against a predefined list and sends e-mail about any interfaces not matching the listed link-speeds.

:local ifspeeds {"ether1"="1Gbps-full";"ether2"="1Gbps-full";"ether5"={"1Gbps-full";"no-link"}}
:local recipient "recipient@example.test"
:local recipientscc ""
:local routername "$[/system identity get name]"

:local eb ""
:foreach interf,speeds in=$ifspeeds do={
  :local status
  :local speed
  :onerror e in={
    :set status [/interface/ethernet/monitor $interf proplist=status,rate,full-duplex once as-value]
    :set speed ($status->"status")
  } do={ :set speed "interface-error" }
  :if ($speed = "link-ok") do={
    :if ($status->"full-duplex") do={
      :set speed (($status->"rate")."-full")
    } else={
      :set speed (($status->"rate")."-half")
    }
  }
  :if ($speed != $speeds && !($speed in $speeds)) do={
    :set eb ($eb."Interface ".$interf." has incorrect speed: ".$speed."\r\n")
    /log/error "Incorrect interface speed $speed for $interf"
  }
}
:if ($eb != "") do={
  /tool e-mail send to="$recipient" cc="$recipientscc" subject="Incorrect interface speed(s) on $routername" body="$eb"
} else={
  /log/info "All checked interface speeds are OK"
}

The script needs read and test permissions (policy), email enabled in device mode, and e-mail sending configured.
Likely this script needs RouterOS 7.24.2 or newer.

As seen in the example ifspeeds is an array with interface names as keys and link-speeds as values. Each value can either be a string (if only a single speed is allowed) or an array of strings (if multiple speeds are allowed).

To install the script in /system/script (with name check-interface-speeds) and schedule it to run twice a day (e.g. at 07:05 - 07:15 and at 19:05 - 19:15) commands like these can be used:

/system/script/add name=check-interface-speeds policy=read,test
/system/script/edit check-interface-speeds source
/system/scheduler/add interval=12h name=check-interface-speeds on-event=":delay [:rndnum from=0 to=599]\n/system script run check-interface-speeds" policy=read,test start-date=2026-01-01 start-time=07:05:00

Comments, suggestions and questions are welcome!

Something to check: I think a script gets terminated if it exceeds 120 seconds...

I do not think this is the case (at least not on current RouterOS versions).
I have tested this script and the scheduler part has waited for more than 5 minutes on RouterOS 7.24.2.
Can you reproduce this behavior?

.....

@rextended Please red my previous message in full! I have tested and not observed the behavior you mentioned. If you can reproduce it, please share a reproduction scenario!

Is it annoying to take just a part of the sentence? That’s what you did in your reply.

@rextended Edited my answer to include your full message.
Can you share a reproduction scenario or not (i.e. can you please check, because I was not able to reproduce the thing you were concerned about)?

Quoting myself here: just because I’m checking and thinking about it doesn’t mean that’s exactly how things are.
There used to be a limit in older versions of RouterOS,
if they’ve removed it.. well, maybe that’s for the best, or maybe not...
but we’d need to verify when that change was made.