m-chrzan.xyz
aboutsummaryrefslogtreecommitdiff
path: root/src/main/resources/pl/edu/mimuw/cloudatlas/fetcher/data_fetcher.py
blob: d53ce05928c29bd6b8755c1fc870076b956a5b34 (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
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
import json
import sys
import time
import psutil
import platform
import socket
import configparser
import statistics
import urllib.request

# Pipe
pipe = None

# Attribute params
initial_delay = 0
collection_interval = 1
averaging_period = 1
averaging_method = ""

"""
    Attributes

    the average CPU load (over all cores) as cpu_load
    the free disk space (in bytes) as free_disk
    the total disk space (in bytes) as total_disk
    the free RAM (in bytes) as free_ram
    the total RAM (in bytes) as total_ram
    the free swap (in bytes) as free_swap
    the total swap (in bytes) as total_swap
    the number of active processes as num_processes
    the number of CPU cores as num_cores
    the kernel version as kernel_ver
    the number of users logged in as logged_users
    a set of up to three DNS names of the machine dns_names

"""


def get_avg_load():
    load_percentages = psutil.cpu_percent(interval=averaging_period, percpu=True)

    if averaging_method == "arithmetic":
        return statistics.mean(load_percentages)
    elif averaging_method == "geometric":
        return statistics.geometric_mean(load_percentages)
    elif averaging_method == "harmonic":
        return statistics.harmonic_mean(load_percentages)
    elif averaging_method == "median":
        return statistics.median(load_percentages)
    else:
        raise RuntimeError("Avg CPU load error")


def get_data():
    avg_load = get_avg_load()
    free_disk = psutil.disk_usage("/").free
    total_disk = psutil.disk_usage("/").total
    free_ram = psutil.virtual_memory().available
    total_ram = psutil.virtual_memory().total
    free_swap = psutil.swap_memory().free
    total_swap = psutil.swap_memory().total
    num_processes = len(psutil.pids())
    num_cores = psutil.cpu_count(False)
    kernel_ver = platform.release()
    logged_users = len(psutil.users())

    try:
        external_ip = urllib.request.urlopen('https://ident.me').read().decode('utf8')
        hostname = socket.gethostbyaddr(external_ip)
        dns_names = ([hostname[0]] + hostname[1])[:3]
    except Exception as e:
        pass
    else:
        dns_names = []

    sys.stdout.write("[{},{},{},{},{},{},{},{},{},{},{},{}]\n".format(
        avg_load,
        free_disk,
        total_disk,
        free_ram,
        total_ram,
        free_swap,
        total_swap,
        num_processes,
        num_cores,
        kernel_ver,
        logged_users,
        json.dumps(dns_names))
    )

    sys.stdout.flush()


def check_averaging_method(averaging_method):
    averaging_methods = ["arithmetic", "geometric", "harmonic", "mean"]
    return averaging_method and averaging_method in averaging_methods


def read_config():
    global initial_delay
    global collection_interval
    global averaging_period
    global averaging_method
    config = configparser.ConfigParser()

    try:
        # check if running from source code dir
        config.read("config.ini")
    except KeyError:
        pass
    else:
        # we assume that it's running as subprocess from Fetcher.java
        # we assume working dir to be CloudAtlas root
        # because gradle seems to put it this way
        config.read("src/main/resources/pl/edu/mimuw/cloudatlas/fetcher/config.ini")

    initial_delay = int(config["AttributeParams"]["initialDelay"])
    collection_interval = int(config["AttributeParams"]["collectionInterval"])
    averaging_period = int(config["AttributeParams"]["averagingPeriod"])
    averaging_method = config["AttributeParams"]["averagingMethod"]

    if not check_averaging_method(averaging_method):
        raise ValueError("Incorrect averaging method")
    elif collection_interval < averaging_period:
        raise ValueError("Collection interval smaller than averaging period")


if __name__ == '__main__':
    read_config()

    time.sleep(initial_delay)
    while True:
        get_data()
        time.sleep(collection_interval - averaging_period)