A little help if possible to do some math

  • 14 June 2024
  • 4 replies

Userlevel 4
Badge +2

Sorry about the lack of punctuation in the title, I can’t edit after ;-)

So I don’t know if this is possible, but maybe someone has an idea.

The script below provides the following output:


The goal of the script is to figure out how ‘over provisioned’ we are on a switch. i.e. how many ports have never passed a packet. This is in order to size environments better for future refreshes.

So the output provides all the necessary info, but I’m not sure how to get a row to tell me “% Utililized”

This would be the total count of the ports in use (last column) divided into the the number of ports that specific switch, that show “0” across the board, and I’ll just take 1 zero and assume the rest are zeros (sometimes they are not, but this is just an estimate anyway).


Any ideas are greatly appreicated.

* @intent Branch Counters
* @description Branch Counters Interface Status show int counters on Arista & IOS-XE Switches
* 1. Check to see what switch ports have had no traffic accross the wire for sizing and planning.
* 2. Match on platform.os
* 3. Use the information from the custom command 'show int counters'.
* 4. Get port Status and number of ports on that switch
// Pattern of output
// Arista & Cisco have same pattern/columns
Traffic =
{Port:string} {InOctets:number} {InUcastPkts:number} {InMcastPkts:number} {InBcastPkts:number}
foreach device in network.devices
where "Branch" in device.tagNames && "AMRS" in device.tagNames && "Access" in device.tagNames
where device.platform.vendor == Vendor.CISCO || device.platform.os == OS.ARISTA_EOS
foreach command in device.outputs.commands
where command.commandText == "sh int counters"
let parsed = parseConfigBlocks(device.platform.os, command.response)
let matchData = blockMatches(parsed, Traffic)
foreach iface in device.interfaces
// get 1 match per interface
let x = max(foreach y in matchData
where iface.name == toLowerCase(y.data.Port)
select y)

where isPresent(x)

select {
Location: device.locationName,
name: device.name,
Vendor: device.platform.vendor,
Model: device.platform.model,
OS: device.platform.os,
Tag: device.tagNames,
Port: iface.name,
OperStatus: iface.operStatus,
Description: iface.description,
InUcastPkts: x.data.InUcastPkts,
InMcastPkts: x.data.InMcastPkts,
InBcastPkts: x.data.InBcastPkts,
InterfaceCount: length(device.interfaces),


4 replies

Userlevel 3

Here are a few queries from the Forward Library that perform math (percent calculations) as examples.




Notice that I multiply by 100 first before dividing.  At the time we only did Integer math.  There now is the ability to set a Type of Float, if you actually want decimal places.

I’ll look over your post a bit more soon.


Userlevel 3
Badge +1

There is some examples of maths also in the nqe documentation.

However, I think you may fiind it be better to consider the ports not used as a number and avoid the percentages. Percentages need to be carefully examined as it can hide the truth.

For example 50% used sounds like we have too much spare capacity, but this may only be true if we actually have a fully populated chassis with many cards installed. On a 24 port switch it sounds okay at least to me. If a switxh has only just been installed then we would expect it to be under uaed for a period of time.

If you do this as a percentage then you may want to first group similar devices. Those that are for the same site, environment or what ever makes sense for your team. As the percentage is then across mutiple device then i think iy may sit better in any reports.

You may also want to flag what the port is used for, such as networking, servers, users, printers and so. Perhaps the descriptions on interfaces can help or whether the port is enabled may be important. If i recall i think NQE exposes earned hosts as well which may be incorporated into your reporting.

For example saying we have 4000 ports for servers available and 2000 are in use for location X gives us 50% utilised is probably more useful for planning.

This isn't to say that having the specifics for each device isn't needed as well.

To group devices you would need some method such as tagNames, naming convention, etc  to grab the collate the data for related devices.

Userlevel 4

@cariddir  This is purposely verbose so you can see the logic. I have two functions which test for any 0 counters or all 0 counters


test =
Router# show interfaces counters
Port InOctets InUcastPkts InMcastPkts InBcastPkts InDiscards
Fa0/0 1234567890 123456 123456 12345 0
Fa0/1 9876543210 654321 654321 54321 0
Fa0/2 0 0 654321 54321 0
Fa0/3 9876543210 654321 654321 0 0
Fa0/4 9876543210 654321 0 54321 0
Fa0/5 0 0 0 0 0

pattern =
{Port:string} {InOctets:number} {InUcastPkts:number} {InMcastPkts:number} {InBcastPkts:number}

countInactiveAnyZero(interfaces) =
foreach interface in interfaces
where 0 in interface.counters
select interface;

countInactiveAllZero(interfaces) =
foreach interface in interfaces
where sum(interface.counters) == 0
select interface;

foreach x in [0]
let blocks = parseConfigBlocks(OS.UNKNOWN, test)
let matches = blockMatches(blocks, pattern)
let fixCounters = (foreach match in matches
select {
port: match.data.Port,
counters: [match.data.InOctets,
let zeroInterfaces = countInactiveAllZero(fixCounters)
where isPresent(zeroInterfaces)
let activePorts = float(length(matches) - length(zeroInterfaces))
let totalPorts = float(length(matches))
let percentage = activePorts / totalPorts
select {
zeroInterfaces, totalPorts, activePorts, percentage: percentage * float(100)


Userlevel 4
Badge +2


Thank you very much. 

 Going to work with this today.  I’ll let you know how it works out!

Again, much appreciated.