Skip to content

Instantly share code, notes, and snippets.

@corvax19
Created January 17, 2013 16:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save corvax19/4557108 to your computer and use it in GitHub Desktop.
Save corvax19/4557108 to your computer and use it in GitHub Desktop.
Script measures IO activity of the processes for a specified amount of time and return top list of those. Read, write or both IO operation could be measured and reported.
#!/usr/bin/python
import subprocess
import sys
import time
from optparse import OptionParser
def getOptionParser():
parser = OptionParser(version = '0.1_2012017',
description = '''Script measures IO activity of the processes for a specified amount of time
and return top list of those. Read, write or both IO operation could be measured and reported.
romans(dot)krjukovs(at)gmail(dot)com''')
parser.add_option("-i", "--interval",
dest = "time_interval",
help = "time interval between making proc io snapshots",
action = "store",
type = "int",
default = 5,
metavar = "SECONDS")
parser.add_option("-o", "--operation",
dest = "operation",
help = "operation to measure IO on",
action = "store",
type = "choice",
choices = ('R', 'W', 'RW'),
default = "W",
metavar = 'OPERATION')
parser.add_option("-v", "--verbose",
action = "store_true",
dest = "verbose",
default = False)
parser.add_option("-n", "--no-heading",
action = "store_true",
dest = "noheading",
default = False)
return parser
def run_command(command):
p = subprocess.Popen(command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
return iter(p.stdout.readline, '')
def read_pid_io(pid):
res = {}
for line in run_command(["cat", "/proc/"+pid+"/io"]):
if line.find("bytes")>-1:
line_split = line.split(":")
res[line_split[0]] = line_split[1].strip()
return res
def snapshot_pid_io():
res = {}
for line in run_command(["ps", "-e", "--no-heading"]):
parts = line.split()
res[parts[0]]={'pid':parts[0], 'proc':parts[3], 'io':read_pid_io(parts[0])}
return res
def compare(f,s,switch):
res = {}
for pid,details in f.items():
if len(details['io'].keys())>0:
first_bytes = int(details['io'][switch])
second_bytes = int(s[pid]['io'][switch])
if (second_bytes > first_bytes):
res[pid] = second_bytes - first_bytes
return res
def parse(pid_hash, compare_res, options, operation):
if not(options.noheading):
print '%s %s %s' % ('PID'.rjust(5), (operation+'-Bytes').rjust(10), 'Proc'.ljust(16))
for pid, delta in sorted(compare_res.items(), key=lambda x: x[1]):
print '%s %s %s' % (str(pid).rjust(5), str(delta).rjust(10), str(pid_hash[pid]['proc']).ljust(16))
if __name__ == "__main__":
(options, args) = getOptionParser().parse_args()
if options.verbose:
print "Making initial snapshot of proc io.."
first = snapshot_pid_io()
if options.verbose:
print "Pausing for %d sec.." % (options.time_interval)
time.sleep(options.time_interval)
if options.verbose:
print "Making second snapshot of proc io.."
second = snapshot_pid_io()
if 'R' in options.operation:
if options.verbose:
print "Comparing R-bytes:"
parse(second, compare(first, second, 'read_bytes'), options, "R")
if 'W' in options.operation:
if options.verbose:
print "Comparing W-bytes:"
parse(second, compare(first, second, 'write_bytes'), options, "W")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment