4.3. How to override the defaults

4.3.1. Example 1: making NetSpyGlass monitor specific interfaces that are not monitored by default

Suppose you want to change just one or two attributes of particular monitoring variable, while leaving the rest the defaults. For example, suppose we just want to make NetSpyGlass monitor Juniper “ms” interfaces in addition to the standard set of variables. The problem with “ms” interfaces is that our network discovery does not think they are connected anywhere but the default monitoring variable builder only monitors interfaces that are connected. So we need to override the logic that selects interfaces for monitoring but don’t need to change anything about the variables it produces.

First, create a “runner” script where you define a class based on our default class VariableBuilder and save this script under the name var_builder.py in NetSpyGlass home directory:

# File var_builder.py

from net.happygears.nw2.py.py_wrappers import PyDevice
from net.happygears.nw2.py.py_wrappers import PyNetworkInterface
from variable_builders import *
from variable_builders.variable_builder_runner import VariableBuilder


class ModifiedInterfaceVarBuilder(InterfaceVariableBuilder):
    """
    This class overrides checks implemented in InterfaceVariableBuilder to make
    NetSpyGlass try to monitor interfaces "ms" in addition to the ones picked
    by the base class InterfaceVariableBuilder.

    You can find copy of the source code of InterfaceVariableBuilder in
    python/variable_builders/interface.py
    """

    def basic_interface_match(self, intf):
        """
        This function overrides the "core" check in the base class. It is used
        to decide if we want to monitor this interface

        :type intf: PyNetworkInterface
        :param intf: PyNetworkInterface wrapper object
        :return: True if we want to monitor this interface
        """
        return 'ms-' in intf.name or super(ModifiedInterfaceVarBuilder, self).basic_interface_match(intf)

class ModifiedVariableBuilder(VariableBuilder):
    """
    This class is based on the standard VariableBuilder class but substitutes
    class used to build interface-related variables.

    :param log: Java logger object. You can call it using self.log.info("log message")
    """

    def __init__(self, log):
        super(ModifiedVariableBuilder, self).__init__(log)
        # Override these builder objects with our new classes
        self.interface = ModifiedInterfaceVarBuilder(log)

This script defines modified interface variable builder class ModifiedInterfaceVarBuilder that mostly defers to the base class except it overrides function basic_interface_match() that also checks if interface name matches simple pattern “ms-“.

4.3.2. Example 2: making NetSpyGlass poll packet rate counter OIDs for network interfaces

By default, NetSpyGlass polls the following OIDs for each network interface:

  • ifAlias this is a string variable, its value is equal to the interface description
  • ifspeed interface speed
  • ifHCInOctets The total number of octets received on the interface, including framing characters. NetSpyGlass uses this information to compute inbound traffic rate through the interface (variable ifInRate)
  • ifHCOutOctets The total number of octets transmitted out of the interface, including framing characters. This information is used to compute outbound traffic rate through the interface (variable ifOutRate)
  • ifInErrors The number of inbound packets that contained errors preventing them from being deliverable to a higher-layer protocol. Variable ifInErrorRate is computed as rate(ifInErrors)
  • ifOutErrors The number of outbound packets that could not be transmitted because of errors. Variable ifOutErrorRate is computed as rate(ifOutErrors)
  • ifInDiscards The number of inbound packets which were chosen to be discarded even though no errors had been detected to prevent their being deliverable to a higher-layer protocol. Variable ifInDiscardRate is computed as rate(ifInDiscards)
  • ifOutDiscards The number of outbound packets which were chosen to be discarded even though no errors had been detected to prevent their being transmitted. Variable ifOutDiscardRate is computed as rate(ifOutDiscards)
  • ifOperStatus The current operational state of the interface.

Some users want to track various packet rates in addition to these. Standard IF-MIB supported by most devices offers a number of OIDs that monitor the following packet rates:

  • ifHCInUcastPkts The number of packets, delivered by this sub-layer to a higher (sub-)layer, which were not addressed to a multicast or broadcast address at this sub-layer.
  • ifHCInMulticastPkts The number of packets, delivered by this sub-layer to a higher (sub-)layer, which were addressed to a multicast address at this sub-layer. For a MAC layer protocol, this includes both Group and Functional addresses.
  • ifHCInBroadcastPkts The number of packets, delivered by this sub-layer to a higher (sub-)layer, which were addressed to a broadcast address at this sub-layer.

(there are also corresponding outbound packet counters).

NetSpyGlass does not poll packet counter OIDs by default, but it is easy to turn this on by just setting one boolean variable in the Interface variable builder class. As in the previous example, save the following script in the file var_builder.py in NetSpyGlass home directory:

# File var_builder.py

from variable_builders import *
from variable_builders.variable_builder_runner import VariableBuilder


class ModifiedVariableBuilder(VariableBuilder):
    """
    This class is based on the standard VariableBuilder class. It just sets
    the flag `make_interface_packet_counter_vars` in the interface variable
    builder class instance to `True`.

    :param log: Java logger object. You can call it using self.log.info("log message")
    """

    def __init__(self, log):
        super(ModifiedVariableBuilder, self).__init__(log)
        self.interface.make_interface_packet_counter_vars = True

4.3.3. Example 3: making NetSpyGlass monitor duplex/half-duplex mode of network interfaces

By default, NetSpyGlass does not poll OIDs that can be used to determine if the interface runs in duplex or half-duplex mode, however you can turn this on by setting just one variable in the Python hook script as shown below.

As in the previous example, save the following script in the file var_builder.py in NetSpyGlass home directory:

# File var_builder.py

from variable_builders import *
from variable_builders.variable_builder_runner import VariableBuilder


class ModifiedVariableBuilder(VariableBuilder):
    """
    This class is based on the standard VariableBuilder class. It just sets
    the flag `make_interface_duplex_status_vars` in the interface variable
    builder class instance to `True`.

    :param log: Java logger object. You can call it using self.log.info("log message")
    """

    def __init__(self, log):
        super(ModifiedVariableBuilder, self).__init__(log)
        self.interface.make_interface_duplex_status_vars = True

Information about interface duplex/half-duplex mode ends up in the monitoring variable with the name ifDuplexStatus in category Interfaces.

Note

NetSpyGlass tries to use EtherLike-MIB to monitor interface’s duplex mode. For the devices from vendors that do not support this MIB, NetSpyGlass uses their proprietary enterprise MIBs to collect similar data. Since these enterprise MIBs return information in a different format, standard data processing script nw2rules.py transforms it to the common format that follows dot3StatsDuplexStatus: unknown(1), halfDuplex(2), fullDuplex(3). Currently NetSpyGlass can use enterprise MIBs to monitor duplex mode of interfaces for the devices made by F5, A10 and Viptela. Devices made by Cisco, Juniper, HP, Dell/F10, as well as software from Cumulus Networks, support EtherLike-MIB.

4.3.4. Example 4: making NetSpyGlass monitor network interface upstream & downstream bandwidths for Viptela devices

By default, NetSpyGlass polls the following OID for each network interface:

  • ifspeed interface speed

Some users want to track separate speeds for interface upstream/downstream supported by Viptela devices

  • interfaceBandwidthUpstream interface Upstream speed
  • interfaceBandwidthDownstream interface Downstream speed

NetSpyGlass does not poll these OIDs by default, but it is easy to turn this on by setting just one variable in the Python hook script as shown below.. As in the previous example, save the following script in the file var_builder.py in NetSpyGlass home directory:

# File var_builder.py

from variable_builders import InterfaceVariableBuilder
from net.happygears.nw2.py.py_wrappers import PyDevice
from net.happygears.nw2.py.py_wrappers import PyNetworkInterface
from variable_builders.variable_builder_runner import VariableBuilder


class ModifiedInterfaceVarBuilder(InterfaceVariableBuilder):
    """
    This class is based on the standard VariableBuilder class. It just sets
    the flag `make_interface_duplex_status_vars` in the interface variable
    builder class instance to `True`.

    :param log: Java logger object. You can call it using self.log.info("log message")
    """

    def __init__(self, log):
        super(ModifiedVariableBuilder, self).__init__(log)

    def make_variables(self, device, intf):
      """
      Given device and network interface objects, build set of monitoring variables
      for the interface

      :type device: PyDevice
      :param device:   network device object
      :type intf: PyNetworkInterface
      :param intf:     network interface object
      :return: a dictionary where the key is variable name and value is another dictionary
      """
      assert isinstance(device, PyDevice)
      assert isinstance(intf, PyNetworkInterface)

      mvars = {}

      mvars.update(self.make_viptela_in_out_bandwidth_vars(device, intf, intf.if_index))

      return mvars

    def make_viptela_in_out_bandwidth_vars(self, device, intf, if_index):
      """
      Make monitoring variables for the interface given its ifIndex.
      :param device: PyDevice wrapper object
      :type intf: PyNetworkInterface
      :param intf: PyNetworkInterface wrapper object
      :param if_index:  ifIndex value
      :return: a dictionary where the key is variable name and value is another dictionary
      """
      mvars_bandwidth = {}

      interfaceVpnId = 0.5
      if_index = 0  # Always 0

      intf_decimal_repr = self.interface_stringToDecimal(intf)

      if 'Vendor.Viptela' in device.tags:
          mvars_bandwidth['ifInBandwidth'] = {
              'component': intf,
              'snmp_oid': 'VIPTELA-OPER-VPN:interfaceBandwidthDownstream.{0}.{1}.{2}'.format(interfaceVpnId,
                                                                                            intf_decimal_repr,
                                                                                            if_index)
          }

          mvars_bandwidth['ifOutBandwidth'] = {
              'component': intf,
              'snmp_oid': 'VIPTELA-OPER-VPN:interfaceBandwidthUpstream.{0}.{1}.{2}'.format(interfaceVpnId,
                                                                                          intf_decimal_repr,
                                                                                          if_index)
          }

      return mvars_bandwidth

    def interface_stringToDecimal(self, intf):
        itfNameList = []
        for intf_char in intf.name:
            new_intf_char = hex(ord(intf_char))
            res = int(new_intf_char, base=16)
            itfNameList.append(str(res))

        # JOINING LIST
        intf_decimal_repr = '.'.join(itfNameList)
        return intf_decimal_repr


class ModifiedVariableBuilder(VariableBuilder):
    """
    This class is based on the standard VariableBuilder class but substitutes
    class used to build interface-related variables.

    :param log: Java logger object. You can call it using self.log.info("log message")
    """

    def __init__(self, log):
        super(ModifiedVariableBuilder, self).__init__(log)
        # Override these builder objects with our new classes
        self.interface = ModifiedInterfaceVarBuilder(log)