def get_procinfo_by_address(ip_src, ip_dst, port_src=None, port_dst=None): """ Gets Infos about the Prozess associated with the given address information Both port_src and port_dst must be not None or None at the same time. return -- [pid, "/path/to/command", "user", "hash"] or [] """ result = [] if port_src is not None: pids = [c.pid for c in net_connections() if len(c.raddr) != 0 and c.pid is not None and (c.laddr[0], c.raddr[0], c.laddr[1], c.raddr[1]) == (ip_src, ip_dst, port_src, port_dst)] else: pids = [c.pid for c in net_connections() if len(c.raddr) != 0 and c.pid is not None and (c.laddr[0], c.raddr[0]) == (ip_src, ip_dst)] try: if len(pids) > 1: logger.warning("more than 1 matching process: %r", pids) proc = Process(pids[0]) cmd = [pids[0], proc.cmdline(), proc.username()] hash_input = "%d%s%s" % (cmd[0], cmd[1], cmd[2]) procinfo_hash = hashlib.sha256(hash_input.encode("UTF-8")) cmd.append(procinfo_hash) logger.debug("process info: %r", cmd) return cmd except IndexError: pass return []
class Proc(object): def __init__(self, pid): self.pid = pid self.proc = Process(pid) with self.proc.oneshot(): self.name = self.proc.name() self.owner = self.proc.username() self.created = self.proc.create_time() def poll(self, delay=1): if not self.proc.is_running(): return ( self.pid, '**DEAD**' + self.name, self.owner, 0, 0 ) with self.proc.oneshot(): self.poll1 = self.proc.cpu_times() self.virtual1 = self.proc.memory_info().vms self.system1 = cpu_times() time.sleep(delay) with self.proc.oneshot(): self.poll2 = self.proc.cpu_times() self.virtual2 = self.proc.memory_info().vms self.system2 = cpu_times() self.proc_time = sum(self.poll2) - sum(self.poll1) self.cpu_time = sum(self.system2) - sum(self.system1) self.virtual = MB(( self.virtual1 + self.virtual2 ) / 2) self.cpu_percent = 100 * ( self.proc_time / self.cpu_time ) return ( self.pid, self.name, self.owner, self.cpu_percent, self.virtual ) def is_running(self): return self.proc.is_running() def __repr__(self): return "**process** %s (%d)" % ( self.proc.name(), self.pid ) def __str__(self): return template.format(self.pid, self.name, self.owner, self.cpu_percent, self.virtual)
def get_user_who_spawned_process(process: psutil.Process): # username = process.username() try: user = process.username() except psutil.AccessDenied: user = "******" return user
def get_info(component_path, format): component_details = open(os.path.join(component_path, ZATO_INFO_FILE)).read() out = { 'component_details': component_details, 'component_full_path': component_path, 'component_host': current_host(), 'component_running': False, 'current_time': datetime.now().isoformat(), 'current_time_utc': datetime.utcnow().isoformat(), 'master_proc_connections': None, 'master_proc_pid': None, 'master_proc_name': None, 'master_proc_create_time': None, 'master_proc_create_time_utc': None, 'master_proc_username': None, 'master_proc_workers_no': None, 'master_proc_workers_pids': None, } master_proc_pid = None try: master_proc_pid = int( open(os.path.join(component_path, MISC.PIDFILE)).read()) except (IOError, ValueError): # Ok, no such file or it's empty pass if master_proc_pid: out['component_running'] = True master_proc = Process(master_proc_pid) workers_pids = sorted(elem.pid for elem in master_proc.children()) out['master_proc_connections'] = format_connections( master_proc.connections(), format) out['master_proc_pid'] = master_proc.pid out['master_proc_create_time'] = datetime.fromtimestamp( master_proc.create_time()).isoformat() out['master_proc_create_time_utc'] = datetime.fromtimestamp( master_proc.create_time(), UTC).isoformat() out['master_proc_username'] = master_proc.username() out['master_proc_name'] = master_proc.name() out['master_proc_workers_no'] = len(workers_pids) out['master_proc_workers_pids'] = workers_pids for pid in workers_pids: worker = Process(pid) out['worker_{}_create_time'.format(pid)] = datetime.fromtimestamp( worker.create_time()).isoformat() out['worker_{}_create_time_utc'.format( pid)] = datetime.fromtimestamp(worker.create_time(), UTC).isoformat() out['worker_{}_connections'.format(pid)] = format_connections( worker.connections(), format) return out
def get_info(component_path, format): component_details = open(os.path.join(component_path, ZATO_INFO_FILE)).read() out = { 'component_details': component_details, 'component_full_path': component_path, 'component_host': current_host(), 'component_running': False, 'current_time': datetime.now().isoformat(), 'current_time_utc': datetime.utcnow().isoformat(), 'master_proc_connections': None, 'master_proc_pid': None, 'master_proc_name': None, 'master_proc_create_time': None, 'master_proc_create_time_utc': None, 'master_proc_username': None, 'master_proc_workers_no': None, 'master_proc_workers_pids': None, } master_proc_pid = None try: master_proc_pid = int(open(os.path.join(component_path, MISC.PIDFILE)).read()) except(IOError, ValueError): # Ok, no such file or it's empty pass if master_proc_pid: out['component_running'] = True master_proc = Process(master_proc_pid) workers_pids = sorted(elem.pid for elem in master_proc.children()) out['master_proc_connections'] = format_connections(master_proc.connections(), format) out['master_proc_pid'] = master_proc.pid out['master_proc_create_time'] = datetime.fromtimestamp(master_proc.create_time()).isoformat() out['master_proc_create_time_utc'] = datetime.fromtimestamp(master_proc.create_time(), UTC).isoformat() out['master_proc_username'] = master_proc.username() out['master_proc_name'] = master_proc.name() out['master_proc_workers_no'] = len(workers_pids) out['master_proc_workers_pids'] = workers_pids for pid in workers_pids: worker = Process(pid) out['worker_{}_create_time'.format(pid)] = datetime.fromtimestamp(worker.create_time()).isoformat() out['worker_{}_create_time_utc'.format(pid)] = datetime.fromtimestamp(worker.create_time(), UTC).isoformat() out['worker_{}_connections'.format(pid)] = format_connections(worker.connections(), format) return out
def add_new_information_from_process_object(self, process: psutil.Process, data_retrieval_timestamp: datetime.datetime) -> None: """ Adds the new information about the process to the application profile. This should be mainly used for applications with only one process. :raises TypeError if process is not of type psutil.Process or data_retrieval_timestamp is not of type datetime.datetime. :raises ValueError if data_retrieval_timestamp is newer than current time. :param process: Information about the specific process. :type process: psutil.Process :param data_retrieval_timestamp: The time the data was retrieved. :type data_retrieval_timestamp: datetime.datetime """ if not (isinstance(process, psutil.Process)): raise TypeError(expected_type_but_received_message.format("process", "psutil.Process", process)) if not (isinstance(data_retrieval_timestamp, datetime.datetime)): raise TypeError(expected_type_but_received_message.format("data_retrieval_timestamp", "datetime.datetime", data_retrieval_timestamp)) if data_retrieval_timestamp.replace(tzinfo=None) > datetime.datetime.now(): raise ValueError("Argument data_retrieval_timestamp cannot be newer than current time. Value receive: {}" .format(data_retrieval_timestamp)) # Get info from the process object. One of the following calls may raise an Error (OS, AccessDenied, etc). open_files = process.open_files() memory_info = process.memory_info() child_process_count = len(process.children()) username = process.username() threads_number = process.num_threads() process.cpu_percent() try: connections_num = len(process.connections()) except psutil.AccessDenied: connections_num = 0 time.sleep(0.1) # wait for cpu_percent to return a meaningful value. cpu_percentage = process.cpu_percent() self.add_open_files(open_files=open_files, data_retrieval_timestamp=data_retrieval_timestamp) self.__memory_usages.append(memory_info.rss) self.__data_retrieval_timestamp.append(data_retrieval_timestamp) self.__child_processes_count.append(child_process_count) self.__users.extend(username) self.__cpu_percent_usages.append(cpu_percentage) self.__threads_numbers.append(threads_number) self.__connections_numbers.append(connections_num)
def main(): connections = psutil.net_connections() listen = list(filter(lambda x: x.status == 'LISTEN', connections)) listen_sorted = sorted(listen, key=lambda x: x.laddr.port) print(f"{'ip':<12} {'port':<6} {'user':<16} {'started':<15} {'parent':<15} {'cwd':<30} {'cmdline'}".upper()) for l in listen_sorted: ip = l.laddr.ip port = l.laddr.port if not l.pid: cwd, user, cmdline, started = 4 * ["NOPERM"] else: p = Process(l.pid) parent = p.parent().name() cwd = p.cwd() user = p.username() cmdline = " ".join(p.cmdline()) started = arrow.get(p.create_time()).humanize() print(f"{ip:<12} {port:<6} {user:<16} {started:<15} {parent:<15} {cwd:<30} {cmdline}")
def track_memory_usage(out_path: str, write_frequency: float): """Track how busy the head node is Args: out_path: Path to the output file write_frequency: How often to write (s) """ while True: # Get a timestamp ts = datetime.now().timestamp() # Measure the thinker process proc = Process() my_usage = proc.cpu_percent() my_memory = proc.memory_full_info().pss # Measure all processes from my user my_name = getuser() all_cpu = all_memory = 0 for proc in process_iter(): if proc.username() != my_name: continue try: all_cpu += proc.cpu_percent() all_memory += proc.memory_full_info().pss except: continue with open(out_path, 'a') as fp: print(json.dumps({ 'time': ts, 'thinker_cpu': my_usage, 'thinker_mem': my_memory, 'all_cpu': all_cpu, 'all_mem': all_memory }), file=fp) time.sleep(write_frequency)
def get_procinfo_by_address(ip_src, ip_dst, port_src=None, port_dst=None): """ Gets Infos about the Prozess associated with the given address information Both port_src and port_dst must be not None or None at the same time. return -- [pid, "/path/to/command", "user", "hash"] or [] """ result = [] if port_src is not None: pids = [ c.pid for c in net_connections() if len(c.raddr) != 0 and c.pid is not None and ( c.laddr[0], c.raddr[0], c.laddr[1], c.raddr[1]) == (ip_src, ip_dst, port_src, port_dst) ] else: pids = [ c.pid for c in net_connections() if len(c.raddr) != 0 and c.pid is not None and ( c.laddr[0], c.raddr[0]) == (ip_src, ip_dst) ] try: if len(pids) > 1: logger.warning("more than 1 matching process: %r", pids) proc = Process(pids[0]) cmd = [pids[0], proc.cmdline(), proc.username()] hash_input = "%d%s%s" % (cmd[0], cmd[1], cmd[2]) procinfo_hash = hashlib.sha256(hash_input.encode("UTF-8")) cmd.append(procinfo_hash) logger.debug("process info: %r", cmd) return cmd except IndexError: pass return []
if echo1.decode("ascii") == msg1: parent = echo_proc try: while parent.pid != master_proc.pid: parent = parent.parent() except: pass # finish the message if parent: queue.send(msg2, type=1) # refuse to speak if no common ancestor process else: eprint("refused " + format(echo_proc) + " from " + echo_proc.username()) # clear try: while True: queue.receive(block=False) except: pass # refuse to speak to wrong echo else: eprint("received " + echo1.decode("ascii") + " sent " + msg1 + " from " + format(echo_proc) + " from " + echo_proc.username()) # clear try: while True:
def _on_server(self, args): os.chdir(self.original_dir) abs_args_path = os.path.abspath(args.path) component_details = open(os.path.join(abs_args_path, ZATO_INFO_FILE)).read() out = { 'component_details': component_details, 'component_full_path': abs_args_path, 'component_host': current_host(), 'component_running': False, 'current_time': datetime.now().isoformat(), 'current_time_utc': datetime.utcnow().isoformat(), 'master_proc_connections': None, 'master_proc_pid': None, 'master_proc_name': None, 'master_proc_create_time': None, 'master_proc_create_time_utc': None, 'master_proc_username': None, 'master_proc_workers_no': None, 'master_proc_workers_pids': None, } master_proc_pid = None try: master_proc_pid = int(open(os.path.join(abs_args_path, MISC.PIDFILE)).read()) except(IOError, ValueError): # Ok, no such file or it's empty pass if master_proc_pid: out['component_running'] = True master_proc = Process(master_proc_pid) workers_pids = sorted(elem.pid for elem in master_proc.children()) out['master_proc_connections'] = master_proc.connections() out['master_proc_pid'] = master_proc.pid out['master_proc_create_time'] = datetime.fromtimestamp(master_proc.create_time()).isoformat() out['master_proc_create_time_utc'] = datetime.fromtimestamp(master_proc.create_time(), UTC).isoformat() out['master_proc_username'] = master_proc.username() out['master_proc_name'] = master_proc.name() out['master_proc_workers_no'] = len(workers_pids) out['master_proc_workers_pids'] = workers_pids for pid in workers_pids: worker = Process(pid) out['worker_{}_create_time'.format(pid)] = datetime.fromtimestamp(worker.create_time()).isoformat() out['worker_{}_create_time_utc'.format(pid)] = datetime.fromtimestamp(worker.create_time(), UTC).isoformat() out['worker_{}_connections'.format(pid)] = worker.connections() if getattr(args, 'json', False): out['component_details'] = loads(out['component_details']) self.logger.info(dumps(out)) else: cols_width = args.cols_width if args.cols_width else DEFAULT_COLS_WIDTH cols_width = (elem.strip() for elem in cols_width.split(',')) cols_width = [int(elem) for elem in cols_width] table = Texttable() table.set_cols_width(cols_width) # Use text ('t') instead of auto so that boolean values don't get converted into ints table.set_cols_dtype(['t', 't']) rows = [['Key', 'Value']] rows.extend(sorted(out.items())) table.add_rows(rows) self.logger.info(table.draw())