def testProperties(self): """Tests the properties.""" pid = os.getpid() process_information = process_info.ProcessInfo(pid) self.assertEqual(process_information.status, process_information.STATUS_RUNNING)
def testGetMemoryInformation(self): """Tests the GetMemoryInformation function.""" pid = os.getpid() process_information = process_info.ProcessInfo(pid) memory_information = process_information.GetMemoryInformation() self.assertNotEqual(memory_information, None)
def MonitorWorker(self, label=None, pid=None, name=None): """Starts monitoring a worker by adding it to the monitor list. This function requires either a label to be set or a PID and a process name. If the label is empty or if both a PID and a name is not provided the function does nothing, as in no process is added to the list of workers to monitor (and no indication). Args: label: A process label (instance of PROCESS_LABEL), if not provided then a pid and a name is required. Defaults to None (if None then both a pid and name have to be provided). pid: The process ID (PID) of the worker that should be added to the monitor list. This is only required if label is not provided. Defaults to None. This is only used if label is set to None, in which case it has to be set. name: The name of the worker process, only required if label is not provided. Defaults to None, only used if label is set to None, in which case it has to be set. """ if label is None: if pid is None or name is None: return label = self.PROCESS_LABEL(name, pid, process_info.ProcessInfo(pid=pid)) if not label: return if label not in self._process_labels: self._process_labels.append(label)
def TerminateProcess(self, label=None, pid=None, name=None): """Terminate a process, even if it is not in the watch list. Args: label: A process label (instance of PROCESS_LABEL), if not provided then a pid and a name is required. It defaults to None, in which case you need to provide a pid and/or a name. pid: The process ID (PID) of the worker. This is only required if label is not provided and defaults to None. name: The name of the worker process, only required if label is not provided and defaults to None. """ if label is not None: self._TerminateProcess(label) return if pid is not None: for process_label in self._process_labels: if process_label.pid == pid: self._TerminateProcess(process_label) return if name is not None: for process_label in self._process_labels: if process_label.label == name: self._TerminateProcess(process_label) return # If we reach here the process is not in our watch list. if pid is not None and name is not None: process_label = self.PROCESS_LABEL( name, pid, process_info.ProcessInfo(pid=pid)) self._TerminateProcess(process_label)
def StopMonitoringWorker(self, label=None, pid=None, name=None): """Stop monitoring a particular worker and remove it from monitor list. The purpose of this function is to remove a worker from the list of monitored workers. In order to do that the function requires either a label or a pid and a name. Args: label: A process label (instance of PROCESS_LABEL). Defaults to None, and so then a pid and name are required. pid: The process ID (PID) of the worker that should no longer be monitored. This is only required if label is not provided and defaults to None. name: The name of the worker process, defaults to None and is only required if label is not set. """ if label is None: if pid is None or name is None: return label = self.PROCESS_LABEL(name, pid, process_info.ProcessInfo(pid=pid)) if label not in self._process_labels: return index = self._process_labels.index(label) del self._process_labels[index] logging.info( u'{0:s} [{1:d}] has been removed from foreman monitoring.'.format( label.label, label.pid))
def testProperties(self): """Tests the properties.""" pid = os.getpid() process_info_object = process_info.ProcessInfo(pid) self.assertEqual(process_info_object.pid, pid) self.assertEqual(process_info_object.status, process_info_object.STATUS_RUNNING) # The following values will vary per platform and how the test is invoked. self.assertNotEqual(process_info_object.command_line, None) self.assertNotEqual(process_info_object.cpu_percent, None) self.assertNotEqual(process_info_object.cpu_times, None) # Testing on OSX fails because get_io_counters from psutils is not # available on that platform. # Ref: https://github.com/log2timeline/plaso/issues/175 # self.assertNotEqual(process_info_object.io_counters, None) self.assertNotEqual(process_info_object.memory_map, None) self.assertNotEqual(process_info_object.name, None) self.assertNotEqual(process_info_object.number_of_threads, 0) self.assertNotEqual(process_info_object.open_files, None) self.assertNotEqual(process_info_object.parent, None) self.assertNotEqual(process_info_object.start_time, None) for _ in process_info_object.children: pass
def __init__(self, show_memory_usage=False): """Initialize the foreman process. Args: show_memory_usage: Optional boolean value to indicate memory information should be included in logging. The default is false. """ super(Foreman, self).__init__() self._last_status_dict = {} self._process_information = process_info.ProcessInfo() self._process_labels = [] self._processing_done = False self._show_memory_usage = show_memory_usage
def MonitorWorker(self, label=None, pid=None, name=None): """Starts monitoring a worker by adding it to the monitor list. This function requires either a label to be set or a PID and a process name. If the label is empty or if both a PID and a name is not provided the function does nothing, as in no process is added to the list of workers to monitor (and no indication). Args: label: A process label (instance of PROCESS_LABEL), if not provided then a pid and a name is required. Defaults to None (if None then both a pid and name have to be provided). pid: The process ID (PID) of the worker that should be added to the monitor list. This is only required if label is not provided. Defaults to None. This is only used if label is set to None, in which case it has to be set. name: The name of the worker process, only required if label is not provided. Defaults to None, only used if label is set to None, in which case it has to be set. Raises: IOError: if the RPC client cannot connect to the server. RuntimeError: if the RPC client is already set for a certain PID. """ if label is None: if pid is None or name is None: return if pid in self._rpc_clients_per_pid: raise RuntimeError( u'RPC client (PID: {0:d}) already exists'.format(pid)) rpc_client = xmlrpc.XMLProcessStatusRPCClient() hostname = u'localhost' port = rpc.GetProxyPortNumberFromPID(pid) if not rpc_client.Open(hostname, port): raise IOError( (u'RPC client (PID: {0:d}) unable to connect to server: ' u'{1:s}:{2:d}').format(pid, hostname, port)) self._rpc_clients_per_pid[pid] = rpc_client process_information = process_info.ProcessInfo(pid) label = self.PROCESS_LABEL(name, pid, process_information) if label.pid not in self._monitored_process_labels: if label.pid in self._completed_process_labels: del self._completed_process_labels[label.pid] self._monitored_process_labels[label.pid] = label
def _StartMonitoringProcess(self, pid): """Starts monitoring a process. Args: pid (int): process identifier (PID). Raises: KeyError: if the process is not registered with the engine or if the process if the processed is already being monitored. IOError: if the RPC client cannot connect to the server. """ self._RaiseIfNotRegistered(pid) if pid in self._process_information_per_pid: raise KeyError( u'Process (PID: {0:d}) already in monitoring list.'.format( pid)) if pid in self._rpc_clients_per_pid: raise KeyError( u'RPC client (PID: {0:d}) already exists'.format(pid)) process = self._processes_per_pid[pid] rpc_client = plaso_xmlrpc.XMLProcessStatusRPCClient() # Make sure that a process has started its RPC server. RPC port will # be 0 if no server is available. rpc_port = process.rpc_port.value time_waited_for_process = 0.0 while not rpc_port: time.sleep(0.1) rpc_port = process.rpc_port.value time_waited_for_process += 0.1 if time_waited_for_process >= self._RPC_SERVER_TIMEOUT: raise IOError( u'RPC client unable to determine server (PID: {0:d}) port.' .format(pid)) hostname = u'localhost' if not rpc_client.Open(hostname, rpc_port): raise IOError( (u'RPC client unable to connect to server (PID: {0:d}) ' u'http://{1:s}:{2:d}').format(pid, hostname, rpc_port)) self._rpc_clients_per_pid[pid] = rpc_client self._process_information_per_pid[pid] = process_info.ProcessInfo(pid)
def testInitialization(self): """Tests the initialization.""" pid = os.getpid() process_information = process_info.ProcessInfo(pid) self.assertNotEqual(process_information, None)
def testIsAlive(self): """Tests the IsAlive function.""" pid = os.getpid() process_info_object = process_info.ProcessInfo(pid) self.assertTrue(process_info_object.IsAlive())