Source code for amsatop.utils.__stat_file

import logging
from dataclasses import dataclass


[docs] @dataclass(frozen=True) class StatFile: """ Represents key fields from a process's or thread /proc/[pid or tgid]/stat file. """ pid: int command: str # Filename of the executable (in parentheses) state: str # Process state ppid: int # Parent PID pgrp: int # Process group ID session: int # Session ID tty_nr: int # Controlling terminal tpgid: int # Foreground process group ID flags: int # Kernel flags minflt: int # Minor faults cminflt: int # Minor faults with children majflt: int # Major faults cmajflt: int # Major faults with children utime: int # User mode jiffies stime: int # Kernel mode jiffies cutime: int # User mode jiffies with children cstime: int # Kernel mode jiffies with children priority: int # Priority value nice: int # Nice value num_threads: int # Number of threads starttime: int # Start time since boot (in jiffies)
[docs] @classmethod def from_stat_line(cls, line: str) -> "StatFile": """ Get a StatFile from the lines of the file :meta private: """ first_paren = line.find('(') last_paren = line.rfind(')') if first_paren == -1 or last_paren == -1: raise ValueError("Malformed stat line: missing parentheses around command") before = line[:first_paren].strip() command = line[first_paren + 1:last_paren] after = line[last_paren + 1:].strip() fields = before.split() + [command] + after.split() if len(fields) < 22: raise ValueError("Malformed stat line: insufficient fields") return StatFile( pid=int(fields[0]), command=fields[1], state=fields[2], ppid=int(fields[3]), pgrp=int(fields[4]), session=int(fields[5]), tty_nr=int(fields[6]), tpgid=int(fields[7]), flags=int(fields[8]), minflt=int(fields[9]), cminflt=int(fields[10]), majflt=int(fields[11]), cmajflt=int(fields[12]), utime=int(fields[13]), stime=int(fields[14]), cutime=int(fields[15]), cstime=int(fields[16]), priority=int(fields[17]), nice=int(fields[18]), num_threads=int(fields[19]), starttime=int(fields[21]), )
[docs] def get_stat_file_from_path(path: str) -> StatFile | None: """ Given a path, returns a StatFile, which can be useful for analyzing a process or thread. :param path: path to the stat file (will be usually in the form of /proc/[pid or tgid]/stat :returns: StatFile or None if the path doesn't exist. :raises: ValueError if the path isn't valid. """ if not path.endswith("/stat"): raise ValueError(f"Stat file, should end with /stat......") try: with open(path, "r", encoding="utf-8") as f: line = f.readline() return StatFile.from_stat_line(line) except FileNotFoundError: return None except Exception as e: logging.error( "Unhandled error in amsatop library (not your solution), please report to the instructors: %s", e ) return None