Skip to content

Commit

Permalink
Folding (#181). Added: folding of server-info-rate output
Browse files Browse the repository at this point in the history
Can be used only manually now.
  • Loading branch information
strizhechenko committed Dec 20, 2017
1 parent 4fc1993 commit 484d211
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 31 deletions.
75 changes: 52 additions & 23 deletions netutils_linux_hardware/assessor.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
# coding: utf-8
import argparse

import yaml

from netutils_linux_hardware.assessor_math import extract
from netutils_linux_hardware.grade import Grade

FOLDING_NO = 0
FOLDING_DEVICE = 1
FOLDING_SUBSYSTEM = 2
FOLDING_SERVER = 3


class Assessor(object):
""" Calculates rates for important system components """
Expand All @@ -10,25 +19,35 @@ class Assessor(object):

def __init__(self, data):
self.data = data
self.args = self.parse_args()
if self.data:
self.assess()

def fold(self, data, level):
""" Схлапывает значения в дикте до среднего арифметического """
if not data:
return 1
if self.args.folding < level:
return data
result = sum(data.values()) / len(data.keys())
return result if level < FOLDING_SERVER else {'server': result}

def __str__(self):
return yaml.dump(self.info, default_flow_style=False).strip()

def assess(self):
self.info = {
self.info = self.fold({
'net': self.__assess(self.assess_netdev, 'net'),
'cpu': self.assess_cpu(),
'memory': self.assess_memory(),
'system': self.assess_system(),
'disk': self.__assess(self.assess_disk, 'disk'),
}
}, FOLDING_SERVER)

def assess_cpu(self):
cpuinfo = extract(self.data, ['cpu', 'info'])
if cpuinfo:
return {
return self.fold({
'CPU MHz': Grade.int(cpuinfo.get('CPU MHz'), 2000, 4000),
'BogoMIPS': Grade.int(cpuinfo.get('BogoMIPS'), 4000, 8000),
'CPU(s)': Grade.int(cpuinfo.get('CPU(s)'), 2, 32),
Expand All @@ -37,51 +56,55 @@ def assess_cpu(self):
'Thread(s) per core': Grade.int(cpuinfo.get('Thread(s) per core'), 2, 1),
'L3 cache': Grade.int(cpuinfo.get('L3 cache'), 1000, 30000),
'Vendor ID': Grade.str(cpuinfo.get('Vendor ID'), good=['GenuineIntel']),
}
}, FOLDING_SUBSYSTEM)

def assess_memory_device(self, device):
return {
'size': Grade.int(device.data.get('size', 0), 512, 8196),
'type': Grade.known_values(device.data.get('type', 'RAM'), {
return self.fold({
'size': Grade.int(device.get('size', 0), 512, 8196),
'type': Grade.known_values(device.get('type', 'RAM'), {
'DDR1': 2,
'DDR2': 3,
'DDR3': 6,
'DDR4': 10,
}),
'speed': Grade.int(device.data.get('speed', 0), 200, 4000),
}
'speed': Grade.int(device.get('speed', 0), 200, 4000),
}, FOLDING_DEVICE)

def assess_memory_devices(self, devices):
return dict((handle, self.assess_memory_device(device)) for handle, device in devices.items())
if not devices:
return 1
return self.fold(dict((handle, self.assess_memory_device(device))
for handle, device in devices.items()),
FOLDING_SUBSYSTEM)

def assess_memory_size(self, size):
return {
return self.fold({
'MemTotal': Grade.int(size.get('MemTotal'), 2 * (1024 ** 2), 16 * (1024 ** 2)),
'SwapTotal': Grade.int(size.get('SwapTotal'), 512 * 1024, 4 * (1024 ** 2)),
}
}, FOLDING_DEVICE)

def assess_memory(self):
meminfo = self.data.get('memory')
if meminfo:
return {
return self.fold({
'devices': self.assess_memory_devices(meminfo.get('devices')),
'size': self.assess_memory_size(meminfo.get('size')),
}
}, FOLDING_SUBSYSTEM)

def assess_system(self):
cpuinfo = extract(self.data, ['cpu', 'info'])
if cpuinfo:
return {
return self.fold({
'Hypervisor vendor': Grade.fact(cpuinfo.get('Hypervisor vendor'), False),
'Virtualization type': Grade.fact(cpuinfo.get('Hypervisor vendor'), False),
}
}, FOLDING_SUBSYSTEM)

def assess_netdev(self, netdev):
netdevinfo = extract(self.data, ['net', netdev])
queues = sum(
len(extract(netdevinfo, ['queues', x])) for x in ('rx', 'rxtx'))
buffers = netdevinfo.get('buffers') or {}
return {
return self.fold({
'queues': Grade.int(queues, 2, 8),
'driver': {
'mlx5_core': 10, # 7500 mbit/s
Expand All @@ -94,21 +117,27 @@ def assess_netdev(self, netdev):
'e1000': 3, # 50 mbit/s
'r8169': 1, 'ATL1E': 1, '8139too': 1, # real trash, you should never use it
}.get(netdevinfo.get('driver').get('driver'), 2),
'buffers': {
'buffers': self.fold({
'cur': Grade.int(buffers.get('cur'), 256, 4096),
'max': Grade.int(buffers.get('max'), 256, 4096),
},
}
}, FOLDING_DEVICE)
}, FOLDING_DEVICE)

def assess_disk(self, disk):
diskinfo = extract(self.data, ['disk', disk])
return {
return self.fold({
'type': Grade.str(diskinfo.get('type'), ['SDD'], ['HDD']),
# 50Gb - good, 1Tb - good enough
'size': Grade.int(diskinfo.get('size'), 50 * (1000 ** 3), 1000 ** 4),
}
}, FOLDING_DEVICE)

def __assess(self, func, key):
items = self.data.get(key)
if items:
return dict((item, func(item)) for item in items)
return self.fold(dict((item, func(item)) for item in items), FOLDING_SUBSYSTEM)

def parse_args(self):
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--folding', action='count', help='-f - device, -ff - subsystem, -fff - server',
default=FOLDING_NO)
return parser.parse_args()
2 changes: 1 addition & 1 deletion netutils_linux_hardware/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ def __parse(devices):
for device in devices:
if 'Memory Device' in device:
mem_dev = MemInfoDMIDevice(device)
output[mem_dev.handle] = mem_dev
output[mem_dev.handle] = mem_dev.data
return output


Expand Down
16 changes: 9 additions & 7 deletions utils/server-info-rate
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ from six import print_
from netutils_linux_hardware.assessor import Assessor
from netutils_linux_hardware.reader import Reader

def get_datadir():
default_data_directory = 'tests/autotune_network.tests/2xE5-2640.i350_and_82599ES.l2_mixed.masterconf'
if os.path.isfile(os.path.join(os.getcwd(), 'lspci')):
return os.getcwd()
return os.environ.get('DATADIR', default_data_directory)


def main():
cwd = os.getcwd()
directory = cwd if os.path.isfile(os.path.join(cwd, 'lspci')) else os.getenv('DATADIR')
reader = Reader(directory)
assessor = Assessor(reader.info)
print_(assessor)


if __name__ == '__main__':
print_(Assessor(Reader(get_datadir()).info))
main()

0 comments on commit 484d211

Please sign in to comment.