def from_env_task(**kwargs): '''Get some set of variables from the environment. We look for those defined in kwargs, but also any in the environment that start with the prefix WATCHMENEV_. They are saved to files that are equivalently named, and the idea is that we can track a changing (single) result, meaning that the timestamp is meaningful, or we can track values for many different results, so the timestamps just serve to record when each was recorded. Parameters ========== *: any number of parameters from the task configuration that will be looked for in the environment. ''' results = [] # Create a temporary directory for results tmpdir = get_tmpdir() # First extract variables from the environment environ = get_watchme_env() for key, value in environ.items(): # Write the result to file (don't include extension) filename = os.path.join(tmpdir, key) write_file(filename, value) results.append(filename) # If no results, return None if len(results) == 0: shutil.rmtree(tmpdir) return results
def users_task(**kwargs): """Get values for current users""" result = {"users": []} for user in psutil.users(): result["users"].append(dict(user._asdict())) # Add any environment variables prefixed wit WATCHMEENV_ environ = get_watchme_env() result.update(environ) return result
def memory_task(**kwargs): """Get values for memory of the host. No parameters are required.""" result = {} # gives an object with many fields result["virtual_memory"] = dict(psutil.virtual_memory()._asdict()) # Add any environment variables prefixed wit WATCHMEENV_ environ = get_watchme_env() result.update(environ) return result
def _filter_result(result, skip): '''a helper function to filter a dictionary based on a list of keys to skip. We also add variables from the environment. Parameters ========== result: a dictionary of results skip: a list of keys to remove/filter from the result. ''' # Add any environment variables prefixed wit WATCHMEENV_ environ = get_watchme_env() result.update(environ) for key in skip: if key in result: del result[key] return result
def monitor_pid_task(**kwargs): '''monitor a specific process. This function can be used as a task, or is (most likely used) for the psutils.decorators. A pid parameter is required. Parameters ========== skip: an optional list of (comma separated) fields to skip. Can be in net_io_counters,net_connections,net_if_address,net_if_stats pid: the process id or name (required) ''' pid = kwargs.get('pid', None) bot.debug(kwargs) # Helper function to get list from one,two,three def get_list(name): csv_list = kwargs.get(name, '') return [x for x in csv_list.split(',') if x] # A comma separated list of parameters to skip skip = get_list('skip') include = get_list('include') only = get_list('only') # Only continue given that argument is provided if pid is None: bot.warning( "A 'pid' parameter is required to use the monitor_pid_task function." ) return pid # The user is allowed to provide a process name, or a number try: pid = int(pid) except ValueError: pid = _get_pid(pid) # But if it's stil no good (None) we exit. if pid is None: bot.warning("'pid' must be a running process or process name.") return pid ps = psutil.Process(pid) bot.debug(ps) results = {} for key, val in ps.as_dict().items(): # If val is None, don't include if val is None: bot.debug('skipping %s, None' % key) continue if key == "connections": connections = [] for net in val: entry = { 'fd': net.fd, 'family': str(net.family), 'type': str(net.type), 'laddr_ip': net.laddr.ip, 'laddr_port': net.laddr.port, 'raddr': net.raddr, 'status': net.status } connections.append(entry) val = connections # First priority goes to a custom set if len(only) > 0: if key in only: results[key] = val else: bot.debug('skipping %s' % key) continue # The user requested to skip elif key in skip or key in ['threads']: continue # Keep count of openfiles elif key in ["open_files"]: results[key] = len(val) # Don't risk exposing sensitive information elif key == "environ": if key in include: results[key] = val # Skip over ones that are too detailed elif key in ['memory_maps']: continue # I assume this included all that are in pmem too elif isinstance(val, psutil._pslinux.pfullmem): results[key] = { "rss": val.rss, "vms": val.vms, "shared": val.shared, "text": val.text, "lib": val.lib, "data": val.data, "dirty": val.dirty, "uss": val.uss, "pss": val.pss, "swap": val.swap } elif isinstance(val, psutil._common.pgids) or isinstance( val, psutil._common.puids): results[key] = { "real": val.real, "effetive": val.effective, "saved": val.saved } elif isinstance(val, psutil._common.pcputimes): results[key] = { "user": val.user, "system": val.system, "children_user": val.children_user, "children_system": val.children_system } elif isinstance(val, psutil._common.pctxsw): results[key] = { "voluntary": val.voluntary, "involuntary": val.involuntary } elif isinstance(val, psutil._common.pionice): results[key] = {"value": val.value} # Older Python version (2) doesn't have attribute if hasattr(val.ioclass, 'name'): results[key]["ioclass"] = val.ioclass.name # pfullmem (first above) should cover this elif isinstance(val, psutil._pslinux.pmem): continue elif isinstance(val, psutil._pslinux.pio): results[key] = { "read_count": val.read_count, "write_count": val.write_count, "read_bytes": val.read_bytes, "write_bytes": val.write_bytes, "read_chars": val.read_chars, "write_chars": val.write_chars } else: results[key] = val # Add any environment variables prefixed wit WATCHMEENV_ environ = get_watchme_env() results.update(environ) return results