Browse Source

Allow for intermediate plot generation

check-vt100
Aleksander Kiryk 4 years ago committed by Aleksander Kiryk
parent
commit
8cdc39c5bd
  1. 48
      graph.py
  2. 26
      sargraph.py
  3. 56
      watch.py

48
graph.py

@ -74,14 +74,14 @@ def g(command):
# Plot a single column of values from data.txt
def plot(ylabel, title, name, column):
def plot(ylabel, title, session, column):
g(f"set ylabel '{ylabel}'")
g(f"set title '{title}'")
g(f"plot '{name}.txt' using 1:{column}:{column} title 'cpu' with boxes palette")
g(f"plot '{session}.txt' using 1:{column}:{column} title 'cpu' with boxes palette")
# Read additional information from 'data.txt' comments
def read_comments(name):
def read_comments(session):
global START_DATE
global END_DATE
global AVERAGE_LOAD
@ -95,7 +95,7 @@ def read_comments(name):
global CPU_NAME
global DURATION
with open(f"{name}.txt", "r") as f:
with open(f"{session}.txt", "r") as f:
for line in f:
value = None
@ -156,18 +156,34 @@ def read_comments(name):
AVERAGE_LOAD = value
try:
if os.environ["SARGRAPH_OUTPUT_TYPE"] == "svg":
OUTPUT_TYPE="svg"
OUTPUT_EXT="svg"
except:
pass
def graph(session, fname='plot.png'):
global OUTPUT_TYPE
global OUTPUT_EXT
global labels
def graph(name):
global gnuplot
read_comments(name)
labels = []
if "SARGRAPH_OUTPUT_TYPE" in os.environ:
if os.environ["SARGRAPH_OUTPUT_TYPE"] == "svg":
OUTPUT_TYPE="svg"
OUTPUT_EXT="svg"
elif fname.lower().endswith('.svg'):
OUTPUT_TYPE="svg"
OUTPUT_EXT="svg"
elif fname.lower().endswith('.png'):
# Otherwise leave the default png
pass
else:
print("Error: unknown graph extension.")
sys.exit(1)
# Leave just the base name
fname = fname[:-4]
read_comments(session)
gnuplot = run_process("gnuplot", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
@ -203,7 +219,7 @@ def graph(name):
g(f"set terminal {OUTPUT_TYPE} size 1200,800 background '#222222' font 'Courier-New,8'")
g(f"set output '{name}.{OUTPUT_EXT}'")
g(f"set output '{fname}.{OUTPUT_EXT}'")
g(f"set multiplot layout {NUMBER_OF_PLOTS},1 title \"\\n\\n\\n\"")
@ -231,9 +247,9 @@ def graph(name):
g("set object rectangle from graph 0, graph 0 to graph 2, graph 2 behind fillcolor rgb '#111111' fillstyle solid noborder")
g(f"set object rectangle from '{START_DATE.replace(' ', '-')}', 0 to '{END_DATE.replace(' ', '-')}', 100 behind fillcolor rgb '#000000' fillstyle solid noborder")
plot("cpu % load (user)", f"cpu load (average = {AVERAGE_LOAD:.2f} %)", name, 2)
plot("ram % usage", f"ram usage (max = {MAX_USED_RAM:.2f} GB)", name, 3)
plot(f"{NAME_FS}'", f"{NAME_FS} usage (max = {MAX_USED_FS:.2f} MB)", name, 4)
plot("cpu % load (user)", f"cpu load (average = {AVERAGE_LOAD:.2f} %)", session, 2)
plot("ram % usage", f"ram usage (max = {MAX_USED_RAM:.2f} GB)", session, 3)
plot(f"{NAME_FS}'", f"{NAME_FS} usage (max = {MAX_USED_FS:.2f} MB)", session, 4)
g("unset multiplot")
g("unset output")

26
sargraph.py

@ -79,7 +79,10 @@ elif cmd[0] == "stop":
except:
print("Warning: cannot find pid.")
gpid = -1
p = subprocess.Popen(["screen", "-S", sid, "-X", "stuff", "q\n"])
if len(cmd) >= 2 and cmd[1] == "none":
p = subprocess.Popen(["screen", "-S", sid, "-X", "stuff", "command:b\n"])
else:
p = subprocess.Popen(["screen", "-S", sid, "-X", "stuff", "command:q\n"])
while p.poll() is None:
time.sleep(0.1)
if gpid == -1:
@ -89,9 +92,6 @@ elif cmd[0] == "stop":
#print("Waiting for pid %d" % gpid)
while pid_running(gpid):
time.sleep(0.25)
import graph
graph.graph(sid)
elif cmd[0] == "label":
# Check if the label name was provided
if len(cmd) < 2:
@ -100,12 +100,24 @@ elif cmd[0] == "label":
label = cmd[1]
print(f"Adding label '{label}' to sargraph session '{sid}'.")
p = subprocess.Popen(["screen", "-S", sid, "-X", "stuff", f"{label}\n"])
p = subprocess.Popen(["screen", "-S", sid, "-X", "stuff", f"label:{label}\n"])
while p.poll() is None:
time.sleep(0.1)
elif cmd[0] == 'save':
print(f"Saving graph from session '{sid}'.")
if len(cmd) < 2:
fname = ''
else:
fname = cmd[1]
p = subprocess.Popen(["screen", "-S", sid, "-X", "stuff", f"command:s:{fname}\n"])
while p.poll() is None:
time.sleep(0.1)
elif cmd[0] == 'plot':
# TODO: plot the result
pass
import graph
if len(cmd) < 2:
graph.graph(sid)
else:
graph.graph(sid, cmd[1])
else:
print(f"Error: Unknown command '{cmd[0]}'")
sys.exit(1)

56
watch.py

@ -68,7 +68,7 @@ def read_table(f):
# Initialize 'data.txt' where the data is dumped
def initialize(name, machine):
def initialize(session, machine):
global TOTAL_RAM
with open("/proc/meminfo") as f:
@ -87,7 +87,7 @@ def initialize(name, machine):
cpu_name = line.replace("\n", "").split(": ")[1]
break
with open(f"{name}.txt", "w") as f:
with open(f"{session}.txt", "w") as f:
print(f"# pid: {os.getpid()}",
f"machine: {uname}",
f"cpu count: {cpus}",
@ -96,7 +96,7 @@ def initialize(name, machine):
# Add a summary comment to 'data.txt'
def summarize(name):
def summarize(session):
average_load = TOTAL_LOAD / float(SAMPLE_NUMBER)
max_used_ram = MAX_USED_RAM / 1024.0 / 1024.0
max_used_fs = MAX_USED_FS / 1024.0
@ -105,7 +105,7 @@ def summarize(name):
edt = datetime.datetime.strptime(END_DATE, '%Y-%m-%d %H:%M:%S')
delta_t = ((edt - sdt).total_seconds()) / 60.0
with open(f"{name}.txt", "a") as f:
with open(f"{session}.txt", "a") as f:
print(f"# total ram: {TOTAL_RAM:.2f} GB",
f"total disk space: {TOTAL_FS:.2f} GB",
f"max ram used: {max_used_ram:.2f} GB",
@ -117,7 +117,7 @@ def summarize(name):
# Run sar and gather data from it
def watch(name, fsdev):
def watch(session, fsdev):
global SAMPLE_NUMBER
global START_DATE
global END_DATE
@ -131,12 +131,15 @@ def watch(name, fsdev):
global die
# Was a graph alreay produced by save command from sargraph?
dont_plot = False
my_env = os.environ
my_env["S_TIME_FORMAT"] = "ISO"
p = run_process("sar", "-F", "-u", "-r", "1", stdout=subprocess.PIPE, env=my_env)
machine = p.stdout.readline().decode()
initialize(name, machine)
initialize(session, machine)
p.stdout.readline()
signal.signal(signal.SIGTERM, kill_handler)
@ -151,13 +154,32 @@ def watch(name, fsdev):
now = datetime.datetime.now()
if sys.stdin in rlist:
label_line = sys.stdin.readline().replace("\n", "")
if label_line == "q":
die = 1
break
with open(f"{name}.txt", "a") as f:
timestamp = now.strftime("%Y-%m-%d-%H:%M:%S")
print(f"# {timestamp} label: {label_line}", file=f)
if label_line.startswith("command:"):
label_line = label_line[len("command:"):]
if label_line == "q":
die = 1
break
elif label_line.startswith("s:"):
label_line = label_line[len("s:"):]
dont_plot = True
if label_line != "none":
import graph
summarize(session)
if not label_line:
graph.graph(session)
else:
graph.graph(session, label_line)
elif label_line == "b":
dont_plot = True
die = 1
break
elif label_line.startswith('label:'):
label_line = label_line[len('label:'):]
with open(f"{session}.txt", "a") as f:
timestamp = now.strftime("%Y-%m-%d-%H:%M:%S")
print(f"# {timestamp} label: {label_line}", file=f)
if (p.stdout not in rlist):
continue
@ -200,7 +222,7 @@ def watch(name, fsdev):
END_DATE = date + " " + daytime
timestamp = date + "-" + daytime
with open(f"{name}.txt", "a") as f:
with open(f"{session}.txt", "a") as f:
print(timestamp,
cpu_data['%user'][0],
ram_data['%memused'][0],
@ -214,4 +236,8 @@ def watch(name, fsdev):
time.sleep(1)
sys.exit(0)
summarize(name)
summarize(session)
if not dont_plot:
import graph
graph.graph(session)

Loading…
Cancel
Save