fix(dashboard): report application memory accurately

This commit is contained in:
jxxghp
2026-06-29 07:37:03 +08:00
parent df4e45c644
commit 8bf826faa0
4 changed files with 29 additions and 15 deletions
+4 -4
View File
@@ -254,24 +254,24 @@ def cpu2(_: Annotated[str, Depends(verify_apitoken)]) -> Any:
@router.get( @router.get(
"/memory", "/memory",
summary="获取当前系统内存信息", summary="获取当前应用与系统内存信息",
response_model=schemas.DashboardMemoryInfo, response_model=schemas.DashboardMemoryInfo,
) )
def memory(_: Any = Depends(get_current_active_superuser)) -> Any: def memory(_: Any = Depends(get_current_active_superuser)) -> Any:
""" """
获取当前系统内存信息 获取当前应用与系统内存信息
""" """
return SystemUtils.memory_usage() return SystemUtils.memory_usage()
@router.get( @router.get(
"/memory2", "/memory2",
summary="获取当前系统内存信息(API_TOKEN)", summary="获取当前应用与系统内存信息(API_TOKEN",
response_model=schemas.DashboardMemoryInfo, response_model=schemas.DashboardMemoryInfo,
) )
def memory2(_: Annotated[str, Depends(verify_apitoken)]) -> Any: def memory2(_: Annotated[str, Depends(verify_apitoken)]) -> Any:
""" """
获取当前系统内存信息 API_TOKEN认证(?token=xxx 获取当前应用与系统内存信息 API_TOKEN认证(?token=xxx
""" """
return SystemUtils.memory_usage() return SystemUtils.memory_usage()
+3 -3
View File
@@ -66,17 +66,17 @@ class DownloaderInfo(BaseModel):
class DashboardMemoryInfo(BaseModel): class DashboardMemoryInfo(BaseModel):
"""仪表板系统内存统计。""" """仪表板应用进程与系统内存统计。"""
# 总内存字节数 # 总内存字节数
total: int = 0 total: int = 0
# 使用内存字节数,不包含缓存 # 当前 MoviePilot 进程使用内存字节数
used: int = 0 used: int = 0
# 缓存与缓冲区占用字节数 # 缓存与缓冲区占用字节数
cached: int = 0 cached: int = 0
# 可用内存字节数 # 可用内存字节数
available: int = 0 available: int = 0
# 使用内存占总内存百分比,不包含缓存 # 当前 MoviePilot 进程使用内存占总内存百分比
usage: float = 0.0 usage: float = 0.0
+3 -3
View File
@@ -689,17 +689,17 @@ class SystemUtils:
@staticmethod @staticmethod
def memory_usage() -> schemas.DashboardMemoryInfo: def memory_usage() -> schemas.DashboardMemoryInfo:
""" """
获取系统已使用、缓存、可用和总内存信息。 获取当前 MoviePilot 进程内存与系统缓存、可用和总内存信息。
""" """
memory = psutil.virtual_memory() memory = psutil.virtual_memory()
total = max(0, int(memory.total)) total = max(0, int(memory.total))
used = max(0, int(memory.used)) used = max(0, int(psutil.Process().memory_info().rss))
cached = max( cached = max(
0, 0,
int(getattr(memory, "cached", 0) or 0) int(getattr(memory, "cached", 0) or 0)
+ int(getattr(memory, "buffers", 0) or 0), + int(getattr(memory, "buffers", 0) or 0),
) )
available = max(0, total - used - cached) available = max(0, int(memory.available))
usage = used / total * 100 if total else 0.0 usage = used / total * 100 if total else 0.0
return schemas.DashboardMemoryInfo( return schemas.DashboardMemoryInfo(
total=total, total=total,
+19 -5
View File
@@ -31,25 +31,39 @@ def test_dashboard_system_info_returns_runtime_environment(monkeypatch):
def test_memory_usage_returns_used_cached_and_available(monkeypatch): def test_memory_usage_returns_used_cached_and_available(monkeypatch):
"""内存统计应拆分已使用、缓存可用容量,并返回已使用百分比""" """内存统计应返回应用进程占用以及系统缓存可用和总容量。"""
class FakeMemoryInfo:
"""提供固定进程 RSS 的桩。"""
rss = 2 * 1024**3
class FakeProcess:
"""提供固定进程内存信息的桩。"""
@staticmethod
def memory_info() -> FakeMemoryInfo:
"""返回固定进程内存信息。"""
return FakeMemoryInfo()
class FakeMemory: class FakeMemory:
"""提供固定系统内存值的桩。""" """提供固定系统内存值的桩。"""
total = 16 * 1024**3 total = 16 * 1024**3
used = 5 * 1024**3
cached = 3 * 1024**3 cached = 3 * 1024**3
buffers = 512 * 1024**2 buffers = 512 * 1024**2
available = 7 * 1024**3
monkeypatch.setattr(system_module.psutil, "Process", FakeProcess)
monkeypatch.setattr(system_module.psutil, "virtual_memory", FakeMemory) monkeypatch.setattr(system_module.psutil, "virtual_memory", FakeMemory)
result = SystemUtils.memory_usage() result = SystemUtils.memory_usage()
assert result.total == 16 * 1024**3 assert result.total == 16 * 1024**3
assert result.used == 5 * 1024**3 assert result.used == 2 * 1024**3
assert result.cached == int(3.5 * 1024**3) assert result.cached == int(3.5 * 1024**3)
assert result.available == int(7.5 * 1024**3) assert result.available == 7 * 1024**3
assert result.usage == 31.25 assert result.usage == 12.5
def test_monthly_media_statistics_counts_successful_unique_media(): def test_monthly_media_statistics_counts_successful_unique_media():