14. Java classes that can be accessed from Python scripts¶
14.1. Summary¶
Java classes that can be accessed from Python scripts that build monitoring variables, process monitoring data or build reports.
Even though these are Java classes, they have method __getattr__() that provides standard “Pythonic” way to access their properties as class attributes. That is, you can call both Java “getter” method:
device.getName()
and access the same property as an attribute:
device.name
We also provide method get() that works exactly like __getattr__() and is intended for Velocity templates used to build reports. This means you can write:
$device.name
in the report template instead of:
$device.getName()
both methods will work though.
Since these wrapper classes are intended to be used with Python scripts, some attributes were
given alternative names to conform with PEP8. For example, attribute PyDevice.sys_name
is mapped to the Java getter method PyDevice.getSytsName()
. This document lists
only attribute names.
14.2. Classes and Functions¶
14.2.1. MonitoringVariable¶
-
class
net.happygears.nw2.py.
MonitoringVariable
¶ This class represents single instance of a monitoring variable. An object of this class holds information about one interface, hardware component, a protocol counter or any other entity that we monitor.
14.2.1.1. Attributes¶
device
¶The name of the device this variable instance collects monitoring data for
component
¶The name if the interface or hardware component this variable collects monitoring data for.
iface
¶This attribute returns the same value as MonitoringVariable.component. This attribute is deprecated and will be removed in future versions, please use MonitoringVariable.component instead.
ds
¶Reference to an instance of class
DataSource
(see below)
statistics
¶
net.happygears.nw2.py.Statistics
object (see below)
timeseries
¶
net.happygears.nw2.time_series_buffer.TimeSeries
object (see below)
tags
Tags: unmodifiable set of strings, each string is in the form “TagFacet.TagWord” Use this attribute to check if the variable has a tag using Python in operator:
1 2 if 'Vendor.Cisco' in mvar.tags: # do something if this is Cisco deviceTo add new tag to the variable use method addTag()
14.2.1.2. Instance Methods¶
Not all methods of the Java class MonitoringVariable are accessible from Python. Here are few that can be useful:
addTag
(tag_string)¶Add tag to the variable. Tag should be in the form of a two-component string, speparated with a dot: Facet.Word. Examples:
1 2 3 Vendor.Cisco ColorLevel.1 ifOperStatus.UpFor example:
mvar.addTag('Aggregate.PaidPeering')
removeTag
(tag_string)¶Remove given tag from the set of tags of the variable. Note that this does not nothing if the tag belongs to the device or its component (those are read-only).
getTags
(facet)¶return unmodifiable set of tags that belong to the specified tag facet. This is different from the attribute
tags
: or methodgetTags()
(with no arguments) that returns full set of tags of the variable, call togetTags()
returns only subset of tags that belong to the specified tag facet. For example, you can get ifIndex of the parent interface this way:
1 2 3 4 assert isinstance(var, MonitoringVariable) for tag in var.getTags('ifParent'): # tag looks like 'ifPArent.5', where the number is ifIndex of parent interface parent_if_index = int(tag.split('.')[1])
add
(observation)¶Append new observation to the end of the list MonitoringVariable.timeseries
add
(observations)Merge observations from the list observations with observations in the list MonitoringVariable.timeseries. This method sorts observations by the time stamp and makes sure new ones are inserted in the right position. Old and new observations with identical timestamp are deduplicated.
double getMinValue()
calculates and returns minimum value by comparing values of all observations in the time series of this monitoring variable stored in the memory buffer. Returns result as a number
double getMaxValue()
calculates and returns maximum value by comparing values of all observations in the time series of this monitoring variable stored in the memory buffer. Returns result as a number
__cmp__
(other)¶compare values of the latest data points in time series of self and other. This makes it possible to sort lists of MonitorngVariable instances or use built-in Python functions max() and min().
__cmp__
(value)compare value of the latest data point in the time series of self with constant.
__add__
(other)¶
__sub__
(other)¶
__mul__
(other)¶
__div__
(other)¶Arithmetic operations between latest values of the time series of two
MonitoringVariable
objects this and other. All these functions return copy of this with time series modified so it has just one data point with calculated value. tags in the variable retain their values only if they are the same in this and other (in other words, after the call to these functions the set of tags is an intersection of sets of tags of two operands before the call). These functions enable calls to Python built-ins sum(), reduce() and others. For example, call to sum() can be used to to calculate sum of values of monitoring variables instances in a list.
__add__
(k)
__sub__
(k)
__mul__
(k)
__div__
(k)The same as the above, but operates with constant k as a second argument.
__radd__
(k)¶
__rsub__
(k)¶
__rmul__
(k)¶
__rdiv__
(k)¶These versions of the arichmetics functions operate with reversed arguments and enable Python expressions such as:
1 2 k + mvar k * mvarwhere k is a constant and mvar is an instance of
MonitoringVariable
. These magic functions make it possible to write in Python:aggregate_var = aggregate_var + input_traffic_rate * 60where both aggregate_var and input_traffic_rate are both instances of
MonitoringVariable
. Expression used in this example can be used to calculate total amount of input or outputtraffic (in bytes) through interface. This formula can be used in combination with call toreduce()
.
14.2.2. Statistics¶
-
class
net.happygears.nw2.py.
Statistics
¶ Object of this class provides functions that can be used to perform basic statistical calculations over the time series of the parent monitoring variable. Example:
1 2 3 4 5
def is_outlier(mvar, value, n_sigmas): assert isinstance(mvar, MonitoringVariable) mean = mvar.statistics.mean() sigma = mvar.statistics.sigma() return value != mean and abs(value - mean) >= (n_sigmas * sigma)
14.2.2.1. Methods¶
double mean()
returns a number equal to the mean value of observations in the whole time series stored in memory. Observations with value NaN are skipped. Note that this operates only on the data in memory. The length of the time series in memmory is determined by the value of configuration parameter monitor.storage.retentionHrs
double mean(begin, length)
returns a number equal to the mean value of
length
non-NaN observations in the time series beginning with observation with indexbegin
. Observations with value NaN are skipped and do not count towardslength
. If begin + length extends beyond the end of the time series buffer, this function stops at the last element. Note that this operates only on the data in memory.
double median()
returns a number equal to the median value of observations in the whole time series stored in memory. Observations with value NaN are skipped. Note that this operates only on the data in memory. The length of the time series in memmory is determined by the value of configuration parameter monitor.storage.retentionHrs
double median(begin, length)
returns a number equal to the median value of
length
non-NaN observations in the time series beginning with observation with indexbegin
. Observations with value NaN are skipped and do not count towardslength
. If begin + length extends beyond the end of the time series buffer, this function stops at the last element. Note that this operates only on the data in memory.
double sigma()
returns a number equal to the standard deviation of values of observations in the whole time series stored in memory. Observations with value NaN are skipped. Note that this operates only on the data in memory. The length of the time series in memmory is determined by the value of configuration parameter monitor.storage.retentionHrs
double sigma(begin, length)
returns a number equal to the standard deviation of
length
non-NaN observations in the time series beginning with observation with indexbegin
. Observations with value NaN are skipped and do not count towardslength
. If begin + length extends beyond the end of the time series buffer, this function stops at the last element. Note that this operates only on the data in memory.
14.2.3. TimeSeries¶
-
class
net.happygears.nw2.time_series_buffer.
TimeSeriesBuffer
¶ Object of this class represents single time series, that is, a set of timestamp-value pairs that represents monitoring data collected for single
net.happygears.nw2.py.MonitoringVariable
instance. This behaves like a list where items are objects of the classnet.happygears.nw2.py.Observation
, so you can iterate over it and access items by index. Unlike in case of the standard Python lists, functions that access observations return a copy of the data stored in the time series. You do not need to create objects of this class manually, instead, you always access them as attribute timeseries ofnet.happygears.nw2.py.MonitoringVariable
:1 2 3
assert isinstance(mvar, MonitoringVariable) for observation in mvar.timeseries: print observation
14.2.3.1. Methods¶
long getLastTimeStamp()
returns time stamp of the last observation in the time series
double getLastValue()
returns value of the last observation in the time series. This can be a NaN.
getLastNonNaNValue
()¶Return value of the latest observation that is not a NaN regardless of its timestamp and how far back in time that was
boolean isLastNaN()
checks if the last observation in the time series is a NaN.
void put(long timestamp, double value)
Puts new observation into the time series buffer
void clear()
clears time series buffer.
Observation first()
returns first observation as
Observation
object
Observation last()
returns last observation as
Observation
object
long getTimeStamp(int idx)
returns time stamp of the observation identified by its index
idx
double getValue(int idx)
returns value of the observation identified by its index
idx
double getLastValue()
returns the value of the last observation in the time series. If the time series holds numeric values, this function returns the last one. If the time series holds strings, this function returns NaN.
String getLastValueAsString()
returns the value of the last observation in the time series. This function returns string representation of the last value regardless of its type, that is, if the time series holds numeric values, this function returns formatted value as a string.
Observation get(int idx)
returns observation identified by its index
idx
asObservation
object
void updateLastValue(final double value)
update value of the last observation in the buffer
double getMinValue()
calculates and returns minimum value by comparing values of all observations in the time series buffer. Returns result as a number
double getMaxValue()
calculates and returns maximum value by comparing values of all observations in the time series buffer. Returns result as a number
14.2.3.2. Python “magic” methods¶
__len__
()¶returns the size of the time series
__nonzero__
()¶returns true if the time series is not empty. This function enables the following Python expression:
1 2 if mvar.timeseries: # do something when time series is not empty
Observation __getitem__(int key)
returns
Observation
object identified by its indexkey
. With this function we can access observations in the time series as if it was a list:mvar.timeseries[1]negative index is also supported:
mvar.timeseries[-1]slices are supported too:
mvar.timeseries[1:10]
14.2.4. Observation¶
-
class
net.happygears.nw2.py.
Observation
¶
14.2.4.1. Attributes¶
timestamp
¶a time stamp in milliseconds (long)
value
value of the observation. This is stored as an instance of Java class Number and can be used in Python directly. This can be NaN.
14.2.4.2. Methods¶
Observation
(timestamp)¶
Parameters: timestamp – observation time stamp (time in milliseconds) Create an Observation object with given timestamp and value of NaN
Observation
(timestamp, value)
Parameters:
- timestamp – observation time stamp (time in milliseconds)
- value – observation value (a number)
Create an Observation object with given timestamp and value
isNaN
()¶Returns True of the value of this Observation is NaN.
14.2.4.3. Python “magic” methods¶
__cmp__
(other)
__eq__
(value)¶
__ne__
(value)¶
__lt__
(value)¶
__le__
(value)¶
__gt__
(value)¶
__ge__
(value)¶“rich” comparison methods are supported and compare Observation value, ignoring its timestamp.
__str__
(other)¶Return string representation of the Observation, useful for logging and reports. Timestamp is printed in seconds.
14.2.5. DataSource¶
-
class
net.happygears.nw2.py.
DataSource
¶ Instance of this class are creaeted internally when the system prepares monitoring variables used for device polling. MonitoringVariable instances hold reference to the instance of DataSource class. You should not need to create objects of this class in the Python script.
14.2.5.1. Attributes¶
name
The name of the data source. This matches the name of the interface or hardware component this data source describes.
index
index is equal to ifIndex if Data Source corresponds to an interface or some kind of unique index of hw component that we have learned while discovering device components.
container
¶Container describes hw component that contains the component named by attribute “name”. Not all components have containers, this depends on the device vendor.
description
Component description. In case of an interface, this is interface description.
unit
¶Units in which collected data is measured. For example, for the variables that collect data from temperature sensors, this could be ‘C’.
14.2.6. DataScaler¶
-
class
net.happygears.nw2.py.
DataScaler
¶ -
DataScaler
(DataSource ds)¶ Parameters: ds (DataSource) – input DataSource object this scaler takes into account pre-set data range it takes from the data source. Since it does not have access to the timeseries, it can not take into account actual values.
-
14.2.6.1. Methods¶
DataScaler
(MonitoringVariable mvar)¶
Parameters: mvar (MonitoringVariable) – monitoring variable to take values from this constructor has access to both DataSource object (a member of MonitoringVariable) and timeseries. Scaler will compute the range using actual values of observations in the time series
DataScaler.
scaleValue
(Observation o)¶
Parameters: o (Observation) – input Observation object Takes an Observation object and returns a number equal to the scaled value of this observation
DataScaler.
getPrefix
()¶returns calculated prefix.
DataScaler.
getUnit
()¶returns the same basic unit it copies form the DataSource object
Example:
1 2 3 4 assert isinstance(mvar, MonitoringVariable) scaler = DataScaler(mvar) value = mvar.last() print scaler.scaleValue(value) + ' ' + scaler.getPrefix() + scaler.getUnit()
14.3. Wrappers¶
The following classes are Python wrappers for the Java classes used to hold information about devices, network interfaces, hardware components etc. These classes are used in variable and view builder scripts.
14.3.1. PyDevice¶
-
class
net.happygears.nw2.py.py_wrappers.
PyDevice
¶
14.3.1.1. Attributes¶
name
Device name. This can be one of the following:
- if config file nw2.conf mentions this device by name, then the value of this attribute is taken from the config.
- if the device is configured by its ip address, then the program tries to use the value returned by sysName OID when we discover the device. This is usually the “hostname” configured on the device.
- if we could not get the value of sysName, then the program runs reverse DNS lookup for the address of the device and assigns the result to this attribute.
- if reverse DNS lookup query fails, the value of this attribute is equal to the ip address of the device.
sys_name
¶Device name returned by the System MIB sysName OID. This is usually host name configured on the device
reverse_dns
¶DNS PTR record configured for this device’s IP address
hostname
¶Device name with all domain parts stripped. If device is configured with short host name, the value of this attribute is equal to it. If the host name configured on the device is really FQDN, then this attribute is equal to its leftmost component.
location
¶Device location configured in the System MIB sysLocation OID
contact
¶Contact name configured in the System MIB sysContact OID
sys_descr
¶Device description returned by the System MIB sysDescr OID.
box_descr
¶Device’s hardware description
sw_rev
¶Software revision running on the device
address
¶IP address used to communicate with the device
tags
Tags of this device as a set of strings. You can manipulate tags by adding or removing items of this set. Setting new value to this attribute is not supported.
14.3.1.2. Instance Methods¶
getTagsInFacet
(facet)¶returns list of tags that belong to the specified tag facet. This is different from the attribute
tags
: where the attribute returns full set of tags of the variable, call togetTagsInFacet()
returns only subset of tags that belong to the specified tag facet.
getNode
()¶returns reference to the underlying
NetworkNode
object.
forwardingClasses
()¶returns set of formwaridng class numbers configured on the device
getQueueNum
(int fcNumber)¶
Parameters: fcNumber – forwarding class number returns Cos queue number for the given forwarding class number
getFcName
(int fcNumber)¶
Parameters: fcNumber – forwarding class number returns forwarding class name for the given forwarding class number
getFcNumber
(int queueNumber)¶
Parameters: queueNumber – queue number returns forwarding class number for the given queue number
getVmHostName
()¶returns VM host name if this device is virtual machine, otherwise returns empty string
getPyInterfaces
()¶returns list of
net.happygears.nw2.py.py_wrappers.PyNetworkInterface
objects that represent network interfaces of this device
getInterface
(int ifIndex)¶return
net.happygears.nw2.py.py_wrappers.PyNetworkInterface
object that represents network interface with given ifIndex. If such interface does not exist, this method returns None.
14.3.2. PyNetworkInterface¶
-
class
net.happygears.nw2.py.py_wrappers.
PyNetworkInterface
¶
14.3.2.1. Attributes¶
name
Interface name
description
Interface description
abbreviated_name
¶Abbreviated name of the interface. NetSpyGlass uses internal translation table to generate abbreviated names. For example, “GigabitEthernet” translates to “ge” and “TenGigabitEthernet” translates to “te”.
address
First address and netmask of the interface as a string in “address/prefixlen” notation
addresses
¶List of all addresses of the interface as strings in in “address/prefixlen” notation
tags
Tags of this interface as a set of strings. You can manipulate tags by adding or removing items of this set. Setting new value to this attribute is not supported.
if_index
¶Interface ifIndex
if_speed
¶Value returned by ifSpeed OID
if_high_speed
¶Value returned by ifHighSpeed OID if it is supported
isis_circuit
¶Id of ISIS circuit terminating on this interface
cos_queues
¶all QoS queues configured on the interface as a set of numbers
14.3.3. PyHardwareComponent¶
-
class
net.happygears.nw2.py.py_wrappers.
PyHardwareComponent
¶
14.3.3.1. Attributes¶
name
Component name
index
Component index. This index is guaranteed to be unique within parent device. Hardware components and interfaces use separate indexes so h/w component index may conisidentally be the same as ifIndex of some interface. In most cases h/w component index is derived from the OID of the component but some times can be computed (this depends on the vendor and SNMP MIB used to discover the component)
description
Component description if available
model
¶Component model if available
oid
¶SNMP OID we use to query to get component status or current value if it is a sensor
sensor_scale
¶Values returned by queries to the oid are multiplied by this coefficient to normalize them. For example, if SNMP MIB says that some sensor reports value in units of 0.01A, then sensor_scale may be set to 100 to normalize values and record them in units of 1A. This makes it possible to maintain common database of values for devices from different vendoes that might report values in different units.
sensor_data_type
¶(a string) this attribute describes the unit this sensor uses and has one of the following values:
- other
- unknown
- voltsAC
- voltsDC
- amperes
- watts
- hertz
- celsius
- percentRH
- rpm
- cmm
- truthvalue
- specialEnum
- dBm
this list will grow over time as we add support for new sensors. If hardware component is not a sensor, the value of this attribute is “other”
component_class
¶(a string) this attribute describes high level class the component belongs to and can be one of the following:
- other
- unknown
- chassis
- backplane
- container
- powerSupply
- fan
- sensor
- module
- port
- stack
- cpu
- opticalTransceiver
- chassisAlarm
- pdu
- disk
- memory
this list will grow over time as we add support for new component classes.
tags
Tags as a set of strings
14.3.4. PyChassisAlarm¶
-
class
net.happygears.nw2.py.py_wrappers.
PyChassisAlarm
¶ net.happygears.nw2.py.py_wrappers.PyChassisAlarm
is a special case ofnet.happygears.nw2.py.py_wrappers.PyHardwareComponent
that has attributecomponent_class
with value chassisAlarm. This object represents a counter of minor or major chassis alarms raised by the device. This class has all attributes ofnet.happygears.nw2.py.py_wrappers.PyHardwareComponent
and one additional attribute:
14.3.5. PyProtocolDescriptor¶
-
class
net.happygears.nw2.py.py_wrappers.
PyProtocolDescriptor
¶ This class is an abstraction that describes parameter or a counter of a protocol. For example, this can be BGP peer state or number of BGP updates received from a peer and so on.
14.3.5.1. Attributes¶
name
Component name
index
Object index. This index is guaranteed to be unique within parent device. In most cases index is derived from the OID of the component but some times can be computed (this depends on the vendor and SNMP MIB used to discover the component)
description
Component description if available
oid
SNMP OID we use to query to get current value of the counter
sensor_scale
Values returned by queries to the oid are multiplied by this coefficient to normalize them.
protocol
¶(a string) the name of the network protocol, such as ‘OSPF’ or ‘BGP4’
14.3.6. PyNetworkGraph¶
-
class
net.happygears.nw2.py.py_wrappers.
PyNetworkGraph
¶ Objects of this class wraps internal class that represents network topology graph.
14.3.6.1. Instance Methods¶
get_connected_device
(device, intf)¶
Parameters:
- device –
net.happygears.nw2.py.py_wrappers.PyDevice
object that represents device- intf –
net.happygears.nw2.py.py_wrappers.PyNetworkInterface
object that represents network interface of the same deviceReturns: a tuple (opp_dev, opp_intf) where opp_dev is
net.happygears.nw2.py.py_wrappers.PyDevice
object that represents device on the opposite end of the network link terminated on dev:intf and opp_intf is annet.happygears.nw2.py.py_wrappers.PyNetworkInterface
object that represents corresponding interface of opp_dev. If interface intf is not connected anywhere, this function returns None.You can find example of this method usage in section User Defined Interface Tags: Parsing Interface Descriptions.
14.4. Examples¶
The following examples are taken from the interface variables builder script, you can find a copy of this script in python/variable_builders/interface.py in your NetSpyGlass installation.
Here is an example of a function that accesses network interface tags to check some conditions:
1 2 3 4 5 6 7 8 9 10 11 12 13 | def is_interesting_interface(self, intf):
"""
This function implements some basic checks 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 ('ifAdminStatus.Up' in intf.tags and
not 'ifRole.LoopbackInterface' in intf.tags and
not 'ifRole.OutOfBandManagement' in intf.tags and
not 'ifRole.SimulatedInterface' in intf.tags and
not 'ifRole.Internal' in intf.tags)
|
Next example demonstrates access to attributes if_index and if_speed of network interface object:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | def make_basic_vars(self, intf):
"""
Generate configuration for the basic set of monitoring variables
for the interface: interface utilization, errors, discards
:type intf: PyNetworkInterface
:param intf: PyNetworkInterface wrapper object
:return: a dictionary where the key is variable name and value is another dictionary
"""
if_index = intf.if_index
in_octets_oid = 'IF-MIB:ifInOctets.{0}'.format(if_index)
out_octets_oid = 'IF-MIB:ifOutOctets.{0}'.format(if_index)
if_speed_oid = 'IF-MIB:ifSpeed.{0}'.format(if_index)
if_speed_scale = 1.0
if intf.if_high_speed > 0:
in_octets_oid = 'IF-MIB:ifHCInOctets.{0}'.format(if_index)
out_octets_oid = 'IF-MIB:ifHCOutOctets.{0}'.format(if_index)
if_speed_oid = 'IF-MIB:ifHighSpeed.{0}'.format(if_index)
if_speed_scale = 1E6 # ifHighSpeed is in 1,000,000 bits/sec
return {
# ---------------------------------------------------------------
'ifSpeed': {
'component': intf,
'snmp_oid': if_speed_oid,
'scale': if_speed_scale
},
'ifHCInOctets': {
'component': intf,
'snmp_oid': in_octets_oid
},
'ifHCOutOctets': {
'component': intf,
'snmp_oid': out_octets_oid
}
}
|