This program only runs during installation if the "debug" command line option is provided. It writes out a /tmp/memory.dat file which can be copied off the system and processed with the provided gnuplot script to display a graph. --- anaconda.spec.in | 1 + data/systemd/Makefile.am | 2 +- data/systemd/instperf.service | 8 +++++ data/systemd/loader.service | 4 +- scripts/Makefile.am | 5 +++- scripts/instperf | 58 +++++++++++++++++++++++++++++++++++++++++ scripts/instperf.p | 15 ++++++++++ 7 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 data/systemd/instperf.service create mode 100755 scripts/instperf create mode 100644 scripts/instperf.p diff --git a/anaconda.spec.in b/anaconda.spec.in index e655c42..707366f 100644 --- a/anaconda.spec.in +++ b/anaconda.spec.in @@ -209,6 +209,7 @@ update-desktop-database &> /dev/null || : %doc docs/anaconda-release-notes.txt /lib/systemd/system/* /lib/udev/rules.d/70-anaconda.rules +%{_bindir}/instperf %{_sbindir}/anaconda %{_sbindir}/logpicker %ifarch i386 i486 i586 i686 x86_64 diff --git a/data/systemd/Makefile.am b/data/systemd/Makefile.am index cebbd2c..4654695 100644 --- a/data/systemd/Makefile.am +++ b/data/systemd/Makefile.am @@ -18,7 +18,7 @@ # Author: Chris Lumens <clumens@xxxxxxxxxx> systemddir = /lib/systemd/system -dist_systemd_DATA = anaconda-shell.service anaconda.target loader.service tmp.mount +dist_systemd_DATA = anaconda-shell.service anaconda.target loader.service instperf.service tmp.mount MAINTAINERCLEANFILES = Makefile.in diff --git a/data/systemd/instperf.service b/data/systemd/instperf.service new file mode 100644 index 0000000..b843872 --- /dev/null +++ b/data/systemd/instperf.service @@ -0,0 +1,8 @@ +[Unit] +Description=anaconda performance monitor +Before=loader.service + +[Service] +WorkingDirectory=/ +ExecStart=/usr/bin/instperf +ConditionKernelCommandLine=debug diff --git a/data/systemd/loader.service b/data/systemd/loader.service index d808067..5d2b0ac 100644 --- a/data/systemd/loader.service +++ b/data/systemd/loader.service @@ -1,7 +1,7 @@ [Unit] Description=The anaconda loader -Requires=dbus.service udev.service rsyslog.service tmp.mount -After=dbus.service udev.service rsyslog.service tmp.mount +Requires=dbus.service udev.service rsyslog.service tmp.mount instperf.service +After=dbus.service udev.service rsyslog.service tmp.mount instperf.service [Service] Environment=HOME=/root MALLOC_CHECK_=2 MALLOC_PERTURB_=204 PATH=/usr/bin:/bin:/sbin:/usr/sbin:/mnt/sysimage/bin:/mnt/sysimage/usr/bin:/mnt/sysimage/usr/sbin:/mnt/sysimage/sbin PYTHONPATH=/tmp/updates TERM=linux diff --git a/scripts/Makefile.am b/scripts/Makefile.am index 329a2fc..7b843a0 100644 --- a/scripts/Makefile.am +++ b/scripts/Makefile.am @@ -25,9 +25,12 @@ dist_scripts_DATA = mk-images.* pyrc.py dist_noinst_SCRIPTS = getlangnames.py upd-bootimage upd-initrd upd-kernel \ makeupdates -dist_bin_SCRIPTS = analog anaconda-cleanup +dist_bin_SCRIPTS = analog anaconda-cleanup instperf stage2scriptsdir = $(datadir)/$(PACKAGE_NAME) dist_stage2scripts_SCRIPTS = restart-anaconda +miscdir = $(datadir)/$(PACKAGE_NAME) +dist_misc_DATA = instperf.p + MAINTAINERCLEANFILES = Makefile.in diff --git a/scripts/instperf b/scripts/instperf new file mode 100755 index 0000000..3999834 --- /dev/null +++ b/scripts/instperf @@ -0,0 +1,58 @@ +#!/usr/bin/python + +import logging +from string import split +from subprocess import Popen, PIPE +import time + +# grab the top five memory consuming processes, returning them in a string of +# of the format: +# +# name1:kB1,name2:kB2,...,name5:kB5 +def topProcesses(): + output = Popen(["ps", "-eo", "comm,rss", "--sort", "-rss", "--no-headers"], stdout=PIPE).communicate()[0] + top5 = output.split("\n")[:5] + return ",".join(map(lambda (a,b): a+":"+b, map(split, top5))) + +def logit(): + buffers = 0 + cached = 0 + memTotal = 0 + memFree = 0 + swapTotal = 0 + swapFree = 0 + + global mem_logger + + with open("/proc/meminfo") as f: + for line in f.readlines(): + if line.startswith("Buffers:"): + buffers = line.split()[1] + elif line.startswith("Cached:"): + cached = line.split()[1] + elif line.startswith("MemTotal:"): + memTotal = line.split()[1] + elif line.startswith("MemFree:"): + memFree = line.split()[1] + elif line.startswith("SwapTotal:"): + swapTotal = line.split()[1] + elif line.startswith("SwapFree:"): + swapFree = line.split()[1] + + d = {"memUsed": int(memTotal)-int(memFree)-int(cached)-int(buffers), + "swapUsed": int(swapTotal)-int(swapFree), + "procs": topProcesses()} + + mem_logger.debug("%(memUsed)d %(swapUsed)d %(procs)s" % d) + +mem_logger = logging.getLogger("memLog") +mem_logger.setLevel(logging.DEBUG) + +handler = logging.FileHandler("/tmp/memory.dat") +handler.setLevel(logging.DEBUG) +handler.setFormatter(logging.Formatter("%(asctime)s %(message)s", "%H:%M:%S")) +mem_logger.addHandler(handler) + +while True: + logit() + time.sleep(10) diff --git a/scripts/instperf.p b/scripts/instperf.p new file mode 100644 index 0000000..078a5a1 --- /dev/null +++ b/scripts/instperf.p @@ -0,0 +1,15 @@ +# This script processes a memory.dat file as generated by instperf during +# installation and writes out a graph to memusage.png. +set terminal png size 1024,768 +set output "memusage.png" +set title "anaconda Memory Usage" +set xlabel "Time" +set xtics rotate +set xdata time +set timefmt "%H:%M:%S" +set ylabel "Memory Used (in KB)\n(Total-Free-Buffers-Cached)" +set format y "%.0f" +set grid + +plot "memory.dat" using 1:2 title "Memory" with lines, \ + "memory.dat" using 1:3 title "Swap" with lines -- 1.7.4.1 _______________________________________________ Anaconda-devel-list mailing list Anaconda-devel-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/anaconda-devel-list