__init__.py 5.49 KB
Newer Older
Mario Hock's avatar
Mario Hock committed
1
2
3
4
5
6
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import psutil
import time

7
8
9
10
11
12
13
14
from collections import namedtuple

import helpers

def get_time():
    """ Unified/comparable clock access """
    return time.time()

Mario Hock's avatar
Mario Hock committed
15
16
17
18
19
20
21
22
23
24

## XXX for interactive debugging only
def RELOAD():
    print ("import importlib")
    print ("importlib.reload(cpunetlog)")


MEASUREMENT_INTERVAL = 0.2


25
26
27
28

class Reading:
    ## XXX DEPRECATED
    last_measurement = None
Mario Hock's avatar
Mario Hock committed
29

30
31
32
    @classmethod
    def get_time_since_last_measurement(cls):
        """ Time since last measurement in seconds (float) """
33
34
        assert( Reading.last_measurement )
        return Reading.get_time() - Reading.last_measurement
35

Mario Hock's avatar
Mario Hock committed
36
37
    @staticmethod
    def update_last_measurement(t):
38
        Reading.last_measurement = t
Mario Hock's avatar
Mario Hock committed
39

40
    ## XXX DEPRECATED
Mario Hock's avatar
Mario Hock committed
41
42
43
44
45
46
47
    ## Exceptions
    class TaintedResultsException(Exception):
        pass


    ## ***
    def __init__(self):
48
        ## sanity check  ## XXX DEPRECATED
Mario Hock's avatar
Mario Hock committed
49
        if ( self.last_measurement ):
50
51
            if ( get_time() - self.last_measurement < 0.09 ):
                print( "WARN: time diff only:", get_time() - self.last_measurement )
Mario Hock's avatar
Mario Hock committed
52
53
54
                raise self.TaintedResultsException

        ## * measurements *
55
56
57
58
        self.timestamp = get_time()
        self.cpu_util = psutil.cpu_percent(interval=0, percpu=True)                      ## XXX
        self.cpu_times_percent = psutil.cpu_times_percent(interval=0, percpu=True)       ## XXX
        self.cpu_times = psutil.cpu_times(percpu=True)
Mario Hock's avatar
Mario Hock committed
59
60
        self.memory = psutil.virtual_memory()
        self.net_io = psutil.net_io_counters(pernic=True)
Mario Hock's avatar
Mario Hock committed
61

62
        ## store timespan for these statistics (if reasonable)  ## XXX DEPRECATED
Mario Hock's avatar
Mario Hock committed
63
        if ( self.last_measurement ):
64
            self.timespan = self.timestamp - self.last_measurement
Mario Hock's avatar
Mario Hock committed
65
66
67
68
69
70
            self.valid = True
        else:
            self.timespan = None
            self.valid = False

        ## update class variable
71
        self.update_last_measurement(self.timestamp)
Mario Hock's avatar
Mario Hock committed
72
73

    def __str__(self):
Mario Hock's avatar
Mario Hock committed
74
75
76
77
78
79
        ## •‣∘⁕∗◘☉☀★◾☞☛⦿
        return "◘ Timespan: " + str(self.timespan) +              \
                "\n◘ CPU utilization: " + str(self.cpu_util) +    \
                "\n◘ CPU times: " + str(self.cpu_times) +         \
                "\n◘ RAM: " + str(self.memory) +                  \
                "\n◘ NET: " + str(self.net_io)
Mario Hock's avatar
Mario Hock committed
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

class NetworkTraffic:
    def __init__(self, older_counters, younger_counters, timespan):
        self.total = dict()
        self.ratio = dict()

        for field in older_counters._fields:
            field_delta = getattr(younger_counters, field) - getattr(older_counters, field)

            self.total[field] = field_delta
            self.ratio[field] = field_delta / timespan

    def __str__(self):
        return "Total (bytes):" + str(self.total) + "; Ratio (bytes/s)" + str(self.ratio)



class Measurement:
    def __init__(self, reading1, reading2):
        self.r1 = reading1
        self.r2 = reading2

        ## calculate differences
        self.timespan = self.r2.timestamp - self.r1.timestamp
        self.cpu_times_percent = helpers.calculate_cpu_times_percent(self.r1.cpu_times, self.r2.cpu_times, percpu=True)
        #self.net_io_diff = helpers.calculate_element_diffs_for_dict_of_tuples(self.r1.net_io, self.r2.net_io)
        #self.net_io_rate = self._calculate_net_io_rate()
        self.net_io = self._calculate_net_io()


    def _calculate_net_io(self):
        ret = dict()

        for nic in self.r1.net_io.keys():
            ret[nic] = NetworkTraffic(self.r1.net_io[nic], self.r2.net_io[nic], self.timespan)

        return ret


    #def __str__(self):
        #return str(self.timespan) + ", " + str(self.r2.timespan)   ## XXX
        #return str(self.cpu_times_percent) + "\n" + str(self.r2.cpu_times_percent)   ## XXX


def measure(interval = MEASUREMENT_INTERVAL):
    r1 = Reading()
    time.sleep(interval)
    r2 = Reading()

    m = Measurement(r1, r2)

    return m



Mario Hock's avatar
Mario Hock committed
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
def display_cpu(measurement):
    num = 1
    for cpu in measurement.cpu_times_percent:
        print( "CPU" + str(num) + " util: " + str(100-cpu.idle) + "% (" + str(cpu.user) + "% user, " + str(cpu.system) + "% system)")
        num += 1

def desplay_network_traffic(measurement, nics = None):
    if not nics:
        nics = measurement.net_io.keys()

    for nic in nics:
        values = measurement.net_io[nic]

        print( "[" + nic + "] Sending (bytes/s): " + str(values.ratio["packets_sent"]) +
              ", Receiving (bytes/s): " + str(values.ratio["packets_recv"]) )


Mario Hock's avatar
Mario Hock committed
154
def display(measurement):
Mario Hock's avatar
Mario Hock committed
155
156
157
158
159
160
161
    nics = ("eth0", "wlan0")

    display_cpu(measurement)
    desplay_network_traffic( measurement, nics )


def displayX(measurement):
Mario Hock's avatar
Mario Hock committed
162
    nic = "eth0"
Mario Hock's avatar
Mario Hock committed
163

164
165
166
167
168
    for cpu in measurement.cpu_times_percent:
        print( ", ".join([str(x) + "%" for x in cpu]))
        print( str(100-cpu.idle) + "%, " + str(cpu.user) + "%. " + str(cpu.system) + "%")
    for nic in measurement.net_io.keys():
        print( "[" + nic + "] " + str(measurement.net_io[nic]) )
Mario Hock's avatar
Mario Hock committed
169
170

    print
Mario Hock's avatar
Mario Hock committed
171
172


173
174
175
## Takes a reading and ensures that (at least) |interval| seconds are covered.
#    NOTE: does not handle race conditions (well)
def take_reading(interval = MEASUREMENT_INTERVAL):
176
    t = interval - Reading.get_time_since_last_measurement()
177
178
179
180
181

    ## sleep if necessary
    if ( t > 0 ):
        time.sleep(t)

182
    m = Reading()
183
184
185
186
187
188
189
190
    assert(m.timespan >= interval)

    return m


## XXX TESTING
def test_loop():
    for i in range(10):
Mario Hock's avatar
Mario Hock committed
191
192
193
        display( measure() )
        time.sleep(0.5)
        print
194
195
196


## XXX TESTING
Mario Hock's avatar
Mario Hock committed
197
198
#display( measure() )
test_loop()
Mario Hock's avatar
Mario Hock committed
199