1
+ # coding: utf-8
2
+ import argparse
3
+
1
4
import yaml
5
+
2
6
from netutils_linux_hardware .assessor_math import extract
3
7
from netutils_linux_hardware .grade import Grade
4
8
9
+ FOLDING_NO = 0
10
+ FOLDING_DEVICE = 1
11
+ FOLDING_SUBSYSTEM = 2
12
+ FOLDING_SERVER = 3
13
+
5
14
6
15
class Assessor (object ):
7
16
""" Calculates rates for important system components """
@@ -10,25 +19,35 @@ class Assessor(object):
10
19
11
20
def __init__ (self , data ):
12
21
self .data = data
22
+ self .args = self .parse_args ()
13
23
if self .data :
14
24
self .assess ()
15
25
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
+
16
35
def __str__ (self ):
17
36
return yaml .dump (self .info , default_flow_style = False ).strip ()
18
37
19
38
def assess (self ):
20
- self .info = {
39
+ self .info = self . fold ( {
21
40
'net' : self .__assess (self .assess_netdev , 'net' ),
22
41
'cpu' : self .assess_cpu (),
23
42
'memory' : self .assess_memory (),
24
43
'system' : self .assess_system (),
25
44
'disk' : self .__assess (self .assess_disk , 'disk' ),
26
- }
45
+ }, FOLDING_SERVER )
27
46
28
47
def assess_cpu (self ):
29
48
cpuinfo = extract (self .data , ['cpu' , 'info' ])
30
49
if cpuinfo :
31
- return {
50
+ return self . fold ( {
32
51
'CPU MHz' : Grade .int (cpuinfo .get ('CPU MHz' ), 2000 , 4000 ),
33
52
'BogoMIPS' : Grade .int (cpuinfo .get ('BogoMIPS' ), 4000 , 8000 ),
34
53
'CPU(s)' : Grade .int (cpuinfo .get ('CPU(s)' ), 2 , 32 ),
@@ -37,51 +56,55 @@ def assess_cpu(self):
37
56
'Thread(s) per core' : Grade .int (cpuinfo .get ('Thread(s) per core' ), 2 , 1 ),
38
57
'L3 cache' : Grade .int (cpuinfo .get ('L3 cache' ), 1000 , 30000 ),
39
58
'Vendor ID' : Grade .str (cpuinfo .get ('Vendor ID' ), good = ['GenuineIntel' ]),
40
- }
59
+ }, FOLDING_SUBSYSTEM )
41
60
42
61
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' ), {
46
65
'DDR1' : 2 ,
47
66
'DDR2' : 3 ,
48
67
'DDR3' : 6 ,
49
68
'DDR4' : 10 ,
50
69
}),
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 )
53
72
54
73
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 )
56
79
57
80
def assess_memory_size (self , size ):
58
- return {
81
+ return self . fold ( {
59
82
'MemTotal' : Grade .int (size .get ('MemTotal' ), 2 * (1024 ** 2 ), 16 * (1024 ** 2 )),
60
83
'SwapTotal' : Grade .int (size .get ('SwapTotal' ), 512 * 1024 , 4 * (1024 ** 2 )),
61
- }
84
+ }, FOLDING_DEVICE )
62
85
63
86
def assess_memory (self ):
64
87
meminfo = self .data .get ('memory' )
65
88
if meminfo :
66
- return {
89
+ return self . fold ( {
67
90
'devices' : self .assess_memory_devices (meminfo .get ('devices' )),
68
91
'size' : self .assess_memory_size (meminfo .get ('size' )),
69
- }
92
+ }, FOLDING_SUBSYSTEM )
70
93
71
94
def assess_system (self ):
72
95
cpuinfo = extract (self .data , ['cpu' , 'info' ])
73
96
if cpuinfo :
74
- return {
97
+ return self . fold ( {
75
98
'Hypervisor vendor' : Grade .fact (cpuinfo .get ('Hypervisor vendor' ), False ),
76
99
'Virtualization type' : Grade .fact (cpuinfo .get ('Hypervisor vendor' ), False ),
77
- }
100
+ }, FOLDING_SUBSYSTEM )
78
101
79
102
def assess_netdev (self , netdev ):
80
103
netdevinfo = extract (self .data , ['net' , netdev ])
81
104
queues = sum (
82
105
len (extract (netdevinfo , ['queues' , x ])) for x in ('rx' , 'rxtx' ))
83
106
buffers = netdevinfo .get ('buffers' ) or {}
84
- return {
107
+ return self . fold ( {
85
108
'queues' : Grade .int (queues , 2 , 8 ),
86
109
'driver' : {
87
110
'mlx5_core' : 10 , # 7500 mbit/s
@@ -94,21 +117,27 @@ def assess_netdev(self, netdev):
94
117
'e1000' : 3 , # 50 mbit/s
95
118
'r8169' : 1 , 'ATL1E' : 1 , '8139too' : 1 , # real trash, you should never use it
96
119
}.get (netdevinfo .get ('driver' ).get ('driver' ), 2 ),
97
- 'buffers' : {
120
+ 'buffers' : self . fold ( {
98
121
'cur' : Grade .int (buffers .get ('cur' ), 256 , 4096 ),
99
122
'max' : Grade .int (buffers .get ('max' ), 256 , 4096 ),
100
- },
101
- }
123
+ }, FOLDING_DEVICE )
124
+ }, FOLDING_DEVICE )
102
125
103
126
def assess_disk (self , disk ):
104
127
diskinfo = extract (self .data , ['disk' , disk ])
105
- return {
128
+ return self . fold ( {
106
129
'type' : Grade .str (diskinfo .get ('type' ), ['SDD' ], ['HDD' ]),
107
130
# 50Gb - good, 1Tb - good enough
108
131
'size' : Grade .int (diskinfo .get ('size' ), 50 * (1000 ** 3 ), 1000 ** 4 ),
109
- }
132
+ }, FOLDING_DEVICE )
110
133
111
134
def __assess (self , func , key ):
112
135
items = self .data .get (key )
113
136
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