File: cpustat.py

package info (click to toggle)
python-pure-python-adb 0.3.0-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,500 kB
  • sloc: python: 2,597; makefile: 8; sh: 1
file content (138 lines) | stat: -rw-r--r-- 4,700 bytes parent folder | download
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
131
132
133
134
135
136
137
138
import re
import time

from ppadb.plugins import Plugin
from ppadb.utils.logger import AdbLogging

logger = AdbLogging.get_logger(__name__)

class TotalCPUStat:
    def __init__(self, user, nice, system, idle, iowait, irq, softirq, stealstolen, guest, guest_nice):
        self.user = user
        self.nice = nice
        self.system = system
        self.idle = idle
        self.iowait = iowait
        self.irq = irq
        self.softirq = softirq
        self.stealstolen = stealstolen
        self.guest = guest
        self.guest_nice = guest_nice

    def total(self):
        return self.user + self.nice + self.system + self.idle + self.iowait + self.irq + self.softirq + self.stealstolen + self.guest + self.guest_nice

    def __add__(self, other):
        summary = TotalCPUStat(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

        summary.user = self.user + other.user
        summary.nice = self.nice + other.nice
        summary.system = self.system + other.system
        summary.idle = self.idle + other.idle
        summary.iowait = self.iowait + other.iowait
        summary.irq = self.irq + other.irq
        summary.softirq = self.softirq + other.softirq
        summary.stealstolen = self.stealstolen + other.stealstolen
        summary.guest = self.guest + other.guest
        summary.guest_nice = self.guest_nice + other.guest_nice

        return summary

    def __sub__(self, other):
        result = TotalCPUStat(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)

        result.user = self.user - other.user
        result.nice = self.nice - other.nice
        result.system = self.system - other.system
        result.idle = self.idle - other.idle
        result.iowait = self.iowait - other.iowait
        result.irq = self.irq - other.irq
        result.softirq = self.softirq - other.softirq
        result.stealstolen = self.stealstolen - other.stealstolen
        result.guest = self.guest - other.guest
        result.guest_nice = self.guest_nice - other.guest_nice

        return result

    def __str__(self):
        attrs = vars(self)
        return ', '.join("%s: %s" % item for item in attrs.items())


class ProcessCPUStat:
    def __init__(self, name, utime, stime):
        self.name = name
        self.utime = utime
        self.stime = stime

    def __add__(self, other):
        summary = ProcessCPUStat(self.name, 0, 0)
        summary.utime = self.utime + other.utime
        summary.stime = self.stime + other.stime
        return summary

    def __sub__(self, other):
        result = ProcessCPUStat(self.name, 0, 0)
        result.utime = self.utime - other.utime
        result.stime = self.stime - other.stime
        return result

    def __str__(self):
        attrs = vars(self)
        return ', '.join("%s: %s" % item for item in attrs.items())

    def total(self):
        return self.utime + self.stime


class CPUStat(Plugin):
    total_cpu_pattern = re.compile(
        r"cpu\s+([\d]+)\s([\d]+)\s([\d]+)\s([\d]+)\s([\d]+)\s([\d]+)\s([\d]+)\s([\d]+)\s([\d]+)\s([\d]+)\s")

    def cpu_times(self):
        return self.get_total_cpu()

    def cpu_percent(self, interval=1):
        cpu_times_start = self.cpu_times()
        time.sleep(interval)
        cpu_times_end = self.cpu_times()

        diff = cpu_times_end - cpu_times_start
        return round(((diff.user + diff.system) / diff.total()) * 100, 2)

    def cpu_count(self):
        result = self.shell('ls /sys/devices/system/cpu')
        match = re.findall(r'cpu[0-9+]', result)
        return len(match)

    def get_total_cpu(self):
        result = self.shell('cat /proc/stat')
        match = self.total_cpu_pattern.search(result)
        if not match and len(match.groups()) != 10:
            logger.error("Can't get the total cpu usage from /proc/stat")
            return None

        return TotalCPUStat(*map(lambda x: int(x), match.groups()))

    def get_pid_cpu(self, pid):
        result = self.shell('cat /proc/{}/stat'.format(pid)).strip()

        if "No such file or directory" in result:
            return ProcessCPUStat("", 0, 0)
        else:
            items = result.split()
            return ProcessCPUStat(items[1], int(items[13]), int(items[14]))

    def get_all_thread_cpu(self, pid):
        result = self.shell("ls /proc/{}/task".format(pid))
        tids = list(map(lambda line: line.strip(), result.split("\n")))

        thread_result = {}
        for tid in tids:
            result = self.shell("cat /proc/{}/task/{}/stat".format(pid, tid))

            if "No such file or directory" not in result:
                items = result.split()
                thread_result[tid] = ProcessCPUStat(items[1], int(items[13]), int(items[14]))

        return thread_result