153 lines
5.5 KiB
Python
153 lines
5.5 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any
|
|
|
|
from core.config import THRESHOLDS, load_hosts, settings_payload, utc_now
|
|
from .host_metrics import get_host_metrics
|
|
from .http_probe import get_service_payload
|
|
from .mongo_metrics import get_mongo_payload
|
|
from .mysql_metrics import get_mysql_overview_payload
|
|
from .nacos import get_nacos_payload
|
|
|
|
|
|
def classify_threshold(value: float | int | None, thresholds: dict[str, float | int]) -> str:
|
|
# 没值时返回 neutral。
|
|
if value is None:
|
|
return "neutral"
|
|
|
|
# 读取 warn 阈值。
|
|
warn = float(thresholds["warn"])
|
|
# 读取 bad 阈值。
|
|
bad = float(thresholds["bad"])
|
|
# 统一转成浮点数比较。
|
|
numeric = float(value)
|
|
|
|
# 超过 bad 阈值记为 bad。
|
|
if numeric >= bad:
|
|
return "bad"
|
|
|
|
# 超过 warn 阈值记为 warn。
|
|
if numeric >= warn:
|
|
return "warn"
|
|
|
|
# 其余情况记为 ok。
|
|
return "ok"
|
|
|
|
|
|
def annotate_metric_levels(metrics: dict[str, Any]) -> dict[str, Any]:
|
|
# 复制一份,避免直接修改缓存原对象。
|
|
payload = dict(metrics)
|
|
|
|
# 指标采集失败时统一按 bad 标记。
|
|
if not payload.get("ok"):
|
|
payload["cpuLevel"] = "bad"
|
|
payload["memoryLevel"] = "bad"
|
|
payload["diskLevel"] = "bad"
|
|
payload["processLevel"] = "bad"
|
|
return payload
|
|
|
|
# 给 CPU 指标增加级别。
|
|
payload["cpuLevel"] = classify_threshold(payload.get("cpuPercent"), THRESHOLDS["cpuPercent"])
|
|
# 给内存指标增加级别。
|
|
payload["memoryLevel"] = classify_threshold(payload.get("memoryPercent"), THRESHOLDS["memoryPercent"])
|
|
# 给磁盘指标增加级别。
|
|
payload["diskLevel"] = classify_threshold(payload.get("diskPercent"), THRESHOLDS["diskPercent"])
|
|
# 给进程数增加级别。
|
|
payload["processLevel"] = classify_threshold(payload.get("processCount"), THRESHOLDS["processCount"])
|
|
|
|
# 返回加完等级的结构。
|
|
return payload
|
|
|
|
|
|
def build_host_payload(
|
|
hosts: list[dict[str, Any]],
|
|
service_payload: dict[str, Any],
|
|
metrics_by_host: dict[str, dict[str, Any]],
|
|
) -> list[dict[str, Any]]:
|
|
# 先把服务结果按 host 分组。
|
|
services_by_host: dict[str, list[dict[str, Any]]] = {}
|
|
|
|
# 遍历所有服务结果。
|
|
for item in service_payload.get("items") or []:
|
|
services_by_host.setdefault(item["host"], []).append(item)
|
|
|
|
# 最终的主机维度结果。
|
|
grouped_hosts: list[dict[str, Any]] = []
|
|
|
|
# 按配置顺序输出主机。
|
|
for host in hosts:
|
|
# 当前主机的服务结果列表。
|
|
items = services_by_host.get(host["host"], [])
|
|
# 当前主机健康服务数量。
|
|
ok_count = sum(1 for item in items if item["ok"])
|
|
# 当前主机原始指标。
|
|
raw_metrics = metrics_by_host.get(host["host"], {"ok": False, "error": "metrics unavailable"})
|
|
# 加上指标阈值等级。
|
|
metrics = annotate_metric_levels(raw_metrics)
|
|
|
|
# 追加主机结构。
|
|
grouped_hosts.append(
|
|
{
|
|
"host": host["host"],
|
|
"ip": host["ip"],
|
|
"group": host["group"],
|
|
"instanceId": host["instanceId"],
|
|
"metrics": metrics,
|
|
"serviceSummary": {
|
|
"total": len(items),
|
|
"ok": ok_count,
|
|
"down": len(items) - ok_count,
|
|
},
|
|
"items": items,
|
|
}
|
|
)
|
|
|
|
# 返回主机分组结果。
|
|
return grouped_hosts
|
|
|
|
|
|
def build_monitor_payload() -> dict[str, Any]:
|
|
# 读取当前监控目标。
|
|
hosts = load_hosts()
|
|
# 获取服务探测结果。
|
|
service_payload = get_service_payload(hosts, THRESHOLDS["latencyMs"])
|
|
# 获取主机资源指标。
|
|
metrics_by_host = get_host_metrics(hosts)
|
|
# 获取 Nacos 注册信息。
|
|
nacos_payload = get_nacos_payload()
|
|
# 获取 Mongo 指标。
|
|
mongo_payload = get_mongo_payload()
|
|
# 获取 MySQL 指标。
|
|
mysql_payload = get_mysql_overview_payload()
|
|
# 组装主机维度视图。
|
|
grouped_hosts = build_host_payload(hosts, service_payload, metrics_by_host)
|
|
# 统计主机指标成功数。
|
|
host_metric_ok = sum(1 for host in grouped_hosts if host["metrics"].get("ok"))
|
|
|
|
# 返回完整的页面 API 载荷。
|
|
return {
|
|
"updatedAt": utc_now(),
|
|
"settings": settings_payload(),
|
|
"summary": {
|
|
**service_payload["summary"],
|
|
"hostMetricOk": host_metric_ok,
|
|
"hostMetricDown": len(grouped_hosts) - host_metric_ok,
|
|
"nacosServiceTotal": int(nacos_payload.get("summary", {}).get("serviceTotal", 0)),
|
|
"nacosInstanceTotal": int(nacos_payload.get("summary", {}).get("instanceTotal", 0)),
|
|
"nacosUnhealthyInstanceTotal": int(
|
|
nacos_payload.get("summary", {}).get("unhealthyInstanceTotal", 0)
|
|
),
|
|
"mongoDatabaseTotal": int(mongo_payload.get("summary", {}).get("databaseTotal", 0)),
|
|
"mongoCollectionTotal": int(mongo_payload.get("summary", {}).get("collectionTotal", 0)),
|
|
"mongoOk": 1 if mongo_payload.get("ok") else 0,
|
|
"mysqlDatabaseTotal": int(mysql_payload.get("summary", {}).get("databaseTotal", 0)),
|
|
"mysqlTableTotal": int(mysql_payload.get("summary", {}).get("tableTotal", 0)),
|
|
"mysqlOk": 1 if mysql_payload.get("ok") else 0,
|
|
},
|
|
"hosts": grouped_hosts,
|
|
"items": service_payload["items"],
|
|
"nacos": nacos_payload,
|
|
"mongo": mongo_payload,
|
|
"mysql": mysql_payload,
|
|
}
|