Skip to content

Instantly share code, notes, and snippets.

@not-inept
Last active March 28, 2019 20:47
Show Gist options
  • Save not-inept/364bddc4ce2fc09210649a131530a09f to your computer and use it in GitHub Desktop.
Save not-inept/364bddc4ce2fc09210649a131530a09f to your computer and use it in GitHub Desktop.
Produces a CSV with
import subprocess
import signal
import time
import sys
import csv
# This is set in the first call to run_top()
headers = []
def get_column_starts(headerStr):
global headers
# Top spaces things out evenly, which seems to be the only sane way to get
# data from columns which may contain all sorts of data
if len(headers) == 0:
headers = filter(None, headerStr.split(' '))
starts = []
begin = 0
for i in range(len(headers)):
header = headers[i]
if i == 0:
start = 0
else:
start = headerStr.find(header, begin)
starts.append(start)
begin = start + len(header)
return starts
def get_column_values(starts, columnStr):
values = []
for i in range(len(starts)):
if i == len(starts)-1:
values.append(columnStr[starts[i]:len(columnStr)].strip())
else:
values.append(columnStr[starts[i]:starts[i+1]].strip())
return values
def parse_top(out):
splitOut = out.split("\n")
# Top has five lines of output, and then headers
headerStr = splitOut[6]
starts = get_column_starts(headerStr)
parsedLines = []
for line in splitOut[7:]:
parsedLines.append(get_column_values(starts, line))
return parsedLines
def run_top():
proc = subprocess.Popen(["top","-b","-d1","-n1"],
stdout=subprocess.PIPE)
out, err = proc.communicate()
return out
killed = False
def main():
global headers
if len(sys.argv) != 2:
print("Usage is: %s <filename>" % sys.argv[0])
return
path = sys.argv[1]
first_run = True
while not killed:
parsedOut = parse_top(run_top())
now = time.time()
if first_run:
# Headers are set in the first call to run_top(), as they change per system
with open(path, 'w+') as outfile:
writer = csv.writer(outfile)
writer.writerow(["TIME"] + headers)
first_run = False
with open(path, 'a+') as outfile:
writer = csv.writer(outfile)
for line in parsedOut:
writer.writerow([now] + line)
time.sleep(1)
sys.exit(0)
def kill_handler(sig, frame):
print('Terminating...')
global killed
killed = True
signal.signal(signal.SIGINT, kill_handler)
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment