PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /opt/sharedrads/python/send_customer_str/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //opt/sharedrads/python/send_customer_str/check_dcpumon |
#!/opt/imh-python/bin/python3 """Displays dcpumon info for one user as an HTML table""" import argparse import subprocess import os import re import time import pty import errno import select from prettytable import PrettyTable import rads def parse_args(): """Parse sys.argv""" parser = argparse.ArgumentParser(description=__doc__) # --user is only for backwards compat parser.add_argument( '-u', '--user', action='store_true', dest='u', help=argparse.SUPPRESS ) parser.add_argument('user', help='cPanel username') args = parser.parse_args() if not rads.is_cpuser(args.user): print(rads.color.red(f"Not a valid cPanel user: {args.user}")) return args.user def dcpumon() -> str: """Run dcpumonview {24h ago} {now} and return stdout as a str""" # master_fd, slave_fd = pty.openpty() start = str(int(time.time()) - 86400) # 24h ago stop = str(int(time.time())) # now cmd = ['/usr/local/cpanel/bin/dcpumonview', start, stop] # dcpumonview prints HTML if it thinks it's not attached to a TTY stdout = tty_capture(cmd) return str(stdout, 'utf-8', 'ignore') def tty_capture(cmd: list[str]) -> bytes: """Run a subprocess with PTYs attached""" # https://stackoverflow.com/a/52954716 # https://stackoverflow.com/a/70166246 m_out, s_out = pty.openpty() m_err, s_err = pty.openpty() m_in, s_in = pty.openpty() with subprocess.Popen( cmd, bufsize=1, stdin=s_in, stdout=s_out, stderr=s_err, close_fds=True, env={"LINES": "40", "COLUMNS": "200", "TERM": "xterm-256color"}, ) as proc: for ready_fd in [s_out, s_err, s_in]: os.close(ready_fd) timeout = 0.04 readable = [m_out, m_err] result = {m_out: b'', m_err: b''} try: while readable: ready, _, _ = select.select(readable, [], [], timeout) for ready_fd in ready: try: data = os.read(ready_fd, 512) except OSError as e: if e.errno != errno.EIO: raise readable.remove(ready_fd) else: if not data: # EOF readable.remove(ready_fd) result[ready_fd] += data finally: for ready_fd in [m_out, m_err, m_in]: os.close(ready_fd) if proc.poll() is None: proc.kill() proc.wait() # stderr is result[m_err], but we don't use that in this script return result[m_out] def check_dcpumon(user: str): """Filter dcpumon output for one user and output as an html table""" hitfound = False tbl_data = False tbl = PrettyTable([f"Top Process for {user}"]) tbl.align[f"Top Process for {user}"] = 'l' user_re = re.compile(r'\|' + re.escape(user) + r'[_\s]*\|') # |userna5_|example.com |0.00|0.00|0.0 | # | Top Process | 0.1 | dovecot/imap | # |userna6 |example2.com |0.00|0.00|0.0 | for line in dcpumon().splitlines(): if user_re.match(line): hitfound = True continue if not hitfound: continue if line.startswith('| Top'): cmd = line.strip(' |').split('|')[-1].strip(' |') tbl_data = True tbl.add_row([cmd]) else: hitfound = False if tbl_data: print(tbl.get_html_string(attributes={"class": "proc_body"})) def main(): """Displays dcpumon info for one user as an HTML table""" user = parse_args() check_dcpumon(user) if __name__ == "__main__": main()