def _parse_section(section_name, current_process, current_thread, maps, stats, data): if section_name == 'meminfo': parse_meminfo(maps, data) elif section_name == 'loadavg': parse_loadavg(stats, data) elif section_name == 'uptime': parse_uptime(stats, data) elif section_name == 'vmstat': parse_vmstat(stats, data) elif current_thread and section_name == 'stat': parse_stat(current_thread, data) elif current_process and section_name != '': # Hit a new file, consolidate what we have so far. if 'smaps' == section_name: _save_smaps_region(current_process.maps, maps, current_process.pid, data) elif 'cmdline' == section_name: # Some command lines have a number of empty arguments. Ignore # that because it's not interesting here. current_process.argv = filter(len, data.strip().split('\0')) elif 'stat' == section_name: parse_stat(current_process, data) else: LOGGER.error('Unrecognised section name: %s' % section_name)
def _parse_section(section_name, current_process, current_thread, data, out): try: parser = parsers.get_parser(section_name) parser.parse(data, out) except: pass if current_thread and section_name == 'stat': _save_stat(current_thread, out['stat']) elif current_process and section_name != '': # Hit a new file, consolidate what we have so far. if 'smaps' == section_name: _save_smaps_region(current_process.maps, out['meminfo'], current_process.pid, data) elif 'cmdline' == section_name: # Some command lines have a number of empty arguments. Ignore # that because it's not interesting here. current_process.argv = filter(len, data.strip().split('\0')) elif 'stat' == section_name: _save_stat(current_process, out['stat']) else: LOGGER.error('Unrecognised section name: %s' % section_name)
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