/
opt
/
dedrads
/
/opt/dedrads
mkdir
upload
Name
Size
Mode
Actions
account_review/
-
0555
rm
check_software_mods/
-
0555
rm
cms_tools/
-
0555
rm
etc/
-
0555
rm
extras/
-
0555
rm
mailparse/
-
0555
rm
mysql/
-
0555
rm
nlp_scripts/
-
0555
rm
oldrads/
-
0555
rm
perl/
-
0555
rm
provision/
-
0555
rm
python/
-
0555
rm
suspended/
-
0555
rm
__pycache__/
-
0555
rm
account-review
799
0555
edit
dl
rm
allfw
6259
0555
edit
dl
rm
alp.py
16553
0555
edit
dl
rm
autossl_sync
6267
0555
edit
dl
rm
check_apache
9205
0555
edit
dl
rm
check_bandwidth
4546
0555
edit
dl
rm
check_boxtrapper
1684
0555
edit
dl
rm
check_cpu
12212
0555
edit
dl
rm
check_crons
1827
0555
edit
dl
rm
check_dcpumon
1973
0555
edit
dl
rm
check_dns
1827
0555
edit
dl
rm
check_domlogs
61
0555
edit
dl
rm
check_exim
3731
0555
edit
dl
rm
check_hacks
22604
0555
edit
dl
rm
check_imap
5249
0555
edit
dl
rm
check_io
6635
0555
edit
dl
rm
check_max_children
16341
0555
edit
dl
rm
check_mem
1660
0555
edit
dl
rm
check_misc
1510
0555
edit
dl
rm
check_pacct
5201
0555
edit
dl
rm
check_php
4344
0555
edit
dl
rm
check_pop3
2295
0555
edit
dl
rm
check_prov.py
4714
0555
edit
dl
rm
check_server
696
0555
edit
dl
rm
check_size
490
0555
edit
dl
rm
check_software
9849
0555
edit
dl
rm
check_spamd
2426
0555
edit
dl
rm
check_traffic
1933
0555
edit
dl
rm
check_user
1887
0555
edit
dl
rm
clean_exim.py
6390
0555
edit
dl
rm
clusterfix
5343
0555
edit
dl
rm
cmspass.py
3970
0555
edit
dl
rm
cms_check.py
9825
0555
edit
dl
rm
cms_counter.py
36734
0555
edit
dl
rm
cms_creds
713
0555
edit
dl
rm
cms_dumpdb
4485
0555
edit
dl
rm
cms_pw
1416
0555
edit
dl
rm
cpanel-api
7040
0555
edit
dl
rm
cpanel_postgres_manager.py
29004
0555
edit
dl
rm
cpmerge
4631
0555
edit
dl
rm
cpumon
2195
0555
edit
dl
rm
dcpumon.pl
1239
0555
edit
dl
rm
dedcheck
18127
0555
edit
dl
rm
dns-sync
14386
0555
edit
dl
rm
docroot.py
4425
0555
edit
dl
rm
du-tree
7450
0555
edit
dl
rm
envinfo.py
6633
0555
edit
dl
rm
exclude_rbl.py
5249
0555
edit
dl
rm
extract-vhost
2691
0555
edit
dl
rm
filescan
3566
0555
edit
dl
rm
find_warez
1460
0555
edit
dl
rm
first_setup.py
19120
0555
edit
dl
rm
fixwpcron.py
4822
0555
edit
dl
rm
fix_dns_cluster
353
0555
edit
dl
rm
goaccess
1217720
0555
edit
dl
rm
hostsfilemods
4467
0555
edit
dl
rm
imap_io
2323
0555
edit
dl
rm
innodb_converter.py
9343
0555
edit
dl
rm
killall911
530
0555
edit
dl
rm
killdns
941
0555
edit
dl
rm
lastcommcache.sh
1374
0555
edit
dl
rm
legal_lock_down.sh
7450
0555
edit
dl
rm
lil-cpanel
52002
0555
edit
dl
rm
listacct
4575
0555
edit
dl
rm
mailscan
4544
0555
edit
dl
rm
mail_sources.py
7407
0555
edit
dl
rm
megaclisas-status
38664
0555
edit
dl
rm
migrate2central.sh
14418
0555
edit
dl
rm
modify-account
40631
0555
edit
dl
rm
modsec_disable.py
11461
0555
edit
dl
rm
monarxctl
8912
0555
edit
dl
rm
msp.pl
27714
0555
edit
dl
rm
mysql_dstat
474
0555
edit
dl
rm
mysql_selector.py
73102
0555
edit
dl
rm
nlp
4582
0555
edit
dl
rm
procscrape
1863
0555
edit
dl
rm
quarantine
11083
0555
edit
dl
rm
radsfunctions.sh
863
0555
edit
dl
rm
recent-cp
16148
0555
edit
dl
rm
remote_dump
18347
0555
edit
dl
rm
reset_cpanel
3205
0555
edit
dl
rm
server-load
2192
0555
edit
dl
rm
show-conns
20105
0555
edit
dl
rm
show-conns-adv.py
54667
0555
edit
dl
rm
sparta.py
382498
0555
edit
dl
rm
sqltop
27129
0555
edit
dl
rm
telcheck
2411
0555
edit
dl
rm
temprootreset
186
0555
edit
dl
rm
unsuspend_user
1307
0555
edit
dl
rm
unsusprunner.sh
1840
0555
edit
dl
rm
updatednsadmin
526
0555
edit
dl
rm
update_spf
14972
0555
edit
dl
rm
upgrade-check
9216
0555
edit
dl
rm
vhost_data.py
6221
0555
edit
dl
rm
wp-xray.sh
85816
0555
edit
dl
rm
Edit:
/opt/dedrads/check_pacct
(5201B)
#!/usr/lib/rads/venv/bin/python3 import argparse import re import subprocess from collections import defaultdict from datetime import datetime, timedelta from prettytable import PrettyTable from rads import is_cpuser, get_plan def parse_args(): parser = argparse.ArgumentParser( description="Process pacct files and total CPU time for cPanel users." ) parser.add_argument( "--days", type=int, default=10, help="Number of pacct files to process (default: 10)", ) parser.add_argument( "-l", "--limit-users", type=int, default=5, help="Number users to display (default: 5)", ) parser.add_argument( "--date", type=str, default=datetime.today().strftime("%Y-%m-%d"), help="Start date in format YYYY-MM-DD (default: today)", ) return parser.parse_args() def get_pacct_files(start_date: str, days: int): """ Generate a list of process accounting (pacct) file paths for a given number of days. Args: start_date (str): The start date in 'YYYY-MM-DD' format. days (int): The number of days of pacct files to retrieve. Returns: list[str]: A list of file paths to the compressed pacct logs in `/var/account/`, named in the format `pacct-YYYYMMDD.gz`. Raises: ValueError: If `start_date` is not in the correct 'YYYY-MM-DD' format. Notes: - If `start_date` is today, the function returns files from the previous `days` days. - Otherwise, it returns files counting backward from the given `start_date`. """ try: start = datetime.strptime(start_date, "%Y-%m-%d") except ValueError as exc: raise ValueError("Date must be in YYYY-MM-DD format.") from exc today = datetime.today().date() start_date_obj = start.date() files = [] if start_date_obj == today: for i in range(1, days + 1): day = today - timedelta(days=i) files.append(f"/var/account/pacct-{day.strftime('%Y%m%d')}.gz") else: for i in range(days): day = start_date_obj - timedelta(days=i) files.append(f"/var/account/pacct-{day.strftime('%Y%m%d')}.gz") return files def process_pacct_file(file_path): """ Run 'zcat' on a compressed pacct file and pipe the output to 'sa -cmi -'. Returns the output lines from the 'sa' command as a list of strings. """ try: with subprocess.Popen( ["zcat", file_path], stdout=subprocess.PIPE ) as zcat_proc: with subprocess.Popen( ["sa", "-cmi", "-"], stdin=zcat_proc.stdout, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, ) as sa_proc: zcat_proc.stdout.close() stdout, stderr = sa_proc.communicate() if sa_proc.returncode != 0: print("Error running sa:", stderr) return [] return stdout.splitlines() except Exception as e: print(f"Failed to process {file_path}: {str(e)}") return [] def main(): args = parse_args() pacct_files = get_pacct_files(args.date, args.days) sa_cp_data = defaultdict(float) sa_proc_data = defaultdict(int) sa_top_user = defaultdict(int) for file_path in pacct_files: pacct_data = process_pacct_file(file_path) try: i = 1 for line in pacct_data: columns = re.split(r"\s+", line.strip()) if is_cpuser(columns[0]): try: username = columns[0] num_proc = int(columns[1]) cpu_time = float(columns[5].replace("cp", "")) sa_cp_data[username] += cpu_time sa_proc_data[username] += num_proc if i <= args.limit_users: sa_top_user[username] += 1 i += 1 except ValueError: continue except Exception as e: print(f"Failed to process {file_path}: {str(e)}") top_users = sorted(sa_cp_data.items(), key=lambda x: x[1], reverse=True) table = PrettyTable() table.field_names = [ "Username", "Total CPU", "Average CPU/day", "Total Procs", "Average Procs/day", f"Days in top {args.limit_users}", "Plan", ] num_days = len(pacct_files) for ( username, total_cpu_time, ) in top_users[: args.limit_users]: table.add_row( [ username, f"{total_cpu_time:.2f}cp", f"{(total_cpu_time / num_days):.2f}cp", f"{sa_proc_data[username]}", f"{(sa_proc_data[username] / num_days):.2f}", f"{sa_top_user[username]}/{num_days}", get_plan(username), ] ) print(table) if __name__ == "__main__": main()
Save
cmd:
run