feat(controller): extend /statistics API with project, node and link stats

Return aggregated statistics:
- computes: per-compute CPU/memory/disk stats (existing)
- projects: total, opened, closed counts
- nodes: total count with breakdown by type and status
- links: total count with capturing count
This commit is contained in:
YueGuobin 2026-03-29 23:49:36 +08:00
parent 3dbae9585c
commit 8b4c3a3517
No known key found for this signature in database

View File

@ -24,7 +24,7 @@ from fastapi.encoders import jsonable_encoder
from fastapi.routing import Mount from fastapi.routing import Mount
from websockets.exceptions import ConnectionClosed, WebSocketException from websockets.exceptions import ConnectionClosed, WebSocketException
from typing import List from typing import List, Dict
from gns3server.config import Config from gns3server.config import Config
from gns3server.controller import Controller from gns3server.controller import Controller
@ -162,19 +162,65 @@ async def update_iou_license(iou_license: schemas.IOULicense) -> schemas.IOULice
@router.get("/statistics", dependencies=[Depends(get_current_active_user)]) @router.get("/statistics", dependencies=[Depends(get_current_active_user)])
async def statistics() -> List[dict]: async def statistics() -> dict:
""" """
Return server statistics. Return server statistics including compute resources, projects, and nodes.
""" """
controller = Controller.instance()
# Compute statistics (existing behavior)
compute_statistics = [] compute_statistics = []
for compute in list(Controller.instance().computes.values()): for compute in list(controller.computes.values()):
try: try:
r = await compute.get("/statistics") r = await compute.get("/statistics")
compute_statistics.append({"compute_id": compute.id, "compute_name": compute.name, "statistics": r.json}) compute_statistics.append({"compute_id": compute.id, "compute_name": compute.name, "statistics": r.json})
except ControllerError as e: except ControllerError as e:
log.error(f"Could not retrieve statistics on compute {compute.name}: {e}") log.error(f"Could not retrieve statistics on compute {compute.name}: {e}")
return compute_statistics
# Project statistics
projects = list(controller.projects.values())
project_stats = {
"total": len(projects),
"opened": sum(1 for p in projects if p.status == "opened"),
"closed": sum(1 for p in projects if p.status == "closed"),
}
# Node statistics
all_nodes = []
for project in projects:
all_nodes.extend(project.nodes.values())
node_by_type = {}
node_by_status = {}
for node in all_nodes:
node_by_type[node.node_type] = node_by_type.get(node.node_type, 0) + 1
node_by_status[node.status] = node_by_status.get(node.status, 0) + 1
node_stats = {
"total": len(all_nodes),
"by_type": node_by_type,
"by_status": node_by_status,
}
# Link statistics
all_links = []
for project in projects:
all_links.extend(project.links.values())
link_capturing = sum(1 for link in all_links if getattr(link, "capturing", False))
link_stats = {
"total": len(all_links),
"capturing": link_capturing,
}
return {
"computes": compute_statistics,
"projects": project_stats,
"nodes": node_stats,
"links": link_stats,
}
@router.get("/notifications", dependencies=[Depends(get_current_active_user)]) @router.get("/notifications", dependencies=[Depends(get_current_active_user)])