Last active
June 6, 2020 15:36
-
-
Save spacelatte/e95293a41518d5519f96bf6d986fd133 to your computer and use it in GitHub Desktop.
procparse.py: parse linux /proc filesystem and expose as API
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
import io, re, os, sys, time, json, socket, threading | |
def reader(file): | |
with open("/proc/{}".format(file)) as file: | |
return file.read().split("\n") | |
return [] | |
def generic_parser(file): | |
return { | |
p[0]: float(p[1]) | |
for p in [ | |
re.split(r"[\0:=\s]+", line) | |
for line in reader(file) | |
if len(line) > 0 | |
] | |
} | |
def flatten(nobj, *args, sep=".", parent=None, final=None, depth=-1, **kwargs): | |
if parent is None: | |
parent = tuple() | |
if final is None: | |
final = dict() | |
#print(parent, final) | |
if depth == 0: | |
final.update({ parent: nobj }) | |
return nobj | |
elif isinstance(nobj, dict): | |
for k, v in nobj.items(): | |
flatten(v, parent=parent+(k,), final=final, depth=depth-1) | |
elif isinstance(nobj, list): | |
for i, j in enumerate(nobj): | |
flatten(j, parent=parent+(i,), final=final, depth=depth-1) | |
else: | |
final.update({ parent: nobj }) | |
return nobj | |
#print("upd", len(parent), upd) | |
return { sep.join([ str(i) for i in k ]): v for k, v in final.items() } | |
diskstatstab = [ | |
"empty", | |
"major_number", | |
"minor_mumber", | |
"device_name", | |
"reads_completed_successfully", | |
"reads_merged", | |
"sectors_read", | |
"time_spent_reading_ms", | |
"writes_completed", | |
"writes_merged", | |
"sectors_written", | |
"time_spent_writing_ms", | |
"IOs_currently_in_progress", | |
"time_spent_doing_IOs_ms", | |
"weighted_time_spent_doing_IOs_ms", | |
"discards_completed_successfully", | |
"discards_merged", | |
"sectors_discarded", | |
"time_spent_discarding", | |
] | |
loadavgtab = [ | |
"01mins", | |
"05mins", | |
"15mins", | |
"proc-thread", | |
"lastpid", | |
] | |
stattab = [ | |
"user", | |
"nice", | |
"system", | |
"idle", | |
"iowait", | |
"irq", | |
"softirq", | |
"steal", | |
"guest", | |
"guest_nice", | |
"10th_col", | |
"11th_col", | |
] | |
parsertab = { | |
"vmstat": generic_parser, | |
"meminfo": generic_parser, | |
"loadavg": (lambda x: { | |
loadavgtab[i]: j | |
for i, j in enumerate(reader(x)[0].split(" ")) | |
}), | |
"diskstats": (lambda x: { | |
p[3]: { | |
diskstatstab[i]: j | |
for i, j in enumerate(p) | |
if i is not 3 and len(j) > 0 | |
} | |
for p in [ | |
re.split(r"\s+", disk) | |
for disk in reader(x) | |
if len(disk) > 0 | |
] | |
}), | |
"stat": (lambda x: { | |
p[0]: { | |
stattab[i]: float(j) | |
for i, j in enumerate(p[1:]) | |
} | |
for p in [ | |
re.split(r"[\0:=\s]+", line) | |
for line in reader(x) | |
if len(line) > 0 | |
] if p[0] not in [ "intr" ] | |
}), | |
"net/netstat": (lambda x: (lambda data: { | |
t[0]: { | |
data[(i-1 if i > 0 else 0)][j+1]: v | |
for j, v in enumerate(t[1:]) | |
} for i, t in enumerate(data) | |
})([ | |
re.split(r"[\0:=\s]+", line) | |
for line in reader(x) | |
if len(line) > 0 | |
])), | |
} | |
get_bulk_data = lambda: { | |
file.replace("/", "_"): parsertab[file](file) for file in [ | |
"net/netstat", | |
#"diskstats", | |
#"mdstat", | |
#"schedstat", | |
#"stat", | |
#"timerstats", | |
"diskstats", | |
"meminfo", | |
"loadavg", | |
"vmstat", | |
"stat", | |
] | |
} | |
def publish(baseurl="https://test-c59fa.firebaseio.com"): | |
import urllib.request | |
url = "{}/{}/{}.json?print=silent".format( | |
baseurl, | |
socket.gethostname().replace(".", "-"), | |
int(time.time()), | |
) | |
request = lambda *args, **kwargs: ( | |
#print(kwargs["data"].decode()), | |
json.loads(urllib.request.urlopen(urllib.request.Request(*args, **kwargs)).read().decode()), | |
)[-1] | |
try: | |
resp = request(url, | |
method="PUT", | |
headers={ | |
"content-type": "application/json" | |
}, | |
data=json.dumps(get_bulk_data(), indent='\t').encode(), | |
) | |
with open("/tmp/last.txt", "w") as file: | |
json.dump(flatten(resp), file, indent='\t') | |
#print(json.dumps(flatten(resp), indent='\t')) | |
except Exception as e: | |
#print(e) | |
pass | |
def main(args): | |
import flask | |
app = flask.Flask(__name__) | |
app.add_url_rule("/", "root", get_bulk_data) | |
return app.run( | |
debug=False, | |
host="0.0.0.0", | |
port=8000, | |
) | |
if __name__ == '__main__': | |
sys.exit(main(sys.argv[1:])) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment