def test_loadavg(self): s = StringIO('==> /proc/loadavg <==\n0.15 0.22 0.43 1/650 3914\n') stats = read_tailed_files(s)[0] self.assertEqual(0.15, stats.one_minute_load) self.assertEqual(0.22, stats.five_minute_load) self.assertEqual(0.43, stats.fifteen_minute_load) self.assertEqual(1, stats.running_threads) self.assertEqual(650, stats.total_threads) self.assertEqual(3914, stats.last_pid)
def test_reading_realistic_file(self): with open(os.path.join(os.path.dirname(__file__), 'procfs.tail'), 'rb') as f: _, processes, _ = read_tailed_files(f) self.assertEqual(6, len(processes)) p = processes[6261] self.assertEqual(p.comm, 'deja-dup-monitor', 'name did not match? [{0}]'.format(p.comm)) self.assertEqual(p.minor_faults, 7149, 'minor_faults did not match') self.assertEqual(p.major_faults, 0, 'major_faults did not match') self.assertEqual(p.user_time, 17, 'user_time did not match') self.assertEqual(p.system_time, 11, 'system_time did not match') self.assertEqual(p.start_time, 1027736, 'start_time did not match')
def read_stats(args): # This is the command to grab all of the necessary info. # Note that -v is passed to tail - this is so we always the filename # given to us, which is needed for parsing. # As processes can be transient, we can get errors here about # non-existent files, so ignore them, this is expected. cmd = 'nice tail -v -n +1 '\ '/proc/%s/{cmdline,smaps} '\ '/proc/meminfo '\ '/proc/loadavg '\ '/proc/uptime '\ '/proc/vmstat '\ '2>/dev/null; ' \ 'nice find /proc/%s -type f -name stat '\ '-exec tail -v -n +1 {} \; 2>/dev/null | '\ 'awk \''\ '/==>/ {print} '\ '/^[0-9]/ {print \$2, \$10, \$12, \$14, \$15, \$22}\';' # Accept a space-separated list of pids as that is what pidof(8) returns and # it's quite likely you'll want to invoke this script with something like: # # --pid "`pidof foobar`" # # at some point. if args.pid.isdigit() or args.pid == '*': pids = args.pid else: pids = '{%s}' % args.pid.replace(' ', ',') # root can see all of /proc, another user is likely not going to be able # to read all of it. This isn't a hard error, but won't give a full view # of the system. if (args.host == '' and getpass.getuser() != "root") or\ (args.host != '' and args.user != 'root'): LOGGER.warning("If not running as root you may not see all info.") if args.host == '': LOGGER.info('Loading local procfs files') cmd = "bash -c \"%s\"" % (cmd % (pids, pids)) elif args.host != '': ssh = ( "ssh %s@%s" " -o UserKnownHostsFile=/dev/null" " -o StrictHostKeyChecking=no" " -o LogLevel=error" % (args.user, args.host) ) if args.password: ssh = "sshpass -p %s %s" % (args.password, ssh) else: ssh = "%s -o PasswordAuthentication=no" % ssh cmd = """%s "%s" """ % (ssh, cmd % (pids, pids)) LOGGER.info('Reading procfs with cmd: %s' % cmd) p = Popen(cmd, shell=True, bufsize=-1, stdout=PIPE, stderr=PIPE) stats = read_tailed_files(p.stdout) if p.poll() != 0: LOGGER.error("Command failed with: %r" % p.stderr.read().strip()) sys.exit(1) return stats
def test_reading_empty_string(self): _, processes, _ = read_tailed_files(StringIO('')) self.assertEqual(0, len(processes))
def test_reading_realistic_file(self): with open(os.path.join(os.path.dirname(__file__), 'procfs.tail'), 'rb') as f: _, processes, _ = read_tailed_files(f) self.assertEqual(6, len(processes))
def test_reading_empty_file(self): with tempfile.TemporaryFile('rb') as f: _, processes, _ = read_tailed_files(f) self.assertEqual(0, len(processes))