Upload 16 files
Browse files- .gitattributes +1 -0
- app/__pycache__/main.cpython-313.pyc +0 -0
- app/main.py +0 -0
- static/public.js +31 -29
.gitattributes
CHANGED
|
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
app/__pycache__/main.cpython-313.pyc filter=lfs diff=lfs merge=lfs -text
|
app/__pycache__/main.cpython-313.pyc
CHANGED
|
Binary files a/app/__pycache__/main.cpython-313.pyc and b/app/__pycache__/main.cpython-313.pyc differ
|
|
|
app/main.py
CHANGED
|
The diff for this file is too large to render.
See raw diff
|
|
|
static/public.js
CHANGED
|
@@ -45,19 +45,20 @@ function applyTimelineGrid(pointsCount) {
|
|
| 45 |
timelineHeader.style.gridTemplateColumns = headerColumns;
|
| 46 |
}
|
| 47 |
|
| 48 |
-
function renderOverview(data) {
|
| 49 |
-
overviewCards.innerHTML = "";
|
| 50 |
-
const averageHealth = data.average_health === null || data.average_health === undefined ? "--" : `${data.average_health.toFixed(2)}%`;
|
| 51 |
-
const totalCalls = data.total_requests ?? 0;
|
| 52 |
-
const healthyModels = (data.models || []).filter((model) => (model.latest_success_rate ?? 0) >= 95).length;
|
| 53 |
-
const displayedBuckets = data.models?.[0]?.points?.length || 0;
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
overviewCards.appendChild(createSummaryCard("
|
| 57 |
-
overviewCards.appendChild(createSummaryCard("
|
| 58 |
-
overviewCards.appendChild(createSummaryCard("
|
| 59 |
-
|
| 60 |
-
|
|
|
|
| 61 |
|
| 62 |
function renderTimelineHeader(models) {
|
| 63 |
timelineHeader.innerHTML = "";
|
|
@@ -85,26 +86,27 @@ function renderHealthRows(models) {
|
|
| 85 |
dashboardEmpty.textContent = "";
|
| 86 |
renderTimelineHeader(models);
|
| 87 |
|
| 88 |
-
models.forEach((model) => {
|
| 89 |
-
const latestRate = model.latest_success_rate === null || model.latest_success_rate === undefined ? "--" : `${model.latest_success_rate.toFixed(2)}%`;
|
| 90 |
-
const latestMeta = rateMeta(model.latest_success_rate);
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
row
|
| 94 |
-
row.
|
|
|
|
| 95 |
|
| 96 |
const summary = document.createElement("div");
|
| 97 |
summary.className = "health-row-summary";
|
| 98 |
summary.innerHTML = `
|
| 99 |
-
<div class="health-row-accent ${latestMeta.className}"></div>
|
| 100 |
-
<div class="health-row-copy">
|
| 101 |
-
<h3 title="${model.model_id}">${model.model_id}</h3>
|
| 102 |
-
<div class="health-meta-inline">
|
| 103 |
-
<span class="health-rate-pill ${latestMeta.className}">${latestRate}</span>
|
| 104 |
-
<span class="health-rate-pill health-call-pill">调用 ${model.total_calls ?? 0} 次</span>
|
| 105 |
-
</div>
|
| 106 |
-
</div>
|
| 107 |
-
`;
|
| 108 |
|
| 109 |
const cells = document.createElement("div");
|
| 110 |
cells.className = "health-cells";
|
|
|
|
| 45 |
timelineHeader.style.gridTemplateColumns = headerColumns;
|
| 46 |
}
|
| 47 |
|
| 48 |
+
function renderOverview(data) {
|
| 49 |
+
overviewCards.innerHTML = "";
|
| 50 |
+
const averageHealth = data.average_health === null || data.average_health === undefined ? "--" : `${data.average_health.toFixed(2)}%`;
|
| 51 |
+
const totalCalls = data.total_requests ?? 0;
|
| 52 |
+
const healthyModels = (data.models || []).filter((model) => (model.latest_success_rate ?? 0) >= 95).length;
|
| 53 |
+
const displayedBuckets = data.models?.[0]?.points?.length || 0;
|
| 54 |
+
const healthWindowMinutes = data.health_window_minutes || 120;
|
| 55 |
+
|
| 56 |
+
overviewCards.appendChild(createSummaryCard("总调用次数", totalCalls, "统计来自网关累计成功与失败请求"));
|
| 57 |
+
overviewCards.appendChild(createSummaryCard("平均健康度", averageHealth, `按监控模型最近 ${healthWindowMinutes} 分钟滚动成功率平均值计算`));
|
| 58 |
+
overviewCards.appendChild(createSummaryCard("高健康模型数", healthyModels, `最近 ${healthWindowMinutes} 分钟滚动成功率达到 95% 以上的模型数量`));
|
| 59 |
+
overviewCards.appendChild(createSummaryCard("统计窗口", `${displayedBuckets * (data.bucket_minutes || 10)} 分钟`, `当前按 ${data.bucket_minutes || 10} 分钟粒度滚动统计`));
|
| 60 |
+
dashboardUpdated.textContent = formatDateTime(data.generated_at);
|
| 61 |
+
}
|
| 62 |
|
| 63 |
function renderTimelineHeader(models) {
|
| 64 |
timelineHeader.innerHTML = "";
|
|
|
|
| 86 |
dashboardEmpty.textContent = "";
|
| 87 |
renderTimelineHeader(models);
|
| 88 |
|
| 89 |
+
models.forEach((model) => {
|
| 90 |
+
const latestRate = model.latest_success_rate === null || model.latest_success_rate === undefined ? "--" : `${model.latest_success_rate.toFixed(2)}%`;
|
| 91 |
+
const latestMeta = rateMeta(model.latest_success_rate);
|
| 92 |
+
const healthWindowMinutes = model.health_window_minutes || 120;
|
| 93 |
+
|
| 94 |
+
const row = document.createElement("article");
|
| 95 |
+
row.className = "health-row-card";
|
| 96 |
+
row.style.gridTemplateColumns = `minmax(${SUMMARY_WIDTH}px, 1fr) max-content`;
|
| 97 |
|
| 98 |
const summary = document.createElement("div");
|
| 99 |
summary.className = "health-row-summary";
|
| 100 |
summary.innerHTML = `
|
| 101 |
+
<div class="health-row-accent ${latestMeta.className}"></div>
|
| 102 |
+
<div class="health-row-copy">
|
| 103 |
+
<h3 title="${model.model_id}">${model.model_id}</h3>
|
| 104 |
+
<div class="health-meta-inline">
|
| 105 |
+
<span class="health-rate-pill ${latestMeta.className}" title="最近 ${healthWindowMinutes} 分钟滚动成功率">${latestRate}</span>
|
| 106 |
+
<span class="health-rate-pill health-call-pill">调用 ${model.total_calls ?? 0} 次</span>
|
| 107 |
+
</div>
|
| 108 |
+
</div>
|
| 109 |
+
`;
|
| 110 |
|
| 111 |
const cells = document.createElement("div");
|
| 112 |
cells.className = "health-cells";
|