fix: Agent network and disk metrics for VPS
Network: - Remove speed > 0 check in _is_real_interface() - Use 1000 Mbps default for interfaces with speed=0 - This allows virtual interfaces (ens3) to be detected - Remove network_rx/network_tx (no longer needed) Disk: - Rewrite get_disk_metrics() to detect unique devices - If only one device (/) - create only disk_used_root - If multiple devices - create for each - This fixes VPS with single disk showing same % for all mounts
This commit is contained in:
parent
c8d0bc4a40
commit
f1fc514a33
Binary file not shown.
105
agent.py
105
agent.py
|
|
@ -21,8 +21,6 @@ def _is_real_interface(name, stats):
|
||||||
return False
|
return False
|
||||||
if not stats.isup:
|
if not stats.isup:
|
||||||
return False
|
return False
|
||||||
if stats.speed <= 0:
|
|
||||||
return False
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -38,7 +36,7 @@ def get_network_metrics(interval=60):
|
||||||
continue
|
continue
|
||||||
if not _is_real_interface(name, stats[name]):
|
if not _is_real_interface(name, stats[name]):
|
||||||
continue
|
continue
|
||||||
speed_mbps = stats[name].speed
|
speed_mbps = stats[name].speed if stats[name].speed > 0 else 1000
|
||||||
speed_bps = speed_mbps * 1000000 / 8
|
speed_bps = speed_mbps * 1000000 / 8
|
||||||
if name in _prev_net_io:
|
if name in _prev_net_io:
|
||||||
prev = _prev_net_io[name]
|
prev = _prev_net_io[name]
|
||||||
|
|
@ -78,38 +76,63 @@ def _is_real_partition(mountpoint, fstype):
|
||||||
|
|
||||||
|
|
||||||
def get_disk_metrics():
|
def get_disk_metrics():
|
||||||
"""Собираем метрики диска для примонтированных разделов"""
|
"""Собираем метрики диска для реальных разделов"""
|
||||||
metrics = {}
|
metrics = {}
|
||||||
total_used = 0
|
skip_fstypes = {'tmpfs', 'devtmpfs', 'overlay', 'squashfs', 'snap',
|
||||||
total_capacity = 0
|
'devpts', 'proc', 'sysfs', 'cgroup', 'cgroup2',
|
||||||
|
'pstore', 'hugetlbfs', 'mqueue', 'debugfs',
|
||||||
priority_mounts = ['/', '/home', '/boot', '/var', '/opt', '/data', '/mnt', '/srv', '/tmp']
|
'tracefs', 'bpf', 'fusectl', 'configfs',
|
||||||
|
'securityfs', 'ramfs'}
|
||||||
for mountpoint in priority_mounts:
|
skip_mounts = {'/run', '/run/lock', '/sys', '/proc', '/dev',
|
||||||
try:
|
'/dev/shm', '/dev/pts', '/sys/fs/cgroup'}
|
||||||
usage = psutil.disk_usage(mountpoint)
|
|
||||||
name = mountpoint.strip('/').replace('/', '_') or 'root'
|
|
||||||
if name not in metrics:
|
|
||||||
metrics[f'disk_used_{name}'] = round(usage.percent, 1)
|
|
||||||
total_used += usage.used
|
|
||||||
total_capacity += usage.total
|
|
||||||
except (PermissionError, OSError, FileNotFoundError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
# Собираем реальные разделы с их устройствами
|
||||||
|
partitions = []
|
||||||
for part in psutil.disk_partitions(all=False):
|
for part in psutil.disk_partitions(all=False):
|
||||||
name = part.mountpoint.strip('/').replace('/', '_') or 'root'
|
if part.fstype in skip_fstypes:
|
||||||
if name in metrics:
|
|
||||||
continue
|
continue
|
||||||
if not _is_real_partition(part.mountpoint, part.fstype):
|
if part.mountpoint in skip_mounts:
|
||||||
|
continue
|
||||||
|
if part.mountpoint == '/boot/efi':
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
usage = psutil.disk_usage(part.mountpoint)
|
usage = psutil.disk_usage(part.mountpoint)
|
||||||
metrics[f'disk_used_{name}'] = round(usage.percent, 1)
|
partitions.append({
|
||||||
|
'mountpoint': part.mountpoint,
|
||||||
|
'device': part.device,
|
||||||
|
'usage': usage
|
||||||
|
})
|
||||||
except (PermissionError, OSError):
|
except (PermissionError, OSError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if total_capacity > 0:
|
# Определяем уникальные устройства
|
||||||
metrics['disk_used'] = round((total_used / total_capacity) * 100, 1)
|
devices = {}
|
||||||
|
for p in partitions:
|
||||||
|
dev = p['device']
|
||||||
|
if dev not in devices:
|
||||||
|
devices[dev] = []
|
||||||
|
devices[dev].append(p)
|
||||||
|
|
||||||
|
# Если одно устройство - только /
|
||||||
|
# Если несколько - для каждого отдельного устройства
|
||||||
|
if len(devices) == 1:
|
||||||
|
# Один диск - только корень
|
||||||
|
for p in partitions:
|
||||||
|
if p['mountpoint'] == '/':
|
||||||
|
metrics['disk_used_root'] = round(p['usage'].percent, 1)
|
||||||
|
metrics['disk_total_gb_root'] = round(p['usage'].total / (1024**3), 1)
|
||||||
|
metrics['disk_used'] = round(p['usage'].percent, 1)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# Несколько устройств - собираем для каждого
|
||||||
|
for dev, parts in devices.items():
|
||||||
|
for p in parts:
|
||||||
|
mp = p['mountpoint']
|
||||||
|
name = mp.strip('/').replace('/', '_') or 'root'
|
||||||
|
metrics[f'disk_used_{name}'] = round(p['usage'].percent, 1)
|
||||||
|
metrics[f'disk_total_gb_{name}'] = round(p['usage'].total / (1024**3), 1)
|
||||||
|
if mp == '/':
|
||||||
|
metrics['disk_used'] = round(p['usage'].percent, 1)
|
||||||
|
|
||||||
return metrics
|
return metrics
|
||||||
|
|
||||||
|
|
@ -122,12 +145,6 @@ def get_metrics():
|
||||||
# Дисковые метрики для всех реальных разделов
|
# Дисковые метрики для всех реальных разделов
|
||||||
disk_metrics = get_disk_metrics()
|
disk_metrics = get_disk_metrics()
|
||||||
|
|
||||||
# Получаем сетевую статистику
|
|
||||||
try:
|
|
||||||
net_io = psutil.net_io_counters()
|
|
||||||
except:
|
|
||||||
net_io = None
|
|
||||||
|
|
||||||
result = {
|
result = {
|
||||||
'cpu_load': cpu_percent,
|
'cpu_load': cpu_percent,
|
||||||
'ram_used': memory.percent,
|
'ram_used': memory.percent,
|
||||||
|
|
@ -137,37 +154,13 @@ def get_metrics():
|
||||||
# Метрики использования сети
|
# Метрики использования сети
|
||||||
net_metrics = get_network_metrics()
|
net_metrics = get_network_metrics()
|
||||||
result.update(net_metrics)
|
result.update(net_metrics)
|
||||||
|
|
||||||
# RAM total GB
|
# RAM total GB
|
||||||
result["ram_total_gb"] = round(memory.total / (1024**3), 1)
|
result["ram_total_gb"] = round(memory.total / (1024**3), 1)
|
||||||
|
|
||||||
# Disk total GB - сначала приоритетные mountpoints
|
|
||||||
priority_mounts = ['/', '/home', '/boot', '/var', '/opt', '/data', '/mnt', '/srv', '/tmp']
|
|
||||||
for mountpoint in priority_mounts:
|
|
||||||
try:
|
|
||||||
usage = psutil.disk_usage(mountpoint)
|
|
||||||
name = mountpoint.strip("/").replace("/", "_") or "root"
|
|
||||||
if f"disk_total_gb_{name}" not in result:
|
|
||||||
result[f"disk_total_gb_{name}"] = round(usage.total / (1024**3), 1)
|
|
||||||
except (PermissionError, OSError, FileNotFoundError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
for part in psutil.disk_partitions(all=False):
|
|
||||||
try:
|
|
||||||
usage = psutil.disk_usage(part.mountpoint)
|
|
||||||
name = part.mountpoint.strip("/").replace("/", "_") or "root"
|
|
||||||
if f"disk_total_gb_{name}" not in result:
|
|
||||||
result[f"disk_total_gb_{name}"] = round(usage.total / (1024**3), 1)
|
|
||||||
except (PermissionError, OSError):
|
|
||||||
pass
|
|
||||||
|
|
||||||
if net_metrics:
|
if net_metrics:
|
||||||
print(f" Сетевые метрики: {net_metrics}")
|
print(f" Сетевые метрики: {net_metrics}")
|
||||||
|
|
||||||
# Сетевые метрики
|
|
||||||
if net_io:
|
|
||||||
result['network_rx'] = round(net_io.bytes_recv / (1024 * 1024), 2)
|
|
||||||
result['network_tx'] = round(net_io.bytes_sent / (1024 * 1024), 2)
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def get_top_processes(process_type='cpu'):
|
def get_top_processes(process_type='cpu'):
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue