Skip to content

Commit

Permalink
Merge 726b423 into be9581f
Browse files Browse the repository at this point in the history
  • Loading branch information
lexover authored Mar 6, 2018
2 parents be9581f + 726b423 commit 8e5bfbb
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 13 deletions.
12 changes: 12 additions & 0 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,18 @@ To include sub-processes in the CPU and memory stats, use:

psrecord 1330 --log activity.txt --include-children

Memory on linux
------------

To record memory activity on linux system as "real memory"
better suited unique set size (USS). Uss is ths portion of
main memory (RAM) occupied by a process which is guaranteed to
be private to that process:

::

psrecord 1330 --log activity.txt --linux

Reporting issues
================

Expand Down
72 changes: 59 additions & 13 deletions psrecord/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import psutil
import time
import argparse
from sys import platform as _platform


def get_percent(process):
Expand All @@ -38,9 +39,10 @@ def get_percent(process):
return process.get_cpu_percent()


def get_memory(process):
def get_memory(process, use_uss):
try:
return process.memory_info()
memory_info = process.memory_full_info() if (use_uss) else process.memory_info()
return memory_info
except AttributeError:
return process.get_memory_info()

Expand All @@ -61,6 +63,23 @@ def all_children(pr):
return processes


def is_uss_possible():
#Test is platform linux
if (_platform == "linux" or _platform == "linux2"):
#Linux option works only with psutil version +2.6x on Linux
if (psutil.version_info >= (2, 6)):
return True
else:
print (("Warning: flag --linux ignored. Version of psutil module have"
"to be greater than 2.6 to use --linux flag. Your version is: "
"{0:d}.{1:d}").format(psutil.version_info[0], psutil.version_info[1]))
return False
else:
print (("Warning: flag --linux ignored. Your OS detected "
"as: {0:s}").format(_platform))
return False


def main():

parser = argparse.ArgumentParser(
Expand Down Expand Up @@ -90,6 +109,12 @@ def main():
'in a slower maximum sampling rate).',
action='store_true')

parser.add_argument('--linux',
help='in additional to real memory usage show unique '
'set size (USS) as more suitable to know how '
'much memory program were using.',
action='store_true')

args = parser.parse_args()

# Attach to process
Expand All @@ -106,14 +131,18 @@ def main():
pid = sprocess.pid

monitor(pid, logfile=args.log, plot=args.plot, duration=args.duration,
interval=args.interval, include_children=args.include_children)
interval=args.interval, include_children=args.include_children,
linux=args.linux)

if sprocess is not None:
sprocess.kill()


def monitor(pid, logfile=None, plot=None, duration=None, interval=None,
include_children=False):
include_children=False, linux=False):

#If flag linux true test is it possible to use this flag
if (linux):
linux = is_uss_possible()

pr = psutil.Process(pid)

Expand All @@ -122,18 +151,25 @@ def monitor(pid, logfile=None, plot=None, duration=None, interval=None,

if logfile:
f = open(logfile, 'w')
f.write("# {0:12s} {1:12s} {2:12s} {3:12s}\n".format(
f.write("# {0:12s} {1:12s} {2:12s} {3:12s}".format(
'Elapsed time'.center(12),
'CPU (%)'.center(12),
'Real (MB)'.center(12),
'Virtual (MB)'.center(12))
)
if (linux):
f.write(" {0:12s}".format(
'USS (MB)'.center(12))
)
f.write("\n")

log = {}
log['times'] = []
log['cpu'] = []
log['mem_real'] = []
log['mem_virtual'] = []
if (linux):
log['mem_uss'] = []

try:

Expand Down Expand Up @@ -163,11 +199,13 @@ def monitor(pid, logfile=None, plot=None, duration=None, interval=None,
# Get current CPU and memory
try:
current_cpu = get_percent(pr)
current_mem = get_memory(pr)
current_mem = get_memory(pr, linux)
except:
break
current_mem_real = current_mem.rss / 1024. ** 2
current_mem_virtual = current_mem.vms / 1024. ** 2
if (linux):
current_mem_uss = current_mem.uss / 1024. ** 2

# Get information for children
if include_children:
Expand All @@ -179,13 +217,18 @@ def monitor(pid, logfile=None, plot=None, duration=None, interval=None,
continue
current_mem_real += current_mem.rss / 1024. ** 2
current_mem_virtual += current_mem.vms / 1024. ** 2
if (linux):
current_mem_uss = current_mem.uss / 1024. ** 2

if logfile:
f.write("{0:12.3f} {1:12.3f} {2:12.3f} {3:12.3f}\n".format(
f.write("{0:12.3f} {1:12.3f} {2:12.3f} {3:12.3f}".format(
current_time - start_time,
current_cpu,
current_mem_real,
current_mem_virtual))
if (linux):
f.write(" {0:12.3f}".format(current_mem_uss))
f.write("\n")
f.flush()

if interval is not None:
Expand All @@ -197,6 +240,8 @@ def monitor(pid, logfile=None, plot=None, duration=None, interval=None,
log['cpu'].append(current_cpu)
log['mem_real'].append(current_mem_real)
log['mem_virtual'].append(current_mem_virtual)
if (linux):
log['mem_uss'].append(current_mem_uss)

except KeyboardInterrupt: # pragma: no cover
pass
Expand All @@ -216,13 +261,14 @@ def monitor(pid, logfile=None, plot=None, duration=None, interval=None,
ax.set_ylabel('CPU (%)', color='r')
ax.set_xlabel('time (s)')
ax.set_ylim(0., max(log['cpu']) * 1.2)


mem_selector = 'mem_uss' if linux else 'mem_real'
ax2 = ax.twinx()
ax2.plot(log['times'], log[mem_selector], '-', lw=1, color='b')
ax2.set_ylim(0., max(log[mem_selector]) * 1.2)

ax2.plot(log['times'], log['mem_real'], '-', lw=1, color='b')
ax2.set_ylim(0., max(log['mem_real']) * 1.2)

ax2.set_ylabel('Real Memory (MB)', color='b')
mem_label= 'Unique set size (MB)' if linux else 'Real Memory (MB)'
ax2.set_ylabel(mem_label, color='b')

ax.grid()

Expand Down

0 comments on commit 8e5bfbb

Please sign in to comment.