summaryrefslogtreecommitdiffstats
path: root/vstf/vstf/agent/perf/sar.py
blob: c4688c9c830df00ec81c232228308a90d93a4777 (plain)
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
"""
Created on 2015-8-6

@author: y00228926
"""
import subprocess
import logging
import time
import os
from signal import SIGINT

from vstf.common.utils import check_output, my_popen, kill_by_name
from vstf.agent.env.basic import collect

LOG = logging.getLogger(__name__)


class Sar(object):
    def __init__(self):
        self.sar_cmd_str = "sar -u %(interval)s"
        self.child_process = {}

    def start(self, interval=2):
        cmd = self.sar_cmd_str % {'interval': interval}
        child = my_popen(cmd.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        time.sleep(1)
        if child.poll() is not None:
            print child.poll()
            raise Exception("start vnstat error, vnstat is not running")
        self.child_process[child.pid] = child
        return child.pid

    def stop(self, pid):
        assert pid in self.child_process
        os.kill(pid, SIGINT)
        process = self.child_process.pop(pid)
        out = process.stdout.read()
        process.wait()
        data = {'raw_data': out, 'tool': 'sar', 'type': 'cpu'}
        cpu_info = collect.Collect().collect_host_info()[1]
        cpu_num = cpu_info['CPU INFO']['CPU(s)']
        cpu_mhz = cpu_info['CPU INFO']['CPU MHz']
        data.update({'cpu_num': float(cpu_num), 'cpu_mhz': float(cpu_mhz)})
        return data

    def process(self, raw):
        lines = raw.splitlines()
        # print lines
        head = lines[2].split()[3:]
        average = lines[-1].split()[2:]
        data = {}
        for h, d in zip(head, average):
            data[h.strip('%')] = float(d)
        cpu_num = check_output('cat /proc/cpuinfo  | grep processor | wc -l', shell=True).strip()
        data.update({'cpu_num': int(cpu_num)})
        return data

    def clean(self):
        for _, process in self.child_process.items():
            process.kill()
            process.wait()
        self.child_process = {}
        return True

    def force_clean(self):
        LOG.info("%s %s start", self.__class__, self.force_clean.__name__)
        kill_by_name("sar")
        self.child_process = {}
        return True

if __name__ == '__main__':
    logging.basicConfig(level=logging.DEBUG)
    q = Sar()
    pid = q.start()
    time.sleep(10)
    raw = q.stop(pid)
    print raw
    print q.process(raw['raw_data'])