def uid(self): """int: Numerical UID as reported by ps""" if self.info is not None: uid = self.info.get("UID") if uid is not None: n = to_int(uid) if n is not None: return n r = run("id", "-u", uid, dryrun=False, fatal=False, logger=None) if r.succeeded: return to_int(r.output)
def _get_file_handler(location, rotate, rotate_count): """ Args: location (str | None): Log file path rotate (str | None): How to rotate, examples: time:midnight - Rotate at midnight time:15s - Rotate every 15 seconds time:2h - Rotate every 2 hours time:7d - Rotate every 7 days size:20m - Rotate every 20MB size:1g - Rotate every 1MB rotate_count (int): How many backups to keep Returns: (logging.FileHandler): Associated handler """ if not rotate: return logging.FileHandler(location) kind, _, mode = rotate.partition(":") if not mode: raise ValueError("Invalid 'rotate' (missing kind): %s" % rotate) if kind == "time": if mode == "midnight": return TimedRotatingFileHandler(location, when="midnight", backupCount=rotate_count) timed = "shd" if mode[-1].lower() not in timed: raise ValueError("Invalid 'rotate' (unknown time spec): %s" % rotate) interval = to_int(mode[:-1]) if interval is None: raise ValueError("Invalid 'rotate' (time range not an int): %s" % rotate) return TimedRotatingFileHandler(location, when=mode[-1], interval=interval, backupCount=rotate_count) if kind == "size": size = to_bytesize(mode) if size is None: raise ValueError("Invalid 'rotate' (size not a bytesize): %s" % rotate) return RotatingFileHandler(location, maxBytes=size, backupCount=rotate_count) raise ValueError("Invalid 'rotate' (unknown type): %s" % rotate)
def get_int(self, key, default=None, minimum=None, maximum=None): """ Args: key (str): Key to lookup default (int | None): Default to use if key is not configured minimum (int | None): If specified, result can't be below this minimum maximum (int | None): If specified, result can't be above this maximum Returns: (int | None): Value of key, if defined """ return capped(to_int(self.get(key), default=default), minimum=minimum, maximum=maximum)
def __init__(self, pid=None): """ Args: pid (int | str): PID of process to get info for (default: current process) """ self.pid = to_int(pid) or os.getpid() if self.pid: r = run("ps", "-f", self.pid, dryrun=False, fatal=False, logger=None) if r.succeeded: info = parsed_tabular(r.output) if info: self.info = info[0]
def userid(self): """str: Userid as reported by ps""" if self.info is not None: uid = self.info.get("UID") if uid is not None: n = to_int(uid) if n is None: return uid r = run("id", "-un", uid, dryrun=False, fatal=False, logger=None) if r.succeeded: return r.output
def followed_parent(self): """ Returns: (PsInfo | None): Parent process info (if any), special processes like tmux are followed through """ if self.parent and self.parent.ppid == 1: follow_command = self.ps_follow.get(self.parent.cmd_basename) if follow_command: r = run(*follow_command, dryrun=False, fatal=False, logger=None) if r.succeeded: p = PsInfo.from_pid(to_int(r.output)) if p: return p return self.parent
def _get_importtime(self): result = run(sys.executable, "-Ximporttime", "-c", "import %s" % self.module_name, fatal=None) if result.failed: lines = result.error.splitlines() self.problem = lines[-1] if lines else "-Ximporttime failed" return None cumulative = 0 for line in result.error.splitlines( ): # python -Ximporttime outputs to stderr c = to_int(line.split("|")[1]) if c: cumulative = max(cumulative, c) return cumulative
def _converted(self, value): return to_int(value)
def _problem(self, value): if to_int(value) is None: return "expecting int, got '%s'" % value
def set_pad(self, value): self.pad = to_int(value)
def ppid(self): """int: Reported parent PID""" if self.info is not None: return to_int(self.info.get("PPID"))