This commit is contained in:
devdatt 2026-02-18 17:49:52 +05:30
parent a6009a1085
commit d21816c93e
2 changed files with 157 additions and 94 deletions

View File

@ -246,124 +246,181 @@ WantedBy=multi-user.target
EOL EOL
cat > /usr/local/bin/nginx_system_monitor_sampler.py<< 'EOL' cat > /usr/local/bin/nginx_system_monitor_sampler.py<< 'EOL'
#!/usr/bin/env python3 #!/usr/bin/env python3 -u
import time, json, os, subprocess import time
from collections import deque import json
from datetime import datetime import os
import subprocess
import threading
import re
import psutil import psutil
import shutil
from collections import deque
from datetime import datetime, timezone
# ---------------- CONFIGURATION ----------------
OUT_FILE = "/var/www/encoder/metrics.json" OUT_FILE = "/var/www/encoder/metrics.json"
TMP_FILE = OUT_FILE + ".tmp" TMP_FILE = OUT_FILE + ".tmp"
SAMPLE_INTERVAL = 10.0 SAMPLE_INTERVAL = 10.0
HISTORY_SECONDS = 15 * 60 HISTORY_SECONDS = 15 * 60
MAX_SAMPLES = int(HISTORY_SECONDS / SAMPLE_INTERVAL) MAX_SAMPLES = int(HISTORY_SECONDS / SAMPLE_INTERVAL)
timestamps=deque(maxlen=MAX_SAMPLES) # ---------------- DEPENDENCY CHECK ----------------
cpu_hist=deque(maxlen=MAX_SAMPLES) if not shutil.which("intel_gpu_top"):
ram_hist=deque(maxlen=MAX_SAMPLES) raise RuntimeError("intel_gpu_top not installed or not in PATH")
gpu_hist=deque(maxlen=MAX_SAMPLES)
net_in_hist=deque(maxlen=MAX_SAMPLES) # ---------------- HISTORY BUFFERS ----------------
net_out_hist=deque(maxlen=MAX_SAMPLES) keys = [
disk_read_hist=deque(maxlen=MAX_SAMPLES) "timestamps", "cpu_percent", "ram_percent", "gpu_total", "gpu_render",
disk_write_hist=deque(maxlen=MAX_SAMPLES) "gpu_video", "gpu_blitter", "gpu_videoenhance", "net_in_Bps",
disk_percent_hist=deque(maxlen=MAX_SAMPLES) "net_out_Bps", "disk_read_Bps", "disk_write_Bps", "disk_percent"
]
hist = {k: deque(maxlen=MAX_SAMPLES) for k in keys}
_prev_net = psutil.net_io_counters() _prev_net = psutil.net_io_counters()
_prev_disk = psutil.disk_io_counters() _prev_disk = psutil.disk_io_counters()
_prev_time = time.time() _prev_time = time.time()
def igpu_percent(): # Prime CPU measurement
try: psutil.cpu_percent(None)
out = subprocess.check_output(
["intel_gpu_top","-J","-s","200","-o","-"],
stderr=subprocess.DEVNULL,
timeout=2
)
line = out.decode().splitlines()[0]
data = json.loads(line)
engines = data.get("engines",{})
if not engines:
return 0.0
return round(max(v.get("busy",0) for v in engines.values()),2)
except Exception:
return 0.0
gpu_data = {"total": 0.0, "render": 0.0, "video": 0.0, "blitter": 0.0, "ve": 0.0}
gpu_lock = threading.Lock()
# ---------------- GPU MONITOR THREAD ----------------
def gpu_monitor():
global gpu_data
cmd = ["intel_gpu_top", "-J", "-s", "1000"]
while True:
try:
p = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.DEVNULL,
text=True,
bufsize=1
)
buf = ""
brace = 0
for chunk in iter(lambda: p.stdout.read(1), ""):
if chunk == "{":
brace += 1
if brace > 0:
buf += chunk
if chunk == "}":
brace -= 1
if brace == 0 and buf.strip():
try:
obj = json.loads(buf)
engines = obj.get("engines", {})
r = v = b = e = 0.0
for name, data in engines.items():
busy = float(data.get("busy", 0.0))
n = name.lower()
if "render" in n or "rcs" in n:
r = max(r, busy)
elif "video" in n or "vcs" in n:
v = max(v, busy)
elif "blitter" in n or "bcs" in n:
b = max(b, busy)
elif "enhance" in n or "vecs" in n:
e = max(e, busy)
with gpu_lock:
gpu_data["render"] = r
gpu_data["video"] = v
gpu_data["blitter"] = b
gpu_data["ve"] = e
gpu_data["total"] = max(r, v, b, e)
except Exception:
pass
buf = ""
p.wait()
except Exception:
time.sleep(2)
# ---------------- SAMPLING ----------------
def sample_once(): def sample_once():
global _prev_net, _prev_disk, _prev_time global _prev_net, _prev_disk, _prev_time
now = time.time() now = time.time()
iso=datetime.fromtimestamp(now).isoformat(timespec='seconds') elapsed = max(now - _prev_time, 0.1)
cpu=psutil.cpu_percent(interval=None) cpu = psutil.cpu_percent()
ram = psutil.virtual_memory().percent ram = psutil.virtual_memory().percent
gpu=igpu_percent()
net = psutil.net_io_counters() net = psutil.net_io_counters()
disk = psutil.disk_io_counters() disk = psutil.disk_io_counters()
try: in_r = (net.bytes_recv - _prev_net.bytes_recv) / elapsed
disk_percent=psutil.disk_usage("/").percent out_r = (net.bytes_sent - _prev_net.bytes_sent) / elapsed
except: read_r = (disk.read_bytes - _prev_disk.read_bytes) / elapsed
disk_percent=0.0 write_r = (disk.write_bytes - _prev_disk.write_bytes) / elapsed
elapsed=now-_prev_time if _prev_time else SAMPLE_INTERVAL with gpu_lock:
if elapsed<=0: elapsed=SAMPLE_INTERVAL g = gpu_data.copy()
in_rate=int(((net.bytes_recv-_prev_net.bytes_recv)/elapsed)) # stale GPU protection
out_rate=int(((net.bytes_sent-_prev_net.bytes_sent)/elapsed)) if time.time() - _prev_time > SAMPLE_INTERVAL * 2:
g = {"total": 0, "render": 0, "video": 0, "blitter": 0, "ve": 0}
read_rate=(disk.read_bytes-_prev_disk.read_bytes)/elapsed hist["timestamps"].append(datetime.now().isoformat(timespec='seconds'))
write_rate=(disk.write_bytes-_prev_disk.write_bytes)/elapsed hist["cpu_percent"].append(round(cpu, 1))
hist["ram_percent"].append(round(ram, 1))
hist["net_in_Bps"].append(int(max(0, in_r)))
hist["net_out_Bps"].append(int(max(0, out_r)))
hist["disk_read_Bps"].append(int(max(0, read_r)))
hist["disk_write_Bps"].append(int(max(0, write_r)))
hist["disk_percent"].append(round(psutil.disk_usage('/').percent, 1))
hist["gpu_total"].append(round(g["total"], 1))
hist["gpu_render"].append(round(g["render"], 1))
hist["gpu_video"].append(round(g["video"], 1))
hist["gpu_blitter"].append(round(g["blitter"], 1))
hist["gpu_videoenhance"].append(round(g["ve"], 1))
timestamps.append(iso) _prev_net, _prev_disk, _prev_time = net, disk, now
cpu_hist.append(round(cpu,2))
ram_hist.append(round(ram,2))
gpu_hist.append(round(gpu,2))
net_in_hist.append(int(in_rate))
net_out_hist.append(int(out_rate))
disk_read_hist.append(int(read_rate))
disk_write_hist.append(int(write_rate))
disk_percent_hist.append(round(disk_percent,2))
_prev_net=net
_prev_disk=disk
_prev_time=now
def write_json_atomic():
payload={
"timestamps":list(timestamps),
"cpu_percent":list(cpu_hist),
"ram_percent":list(ram_hist),
"igpu_percent":list(gpu_hist),
"net_in_Bps":list(net_in_hist),
"net_out_Bps":list(net_out_hist),
"disk_read_Bps":list(disk_read_hist),
"disk_write_Bps":list(disk_write_hist),
"disk_percent":list(disk_percent_hist),
"sample_interval":SAMPLE_INTERVAL,
"generated_at":datetime.utcnow().isoformat(timespec='seconds')+"Z"
}
with open(TMP_FILE,"w") as f: json.dump(payload,f)
os.replace(TMP_FILE,OUT_FILE)
# ---------------- MAIN LOOP ----------------
def main(): def main():
global _prev_net,_prev_disk,_prev_time threading.Thread(target=gpu_monitor, daemon=True).start()
_prev_net=psutil.net_io_counters()
_prev_disk=psutil.disk_io_counters()
_prev_time=time.time()
time.sleep(0.2)
while True: while True:
try: try:
sample_once() sample_once()
write_json_atomic()
except Exception as e: payload = {k: list(v) for k, v in hist.items()}
print("Sampler error:",e) payload.update({
"sample_interval": SAMPLE_INTERVAL,
"generated_at": datetime.now(timezone.utc).isoformat()
})
with open(TMP_FILE, "w") as f:
json.dump(payload, f)
os.replace(TMP_FILE, OUT_FILE)
except Exception:
pass
time.sleep(SAMPLE_INTERVAL) time.sleep(SAMPLE_INTERVAL)
# ---------------- ENTRY ----------------
if __name__ == "__main__": if __name__ == "__main__":
main() main()
EOL
EOL
sudo mkdir -p /etc/srt/; sudo mkdir -p /etc/srt/;
cat > /etc/srt/srt.sh<< 'EOL' cat > /etc/srt/srt.sh<< 'EOL'

View File

@ -1,3 +1,9 @@
sudo apt update
sudo apt upgrade -y
sudo apt install -y apache2 php libapache2-mod-php vainfo ufw intel-media-va-driver-non-free libavcodec-extra mesa-utils i965-va-driver libmfx1 certbot intel-gpu-tools python3-certbot-nginx ffmpeg nginx v4l-utils python3-pip mpv libnginx-mod-rtmp alsa-utils vlan git zlib1g-dev php-zip php-curl
sudo pip3 install psutil --break-system-packages
sudo cp -r encoder/* /var/www/encoder/ sudo cp -r encoder/* /var/www/encoder/
sudo cp -r html/* /var/www/html/ sudo cp -r html/* /var/www/html/
sudo cp attempts.json /var/www/attempts.json sudo cp attempts.json /var/www/attempts.json