-
Notifications
You must be signed in to change notification settings - Fork 0
/
metrics.py
98 lines (84 loc) · 2.98 KB
/
metrics.py
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
import subprocess
from prometheus_client import Gauge, start_http_server
ENC = "utf-8"
HOSTNAME = (subprocess.check_output("hostname").splitlines()[0]).decode(ENC)
TOP_CMD = "top -bn1".split()
DF_CMD = "df"
INVALID_CHARS = [
"/",
"\\",
"_",
]
def _sanitize(string: str) -> str:
for char in string:
if char in INVALID_CHARS:
return _sanitize(string.replace(char, "."))
return string
def _get_metric_name(subtype: str, unit: str, subunit: str = None) -> str:
subtype = _sanitize(subtype)
unit = _sanitize(unit)
name = f"{HOSTNAME}_{subtype}_{unit}"
if subunit:
name += f"_{subunit}"
return name
def _get_top_data() -> dict:
output = subprocess.check_output(TOP_CMD)
result = {}
for line in output.splitlines():
decoded = line.decode(ENC)
if "%Cpu(s)" in decoded:
print(f"Found CPU line: {decoded}")
vals = decoded.split(",")
for val in vals:
measurement = val.split()
unit = measurement[-1]
measure = float(measurement[-2])
metric = _get_metric_name("cpu", unit)
result[metric] = measure
elif "MiB" in decoded:
print(f"Found Memory line: {decoded}")
mem_type = decoded.split()[1].replace(":", "").lower()
vals = decoded.split(",")
for val in vals:
measurement = val.split()
unit = measurement[-1]
measure = measurement[-2]
metric = _get_metric_name(mem_type, unit)
if measure.lower() != "avail":
result[metric] = measure
elif "Tasks" in decoded:
print(f"Found tasks line: {decoded}")
vals = decoded.split(",")
for val in vals:
measurement = val.split()
unit = measurement[-1]
measure = measurement[-2]
metric = _get_metric_name("tasks", unit)
result[metric] = measure
return result
def _get_df_data() -> dict:
output = subprocess.check_output(DF_CMD)
result = {}
for line in output.splitlines():
decoded = line.decode(ENC)
if "Filesystem" not in decoded:
columns = decoded.split()
filesystem = columns[0]
used = int(columns[2])
available = int(columns[3])
total = used + available
percentage = used / total
result[
_get_metric_name(subtype="filesystem", unit=filesystem, subunit="used")
] = used
result[
_get_metric_name(subtype="filesystem", unit=filesystem, subunit="free")
] = available
result[
_get_metric_name(subtype="filesystem", unit=filesystem, subunit="perc")
] = percentage
return result
if __name__ == "__main__":
result = _get_df_data()
for key in result.keys():
print(f"{key}:{result[key]}")