-
Notifications
You must be signed in to change notification settings - Fork 72
Expand file tree
/
Copy pathserver.py
More file actions
130 lines (114 loc) · 5.69 KB
/
server.py
File metadata and controls
130 lines (114 loc) · 5.69 KB
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# coding=utf-8
import argparse
import os
import shutil
from six import print_
from netutils_linux_hardware.cpu import CPU
from netutils_linux_hardware.disk import Disk
from netutils_linux_hardware.folding import Folding
from netutils_linux_hardware.memory import Memory
from netutils_linux_hardware.net import Net
from netutils_linux_hardware.system import System
from netutils_linux_hardware.yaml_tools import dict2yaml
class Server(object):
""" Single entry point for --collect, --rate, --show """
args = None
commands = ['--collect', '--rate', '--show', '--help']
subsystems = {
'net': Net,
'cpu': CPU,
'system': System,
'memory': Memory,
'disk': Disk,
}
def __init__(self):
self.parser = argparse.ArgumentParser()
self.__parse_args()
self.__check_args()
self.tarball, self.directory = self.tarball_directory()
def tarball_directory(self):
""" Decision about and smart 'corrections' """
suffix = '.tar.gz'
if self.args.directory.endswith(suffix):
return self.args.directory, self.args.directory[:-7]
return (self.args.directory.rstrip('/') + suffix) if self.args.gzip else None, self.args.directory
def collect(self):
""" Save raw data to given directory """
already_exists = os.path.exists(self.directory)
if already_exists and not self.args.collect:
return
if already_exists:
shutil.rmtree(self.directory)
os.makedirs(self.directory)
os.system('server-info-collect {0}'.format(self.directory))
self.archive()
def read(self):
""" Parser of raw saved data info dictionary """
info = self.__read()
# system requires cpu because virtualization data is in lscpu output
# net requires cpu because queue count rate depends on NUMA's core count
if self.args.rate and not self.args.cpu and (self.args.system or self.args.net):
info['cpu'] = CPU(datadir=self.directory).parse()
return info
def rate(self):
""" Rater of parsed data """
info = self.read()
folding = Folding(self.args)
rates = dict()
for key, subsystem in self.subsystems.items():
if getattr(self.args, key):
rates[key] = subsystem(info, folding).rate()
return folding.fold(rates, Folding.SERVER)
def archive(self):
""" Create an archive of saved data if you need to fetch it from server """
if not self.tarball:
return
os.chdir(os.path.join(self.directory, '..'))
os.system('tar cfz {0} {1} 2>/dev/null'.format(self.tarball, self.directory))
def __read(self):
return dict(
(key, subsystem(datadir=self.directory).parse())
for key, subsystem in self.subsystems.items()
if key != 'system' and getattr(self.args, key)
)
def __parse_args(self):
default_directory = '/tmp/netutils_server_info/'
self.parser.add_argument('--directory', type=str, help="Specify a data directory or a tarball",
default=default_directory)
self.parser.add_argument('--collect', action='store_true', help='Collect the data about the server',
default=False)
self.parser.add_argument('--gzip', action='store_true', help="Compress the data", default=False)
self.parser.add_argument('--show', action='store_true', help='Shows data about the server in YAML',
default=False)
self.parser.add_argument('--rate', action='store_true', help='Rates data about the server', default=False)
self.parser.add_argument('--device', action='store_const', const=Folding.DEVICE, dest='folding',
help='Folds rates details to entire devices')
self.parser.add_argument('--subsystem', action='store_const', const=Folding.SUBSYSTEM, dest='folding',
help='Folds rates details to entire subsystems')
self.parser.add_argument('--server', action='store_const', const=Folding.SERVER, dest='folding',
help='Folds rates details to entire server')
self.parser.add_argument('--cpu', action='store_true', help='Show information about CPU', default=False)
self.parser.add_argument('--memory', action='store_true', help='Show information about RAM', default=False)
self.parser.add_argument('--net', action='store_true', help='Show information about network devices',
default=False)
self.parser.add_argument('--disk', action='store_true', help='Show information about disks', default=False)
self.parser.add_argument('--system', action='store_true',
help='Show information about system overall (rate only)', default=False)
self.args = self.parser.parse_args()
def __check_args(self):
""" Maybe they should be positional arguments, not options. But subparsers/groups are stupid """
if not any([self.args.collect, self.args.rate, self.args.show]):
print('Error: please, specify --rate, --show or --collect command')
self.parser.print_help()
exit(1)
if self.args.folding is None:
self.args.folding = Folding.NO
if not any(getattr(self.args, subsystem) for subsystem in self.subsystems):
for subsystem in self.subsystems:
setattr(self.args, subsystem, True)
def main(self):
self.collect()
if self.args.show:
print_(dict2yaml(self.read()))
elif self.args.rate:
print_(dict2yaml(self.rate()))