Robert Chacón 2022-09-12 01:37:25 -06:00 committed by GitHub
parent 6964aad285
commit 8ba4f06135
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -10,199 +10,177 @@ from ispConfig import interfaceA, interfaceB, influxDBBucket, influxDBOrg, influ
def getInterfaceStats(interface): def getInterfaceStats(interface):
command = 'tc -j -s qdisc show dev ' + interface command = 'tc -j -s qdisc show dev ' + interface
jsonAr = json.loads(subprocess.run(command.split(' '), stdout=subprocess.PIPE).stdout.decode('utf-8')) jsonAr = json.loads(subprocess.run(command.split(' '), stdout=subprocess.PIPE).stdout.decode('utf-8'))
jsonDict = {} jsonDict = {}
for element in filter(lambda e: 'parent' in e, jsonAr): for element in filter(lambda e: 'parent' in e, jsonAr):
flowID = ':'.join(map(lambda p: f'0x{p}', element['parent'].split(':')[0:2])) flowID = ':'.join(map(lambda p: f'0x{p}', element['parent'].split(':')[0:2]))
jsonDict[flowID] = element jsonDict[flowID] = element
del jsonAr del jsonAr
return jsonDict return jsonDict
def chunk_list(l, n): def chunk_list(l, n):
for i in range(0, len(l), n): for i in range(0, len(l), n):
yield l[i:i + n] yield l[i:i + n]
def getDeviceStats(devices): def getDeviceStats(devices):
interfaces = [interfaceA, interfaceB] interfaces = [interfaceA, interfaceB]
ifaceStats = list(map(getInterfaceStats, interfaces)) ifaceStats = list(map(getInterfaceStats, interfaces))
for device in devices: for device in devices:
if 'timeQueried' in device: if 'timeQueried' in device:
device['priorQueryTime'] = device['timeQueried'] device['priorQueryTime'] = device['timeQueried']
for (interface, stats, dirSuffix) in zip(interfaces, ifaceStats, ['Download', 'Upload']): for (interface, stats, dirSuffix) in zip(interfaces, ifaceStats, ['Download', 'Upload']):
element = stats[device['qdisc']] if device['qdisc'] in stats else False element = stats[device['qdisc']] if device['qdisc'] in stats else False
if element: if element:
bytesSent = int(element['bytes']) bytesSent = int(element['bytes'])
drops = int(element['drops']) drops = int(element['drops'])
packets = int(element['packets']) packets = int(element['packets'])
if 'bytesSent' + dirSuffix in device: if 'bytesSent' + dirSuffix in device:
device['priorQueryBytes' + dirSuffix] = device['bytesSent' + dirSuffix] device['priorQueryBytes' + dirSuffix] = device['bytesSent' + dirSuffix]
device['bytesSent' + dirSuffix] = bytesSent device['bytesSent' + dirSuffix] = bytesSent
if 'dropsSent' + dirSuffix in device: if 'dropsSent' + dirSuffix in device:
device['priorDropsSent' + dirSuffix] = device['dropsSent' + dirSuffix] device['priorDropsSent' + dirSuffix] = device['dropsSent' + dirSuffix]
device['dropsSent' + dirSuffix] = drops device['dropsSent' + dirSuffix] = drops
if 'packetsSent' + dirSuffix in device: if 'packetsSent' + dirSuffix in device:
device['priorPacketsSent' + dirSuffix] = device['packetsSent' + dirSuffix] device['priorPacketsSent' + dirSuffix] = device['packetsSent' + dirSuffix]
device['packetsSent' + dirSuffix] = packets device['packetsSent' + dirSuffix] = packets
device['timeQueried'] = datetime.now().isoformat() device['timeQueried'] = datetime.now().isoformat()
for device in devices: for device in devices:
device['bitsDownloadSinceLastQuery'] = device['bitsUploadSinceLastQuery'] = 0 device['bitsDownloadSinceLastQuery'] = device['bitsUploadSinceLastQuery'] = 0
if 'priorQueryTime' in device: if 'priorQueryTime' in device:
try: try:
bytesDLSinceLastQuery = device['bytesSentDownload'] - device['priorQueryBytesDownload'] bytesDLSinceLastQuery = device['bytesSentDownload'] - device['priorQueryBytesDownload']
bytesULSinceLastQuery = device['bytesSentUpload'] - device['priorQueryBytesUpload'] bytesULSinceLastQuery = device['bytesSentUpload'] - device['priorQueryBytesUpload']
except: except:
bytesDLSinceLastQuery = bytesULSinceLastQuery = 0 bytesDLSinceLastQuery = bytesULSinceLastQuery = 0
currentQueryTime = datetime.fromisoformat(device['timeQueried']) currentQueryTime = datetime.fromisoformat(device['timeQueried'])
priorQueryTime = datetime.fromisoformat(device['priorQueryTime']) priorQueryTime = datetime.fromisoformat(device['priorQueryTime'])
deltaSeconds = (currentQueryTime - priorQueryTime).total_seconds() deltaSeconds = (currentQueryTime - priorQueryTime).total_seconds()
device['bitsDownloadSinceLastQuery'] = round( device['bitsDownloadSinceLastQuery'] = round(
((bytesDLSinceLastQuery * 8) / deltaSeconds)) if deltaSeconds > 0 else 0 ((bytesDLSinceLastQuery * 8) / deltaSeconds)) if deltaSeconds > 0 else 0
device['bitsUploadSinceLastQuery'] = round( device['bitsUploadSinceLastQuery'] = round(
((bytesULSinceLastQuery * 8) / deltaSeconds)) if deltaSeconds > 0 else 0 ((bytesULSinceLastQuery * 8) / deltaSeconds)) if deltaSeconds > 0 else 0
return devices return devices
def getParentNodeStats(parentNodes, devices): def getParentNodeStats(parentNodes, devices):
for parentNode in parentNodes: for parentNode in parentNodes:
thisNodeBitsDownload = 0 thisNodeBitsDownload = 0
thisNodeBitsUpload = 0 thisNodeBitsUpload = 0
for device in devices: for device in devices:
if device['ParentNode'] == parentNode['parentNodeName']: if device['ParentNode'] == parentNode['parentNodeName']:
thisNodeBitsDownload += device['bitsDownloadSinceLastQuery'] thisNodeBitsDownload += device['bitsDownloadSinceLastQuery']
thisNodeBitsUpload += device['bitsUploadSinceLastQuery'] thisNodeBitsUpload += device['bitsUploadSinceLastQuery']
parentNode['bitsDownloadSinceLastQuery'] = thisNodeBitsDownload parentNode['bitsDownloadSinceLastQuery'] = thisNodeBitsDownload
parentNode['bitsUploadSinceLastQuery'] = thisNodeBitsUpload parentNode['bitsUploadSinceLastQuery'] = thisNodeBitsUpload
return parentNodes return parentNodes
def getParentNodeDict(data, depth, parentNodeNameDict): def getParentNodeDict(data, depth, parentNodeNameDict):
if parentNodeNameDict == None: if parentNodeNameDict == None:
parentNodeNameDict = {} parentNodeNameDict = {}
for elem in data: for elem in data:
if 'children' in data[elem]: if 'children' in data[elem]:
for child in data[elem]['children']: for child in data[elem]['children']:
parentNodeNameDict[child] = elem parentNodeNameDict[child] = elem
tempDict = getParentNodeDict(data[elem]['children'], depth + 1, parentNodeNameDict) tempDict = getParentNodeDict(data[elem]['children'], depth + 1, parentNodeNameDict)
parentNodeNameDict = dict(parentNodeNameDict, **tempDict) parentNodeNameDict = dict(parentNodeNameDict, **tempDict)
return parentNodeNameDict return parentNodeNameDict
def parentNodeNameDictPull(): def parentNodeNameDictPull():
# Load network heirarchy # Load network heirarchy
with open('network.json', 'r') as j: with open('network.json', 'r') as j:
network = json.loads(j.read()) network = json.loads(j.read())
parentNodeNameDict = getParentNodeDict(network, 0, None) parentNodeNameDict = getParentNodeDict(network, 0, None)
return parentNodeNameDict return parentNodeNameDict
def refreshBandwidthGraphs(): def refreshBandwidthGraphs():
startTime = datetime.now() startTime = datetime.now()
with open('statsByParentNode.json', 'r') as j: with open('statsByParentNode.json', 'r') as j:
parentNodes = json.loads(j.read()) parentNodes = json.loads(j.read())
with open('statsByDevice.json', 'r') as j: with open('statsByDevice.json', 'r') as j:
devices = json.loads(j.read()) devices = json.loads(j.read())
parentNodeNameDict = parentNodeNameDictPull() parentNodeNameDict = parentNodeNameDictPull()
print("Retrieving device statistics") print("Retrieving device statistics")
devices = getDeviceStats(devices) devices = getDeviceStats(devices)
print("Computing parent node statistics") print("Computing parent node statistics")
parentNodes = getParentNodeStats(parentNodes, devices) parentNodes = getParentNodeStats(parentNodes, devices)
print("Writing data to InfluxDB") print("Writing data to InfluxDB")
client = InfluxDBClient( client = InfluxDBClient(
url=influxDBurl, url=influxDBurl,
token=influxDBtoken, token=influxDBtoken,
org=influxDBOrg org=influxDBOrg
) )
write_api = client.write_api(write_options=SYNCHRONOUS) write_api = client.write_api(write_options=SYNCHRONOUS)
chunkedDevices = list(chunk_list(devices, 200)) chunkedDevices = list(chunk_list(devices, 200))
queriesToSendCount = 0 queriesToSendCount = 0
for chunk in chunkedDevices: for chunk in chunkedDevices:
queriesToSend = [] queriesToSend = []
for device in chunk: for device in chunk:
bitsDownload = int(device['bitsDownloadSinceLastQuery']) bitsDownload = int(device['bitsDownloadSinceLastQuery'])
bitsUpload = int(device['bitsUploadSinceLastQuery']) bitsUpload = int(device['bitsUploadSinceLastQuery'])
if (bitsDownload > 0) and (bitsUpload > 0): if (bitsDownload > 0) and (bitsUpload > 0):
percentUtilizationDownload = round((bitsDownload / round(device['downloadMax'] * 1000000)), 4) percentUtilizationDownload = round((bitsDownload / round(device['downloadMax'] * 1000000)), 4)
percentUtilizationUpload = round((bitsUpload / round(device['uploadMax'] * 1000000)), 4) percentUtilizationUpload = round((bitsUpload / round(device['uploadMax'] * 1000000)), 4)
p = Point('Bandwidth').tag("Device", device['hostname']).tag("ParentNode", device['ParentNode']).tag("Type", "Circuit").field("Download", bitsDownload).field("Upload", bitsUpload)
queriesToSend.append(p)
p = Point('Utilization').tag("Device", device['hostname']).tag("ParentNode", device['ParentNode']).tag("Type", "Circuit").field("Download", percentUtilizationDownload).field("Upload", percentUtilizationUpload)
queriesToSend.append(p)
p = Point('Bandwidth').tag("Device", device['hostname']).tag("ParentNode", device['ParentNode']).tag( write_api.write(bucket=influxDBBucket, record=queriesToSend)
"Type", "Device").field("Download", bitsDownload) # print("Added " + str(len(queriesToSend)) + " points to InfluxDB.")
queriesToSend.append(p) queriesToSendCount += len(queriesToSend)
p = Point('Bandwidth').tag("Device", device['hostname']).tag("ParentNode", device['ParentNode']).tag(
"Type", "Device").field("Upload", bitsUpload)
queriesToSend.append(p)
p = Point('Utilization').tag("Device", device['hostname']).tag("ParentNode", device['ParentNode']).tag(
"Type", "Device").field("Download", percentUtilizationDownload)
queriesToSend.append(p)
p = Point('Utilization').tag("Device", device['hostname']).tag("ParentNode", device['ParentNode']).tag(
"Type", "Device").field("Upload", percentUtilizationUpload)
queriesToSend.append(p)
write_api.write(bucket=influxDBBucket, record=queriesToSend) queriesToSend = []
# print("Added " + str(len(queriesToSend)) + " points to InfluxDB.") for parentNode in parentNodes:
queriesToSendCount += len(queriesToSend) bitsDownload = int(parentNode['bitsDownloadSinceLastQuery'])
bitsUpload = int(parentNode['bitsUploadSinceLastQuery'])
if (bitsDownload > 0) and (bitsUpload > 0):
percentUtilizationDownload = round((bitsDownload / round(parentNode['downloadMax'] * 1000000)), 4)
percentUtilizationUpload = round((bitsUpload / round(parentNode['uploadMax'] * 1000000)), 4)
p = Point('Bandwidth').tag("Device", parentNode['parentNodeName']).tag("ParentNode", parentNode['parentNodeName']).tag("Type", "Parent Node").field("Download", bitsDownload).field("Upload", bitsUpload)
queriesToSend.append(p)
p = Point('Utilization').tag("Device", parentNode['parentNodeName']).tag("ParentNode", parentNode['parentNodeName']).tag("Type", "Parent Node").field("Download", percentUtilizationDownload).field("Upload", percentUtilizationUpload)
queriesToSend.append(p)
queriesToSend = [] write_api.write(bucket=influxDBBucket, record=queriesToSend)
for parentNode in parentNodes: # print("Added " + str(len(queriesToSend)) + " points to InfluxDB.")
bitsDownload = int(parentNode['bitsDownloadSinceLastQuery']) queriesToSendCount += len(queriesToSend)
bitsUpload = int(parentNode['bitsUploadSinceLastQuery']) print("Added " + str(queriesToSendCount) + " points to InfluxDB.")
if (bitsDownload > 0) and (bitsUpload > 0):
percentUtilizationDownload = round((bitsDownload / round(parentNode['downloadMax'] * 1000000)), 4)
percentUtilizationUpload = round((bitsUpload / round(parentNode['uploadMax'] * 1000000)), 4)
p = Point('Bandwidth').tag("Device", parentNode['parentNodeName']).tag("ParentNode", client.close()
parentNode['parentNodeName']).tag(
"Type", "Parent Node").field("Download", bitsDownload)
queriesToSend.append(p)
p = Point('Bandwidth').tag("Device", parentNode['parentNodeName']).tag("ParentNode",
parentNode['parentNodeName']).tag(
"Type", "Parent Node").field("Upload", bitsUpload)
queriesToSend.append(p)
p = Point('Utilization').tag("Device", parentNode['parentNodeName']).tag("ParentNode",
parentNode['parentNodeName']).tag(
"Type", "Parent Node").field("Download", percentUtilizationDownload)
queriesToSend.append(p)
p = Point('Utilization').tag("Device", parentNode['parentNodeName']).tag("ParentNode",
parentNode['parentNodeName']).tag(
"Type", "Parent Node").field("Upload", percentUtilizationUpload)
queriesToSend.append(p)
write_api.write(bucket=influxDBBucket, record=queriesToSend)
# print("Added " + str(len(queriesToSend)) + " points to InfluxDB.")
queriesToSendCount += len(queriesToSend)
print("Added " + str(queriesToSendCount) + " points to InfluxDB.")
client.close()
with open('statsByParentNode.json', 'w') as infile: with open('statsByParentNode.json', 'w') as infile:
json.dump(parentNodes, infile) json.dump(parentNodes, infile)
with open('statsByDevice.json', 'w') as infile: with open('statsByDevice.json', 'w') as infile:
json.dump(devices, infile) json.dump(devices, infile)
endTime = datetime.now() endTime = datetime.now()
durationSeconds = round((endTime - startTime).total_seconds(), 2) durationSeconds = round((endTime - startTime).total_seconds(), 2)
print("Graphs updated within " + str(durationSeconds) + " seconds.") print("Graphs updated within " + str(durationSeconds) + " seconds.")
if __name__ == '__main__': if __name__ == '__main__':
refreshBandwidthGraphs() refreshBandwidthGraphs()