Switch Port Activity

  • 4 April 2024
  • 2 replies
  • 74 views

Userlevel 3
Badge +2

This is a script to pull switch port stats from our access switches in our network. The data pulled in this script is used for ‘right sizing’ and network planning. 

We can then export the results, and pivot table them to see the % of switch ports in use/not-in use. I’ll add this attachment later.

/**
* @intent Show int counters on Arista & IOS-XE Switches
* @description
* 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 counts of switch ports on that device so we can use to calculate % in use
**/

// Pattern of output
// Arista & Cisco Same Columns
Traffic =
```
{Port:string} {InOctets:number} {InUcastPkts:number} {InMcastPkts:number} {InBcastPkts:number}
```;
// Arista Function
EOS_Stats =
foreach device in network.devices
where device.platform.os == OS.ARISTA_EOS
foreach command in device.outputs.commands
where command.commandText == "sh int counters"
let parsed = parseConfigBlocks(OS.ARISTA_EOS, 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 {
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,
InOctets: x.data.InOctets,
InUcastPkts: x.data.InUcastPkts,
InMcastPkts: x.data.InMcastPkts,
InBcastPkts: x.data.InBcastPkts,
InterfaceCount: length(device.interfaces),
};
// Cisco Function
Cisco_Stats =
foreach device in network.devices
where device.platform.vendor == Vendor.CISCO
foreach command in device.outputs.commands
where command.commandText == "sh int counters"
let parsed = parseConfigBlocks(OS.IOS_XE, 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 {
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,
InOctets: x.data.InOctets,
InUcastPkts: x.data.InUcastPkts,
InMcastPkts: x.data.InMcastPkts,
InBcastPkts: x.data.InBcastPkts,
InterfaceCount: length(device.interfaces),
};
// Combine Functions
ifaceStats = EOS_Stats + Cisco_Stats;

foreach result in ifaceStats
select {
Hostname: result.name,
Vendor: result.Vendor,
Model: result.Model,
OS: result.OS,
Tag: result.Tag,
OperStatus: result.OperStatus,
Desc: result.Description,
Port: result.Port,
InUcastPkts: result.InUcastPkts,
InMcastPkts: result.InMcastPkts,
InBcastPkts: result.InBcastPkts,
InterfaceCount: result.InterfaceCount
}

 


2 replies

Userlevel 3

Thanks for sharing! This is super helpful! If I may offer a suggestion, because the custom command and output are the same, for the sake of a shorter query - combining the where statement to filter the vendor/os with an “or” and using “device.platform.os” in the parsed output. 

/**
* @intent Show int counters on Arista & IOS-XE Switches
* @description
* 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 counts of switch ports on that device so we can use to calculate % in use
**/

// Pattern of output
// Arista & Cisco Same Columns
Traffic =
```
{Port:string} {InOctets:number} {InUcastPkts:number} {InMcastPkts:number} {InBcastPkts:number}
```;
foreach device in network.devices
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 {
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,
InOctets: x.data.InOctets,
InUcastPkts: x.data.InUcastPkts,
InMcastPkts: x.data.InMcastPkts,
InBcastPkts: x.data.InBcastPkts,
InterfaceCount: length(device.interfaces),
}

 

Userlevel 3
Badge +2

Thanks Arica !

That is much more concise and clear.

I originally wrote it between two other platforms, and the outputs were not the same, but then just replaced the other platform with the ‘Arista’ function b/c it seemed quick and probably I was lazy.

But definitely will modify for the production queries, and save the original in my chaotic personal folder.

 

Thank you again.
Rich

Reply