summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lumens <clumens@redhat.com>2011-05-10 09:24:26 -0400
committerChris Lumens <clumens@redhat.com>2011-05-16 14:07:48 -0400
commit4e5940ffc640f10d6901f6582db50899d58bc6c2 (patch)
tree10b42eba77625adc5920331df86bfbbd00f14e16
parentf159bd6b1be7e2baef3b20633b38863817d7f410 (diff)
downloadanaconda-4e5940ffc640f10d6901f6582db50899d58bc6c2.tar.gz
anaconda-4e5940ffc640f10d6901f6582db50899d58bc6c2.tar.xz
anaconda-4e5940ffc640f10d6901f6582db50899d58bc6c2.zip
Add a python program to record memory usage during installation.
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.
-rw-r--r--anaconda.spec.in1
-rw-r--r--data/systemd/Makefile.am2
-rw-r--r--data/systemd/instperf.service8
-rw-r--r--data/systemd/loader.service4
-rw-r--r--scripts/Makefile.am5
-rwxr-xr-xscripts/instperf58
-rw-r--r--scripts/instperf.p15
7 files changed, 89 insertions, 4 deletions
diff --git a/anaconda.spec.in b/anaconda.spec.in
index e655c427e..707366fce 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 cebbd2ca5..465469518 100644
--- a/data/systemd/Makefile.am
+++ b/data/systemd/Makefile.am
@@ -18,7 +18,7 @@
# Author: Chris Lumens <clumens@redhat.com>
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 000000000..b843872e3
--- /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 d80806781..5d2b0ac0d 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 329a2fc6f..7b843a066 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 000000000..f0f53cc9e
--- /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(1)
diff --git a/scripts/instperf.p b/scripts/instperf.p
new file mode 100644
index 000000000..078a5a140
--- /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