1+ # coding: utf-8
2+ import argparse
3+
14import yaml
5+
26from netutils_linux_hardware .assessor_math import extract
37from netutils_linux_hardware .grade import Grade
48
9+ FOLDING_NO = 0
10+ FOLDING_DEVICE = 1
11+ FOLDING_SUBSYSTEM = 2
12+ FOLDING_SERVER = 3
13+
514
615class Assessor (object ):
716 """ Calculates rates for important system components """
@@ -10,25 +19,35 @@ class Assessor(object):
1019
1120 def __init__ (self , data ):
1221 self .data = data
22+ self .args = self .parse_args ()
1323 if self .data :
1424 self .assess ()
1525
26+ def fold (self , data , level ):
27+ """ Схлапывает значения в дикте до среднего арифметического """
28+ if not data :
29+ return 1
30+ if self .args .folding < level :
31+ return data
32+ result = sum (data .values ()) / len (data .keys ())
33+ return result if level < FOLDING_SERVER else {'server' : result }
34+
1635 def __str__ (self ):
1736 return yaml .dump (self .info , default_flow_style = False ).strip ()
1837
1938 def assess (self ):
20- self .info = {
39+ self .info = self . fold ( {
2140 'net' : self .__assess (self .assess_netdev , 'net' ),
2241 'cpu' : self .assess_cpu (),
2342 'memory' : self .assess_memory (),
2443 'system' : self .assess_system (),
2544 'disk' : self .__assess (self .assess_disk , 'disk' ),
26- }
45+ }, FOLDING_SERVER )
2746
2847 def assess_cpu (self ):
2948 cpuinfo = extract (self .data , ['cpu' , 'info' ])
3049 if cpuinfo :
31- return {
50+ return self . fold ( {
3251 'CPU MHz' : Grade .int (cpuinfo .get ('CPU MHz' ), 2000 , 4000 ),
3352 'BogoMIPS' : Grade .int (cpuinfo .get ('BogoMIPS' ), 4000 , 8000 ),
3453 'CPU(s)' : Grade .int (cpuinfo .get ('CPU(s)' ), 2 , 32 ),
@@ -37,51 +56,55 @@ def assess_cpu(self):
3756 'Thread(s) per core' : Grade .int (cpuinfo .get ('Thread(s) per core' ), 2 , 1 ),
3857 'L3 cache' : Grade .int (cpuinfo .get ('L3 cache' ), 1000 , 30000 ),
3958 'Vendor ID' : Grade .str (cpuinfo .get ('Vendor ID' ), good = ['GenuineIntel' ]),
40- }
59+ }, FOLDING_SUBSYSTEM )
4160
4261 def assess_memory_device (self , device ):
43- return {
44- 'size' : Grade .int (device .data . get ('size' , 0 ), 512 , 8196 ),
45- 'type' : Grade .known_values (device .data . get ('type' , 'RAM' ), {
62+ return self . fold ( {
63+ 'size' : Grade .int (device .get ('size' , 0 ), 512 , 8196 ),
64+ 'type' : Grade .known_values (device .get ('type' , 'RAM' ), {
4665 'DDR1' : 2 ,
4766 'DDR2' : 3 ,
4867 'DDR3' : 6 ,
4968 'DDR4' : 10 ,
5069 }),
51- 'speed' : Grade .int (device .data . get ('speed' , 0 ), 200 , 4000 ),
52- }
70+ 'speed' : Grade .int (device .get ('speed' , 0 ), 200 , 4000 ),
71+ }, FOLDING_DEVICE )
5372
5473 def assess_memory_devices (self , devices ):
55- return dict ((handle , self .assess_memory_device (device )) for handle , device in devices .items ())
74+ if not devices :
75+ return 1
76+ return self .fold (dict ((handle , self .assess_memory_device (device ))
77+ for handle , device in devices .items ()),
78+ FOLDING_SUBSYSTEM )
5679
5780 def assess_memory_size (self , size ):
58- return {
81+ return self . fold ( {
5982 'MemTotal' : Grade .int (size .get ('MemTotal' ), 2 * (1024 ** 2 ), 16 * (1024 ** 2 )),
6083 'SwapTotal' : Grade .int (size .get ('SwapTotal' ), 512 * 1024 , 4 * (1024 ** 2 )),
61- }
84+ }, FOLDING_DEVICE )
6285
6386 def assess_memory (self ):
6487 meminfo = self .data .get ('memory' )
6588 if meminfo :
66- return {
89+ return self . fold ( {
6790 'devices' : self .assess_memory_devices (meminfo .get ('devices' )),
6891 'size' : self .assess_memory_size (meminfo .get ('size' )),
69- }
92+ }, FOLDING_SUBSYSTEM )
7093
7194 def assess_system (self ):
7295 cpuinfo = extract (self .data , ['cpu' , 'info' ])
7396 if cpuinfo :
74- return {
97+ return self . fold ( {
7598 'Hypervisor vendor' : Grade .fact (cpuinfo .get ('Hypervisor vendor' ), False ),
7699 'Virtualization type' : Grade .fact (cpuinfo .get ('Hypervisor vendor' ), False ),
77- }
100+ }, FOLDING_SUBSYSTEM )
78101
79102 def assess_netdev (self , netdev ):
80103 netdevinfo = extract (self .data , ['net' , netdev ])
81104 queues = sum (
82105 len (extract (netdevinfo , ['queues' , x ])) for x in ('rx' , 'rxtx' ))
83106 buffers = netdevinfo .get ('buffers' ) or {}
84- return {
107+ return self . fold ( {
85108 'queues' : Grade .int (queues , 2 , 8 ),
86109 'driver' : {
87110 'mlx5_core' : 10 , # 7500 mbit/s
@@ -94,21 +117,27 @@ def assess_netdev(self, netdev):
94117 'e1000' : 3 , # 50 mbit/s
95118 'r8169' : 1 , 'ATL1E' : 1 , '8139too' : 1 , # real trash, you should never use it
96119 }.get (netdevinfo .get ('driver' ).get ('driver' ), 2 ),
97- 'buffers' : {
120+ 'buffers' : self . fold ( {
98121 'cur' : Grade .int (buffers .get ('cur' ), 256 , 4096 ),
99122 'max' : Grade .int (buffers .get ('max' ), 256 , 4096 ),
100- },
101- }
123+ }, FOLDING_DEVICE )
124+ }, FOLDING_DEVICE )
102125
103126 def assess_disk (self , disk ):
104127 diskinfo = extract (self .data , ['disk' , disk ])
105- return {
128+ return self . fold ( {
106129 'type' : Grade .str (diskinfo .get ('type' ), ['SDD' ], ['HDD' ]),
107130 # 50Gb - good, 1Tb - good enough
108131 'size' : Grade .int (diskinfo .get ('size' ), 50 * (1000 ** 3 ), 1000 ** 4 ),
109- }
132+ }, FOLDING_DEVICE )
110133
111134 def __assess (self , func , key ):
112135 items = self .data .get (key )
113136 if items :
114- return dict ((item , func (item )) for item in items )
137+ return self .fold (dict ((item , func (item )) for item in items ), FOLDING_SUBSYSTEM )
138+
139+ def parse_args (self ):
140+ parser = argparse .ArgumentParser ()
141+ parser .add_argument ('-f' , '--folding' , action = 'count' , help = '-f - device, -ff - subsystem, -fff - server' ,
142+ default = FOLDING_NO )
143+ return parser .parse_args ()
0 commit comments