mirror of
https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
synced 2025-04-18 21:44:02 +03:00
111 lines
3.5 KiB
Python
111 lines
3.5 KiB
Python
import os
|
|
import time
|
|
|
|
import psutil
|
|
|
|
PROCFS_PATH = '/proc/' # Linux only
|
|
|
|
|
|
def open_binary(fname, **kwargs):
|
|
return open(fname, "rb", **kwargs)
|
|
|
|
|
|
def get_host_uptime():
|
|
"""
|
|
Return the system boot time expressed in seconds since the epoch.
|
|
|
|
:rtype: int : diff b/w current epoch and boot epoch
|
|
"""
|
|
path = f'{PROCFS_PATH}stat'
|
|
boot_time = 0
|
|
with open_binary(path) as f:
|
|
for line in f:
|
|
if line.startswith(b'btime'):
|
|
boot_time = float(line.strip().split()[1])
|
|
return int(time.time() - int(boot_time))
|
|
return 0
|
|
|
|
|
|
class Process():
|
|
"""An interface to retrieve data from proc."""
|
|
def get_proc_iterator(self):
|
|
for pid in self.pids():
|
|
yield pid
|
|
|
|
|
|
def pids(self):
|
|
"""Returns a list of PIDs currently running on the system."""
|
|
return [int(x) for x in os.listdir(PROCFS_PATH) if x.isdigit()]
|
|
|
|
|
|
def name(self, pid: int):
|
|
"""Method to retrive name associated with the pid."""
|
|
return self.parse_stat_file(pid)['name']
|
|
|
|
|
|
def parse_stat_file(self, pid: int):
|
|
"""Parse /proc/{pid}/stat file and return a dict with various
|
|
process info.
|
|
|
|
Using "man proc" as a reference: where "man proc" refers to
|
|
position N always substract 3 (e.g ppid position 4 in
|
|
'man proc' == position 1 in here).
|
|
"""
|
|
ret = {}
|
|
try:
|
|
with open_binary(f"{PROCFS_PATH}{pid}/stat") as f:
|
|
data = f.read()
|
|
# Process name is between parentheses. It can contain spaces and
|
|
# other parentheses. This is taken into account by looking for
|
|
# the first occurrence of "(" and the last occurence of ")".
|
|
rpar = data.rfind(b')')
|
|
name = data[data.find(b'(') + 1:rpar]
|
|
fields = data[rpar + 2:].split()
|
|
|
|
ret['name'] = name
|
|
ret['status'] = fields[0]
|
|
ret['ppid'] = fields[1]
|
|
ret['ttynr'] = fields[4]
|
|
ret['utime'] = fields[11]
|
|
ret['stime'] = fields[12]
|
|
ret['children_utime'] = fields[13]
|
|
ret['children_stime'] = fields[14]
|
|
ret['create_time'] = fields[19]
|
|
ret['cpu_num'] = fields[36]
|
|
ret['blkio_ticks'] = fields[39] # aka 'delayacct_blkio_ticks'
|
|
except (PermissionError, ProcessLookupError, FileNotFoundError):
|
|
ret['name'] = ''
|
|
ret['status'] = ''
|
|
ret['ppid'] = ''
|
|
ret['ttynr'] = ''
|
|
ret['utime'] = ''
|
|
ret['stime'] = ''
|
|
ret['children_utime'] = ''
|
|
ret['children_stime'] = ''
|
|
ret['create_time'] = ''
|
|
ret['cpu_num'] = ''
|
|
ret['blkio_ticks'] = '' # aka 'delayacct_blkio_ticks'
|
|
return ret
|
|
|
|
@staticmethod
|
|
def check_process_alive(proc_name: str) -> bool:
|
|
"""Check process running.
|
|
|
|
:param proc_name: process name
|
|
:type proc_name: str
|
|
:return: True if process running, otherwise False
|
|
:rtype: bool
|
|
"""
|
|
# Iterate over the all the running process
|
|
for proc in psutil.process_iter():
|
|
try:
|
|
# Check if process name equals to the given name string.
|
|
if proc_name.lower() == proc.name().lower():
|
|
return True
|
|
except (
|
|
psutil.NoSuchProcess, psutil.AccessDenied,
|
|
psutil.ZombieProcess
|
|
):
|
|
pass
|
|
return False
|