Update app.py
Browse files
app.py
CHANGED
|
@@ -250,7 +250,7 @@ htmlTemplate = f"""
|
|
| 250 |
|
| 251 |
try {{
|
| 252 |
const eventSource = new EventSource(
|
| 253 |
-
`https://api.hf.space/v1/${username}/${instanceId}/live-metrics/sse`
|
| 254 |
);
|
| 255 |
|
| 256 |
this.spaceIds.set(instanceId, instanceId);
|
|
@@ -261,18 +261,18 @@ htmlTemplate = f"""
|
|
| 261 |
const data = JSON.parse(event.data);
|
| 262 |
updateServerCard(data, instanceId);
|
| 263 |
}} catch (error) {{
|
| 264 |
-
console.error(`解析数据失败 (${instanceId}):`, error);
|
| 265 |
}}
|
| 266 |
}});
|
| 267 |
|
| 268 |
eventSource.onerror = (error) => {{
|
| 269 |
-
console.error(`EventSource 错误 (${instanceId}):`, error);
|
| 270 |
eventSource.close();
|
| 271 |
}};
|
| 272 |
|
| 273 |
this.eventSources.set(instanceId, eventSource);
|
| 274 |
}} catch (error) {{
|
| 275 |
-
console.error(`连接失败 (${username}/${instanceId}):`, error);
|
| 276 |
}}
|
| 277 |
}}
|
| 278 |
|
|
@@ -296,12 +296,12 @@ htmlTemplate = f"""
|
|
| 296 |
|
| 297 |
function updateServerCard(data, spaceId) {{
|
| 298 |
const serverId = data.replica;
|
| 299 |
-
const serverElement = document.getElementById(`server-${serverId}`);
|
| 300 |
const owner = metricsManager.instanceOwners.get(spaceId);
|
| 301 |
|
| 302 |
if (!serverElement) {{
|
| 303 |
const card = document.createElement('div');
|
| 304 |
-
card.id = `server-${serverId}`;
|
| 305 |
card.className = 'server-card';
|
| 306 |
card.innerHTML = `
|
| 307 |
<div class="server-header">
|
|
@@ -310,7 +310,7 @@ htmlTemplate = f"""
|
|
| 310 |
<svg class="server-flag" width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
| 311 |
<path d="M21 3H3C1.9 3 1 3.9 1 5v3c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 5H4V6h16v2zm1 4H3c-1.1 0-2 .9-2 2v3c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2v-3c0-1.1-.9-2-2-2zm-1 5H4v-2h16v2zm1 4H3c-1.1 0-2 .9-2 2v3c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2v-3c0-1.1-.9-2-2-2zm-1 5H4v-2h16v2z"/>
|
| 312 |
</svg>
|
| 313 |
-
<div>${serverId} (${owner}/${spaceId})</div>
|
| 314 |
</div>
|
| 315 |
</div>
|
| 316 |
<div class="metric-grid">
|
|
@@ -341,21 +341,21 @@ htmlTemplate = f"""
|
|
| 341 |
document.getElementById('servers').appendChild(card);
|
| 342 |
}}
|
| 343 |
|
| 344 |
-
const card = document.getElementById(`server-${serverId}`);
|
| 345 |
const cpuUsage = data.cpu_usage_pct;
|
| 346 |
const memoryUsage = (data.memory_used_bytes / data.memory_total_bytes) * 100;
|
| 347 |
const uploadBps = data.tx_bps;
|
| 348 |
const downloadBps = data.rx_bps;
|
| 349 |
|
| 350 |
-
card.querySelector('.cpu-usage').textContent = `${cpuUsage.toFixed(2)}%`;
|
| 351 |
-
card.querySelector('.cpu-progress-bar').style.width = `${cpuUsage}%`;
|
| 352 |
|
| 353 |
-
card.querySelector('.memory-usage').textContent = `${memoryUsage.toFixed(2)}%`;
|
| 354 |
-
card.querySelector('.memory-progress-bar').style.width = `${memoryUsage}%`;
|
| 355 |
|
| 356 |
-
card.querySelector('.upload').textContent = `${formatBytes(uploadBps)}/s`;
|
| 357 |
|
| 358 |
-
card.querySelector('.download').textContent = `${formatBytes(downloadBps)}/s`;
|
| 359 |
|
| 360 |
servers.set(serverId, Date.now());
|
| 361 |
updateSummary();
|
|
@@ -370,10 +370,10 @@ htmlTemplate = f"""
|
|
| 370 |
|
| 371 |
servers.forEach((lastSeen, serverId) => {{
|
| 372 |
const isOnline = (now - lastSeen) < 10000;
|
| 373 |
-
const serverCard = document.getElementById(`server-${serverId}`);
|
| 374 |
if (serverCard) {{
|
| 375 |
const statusDot = serverCard.querySelector('.status-dot');
|
| 376 |
-
statusDot.className = `status-dot status-${isOnline ? 'online' : 'offline'}`;
|
| 377 |
|
| 378 |
if (isOnline) {{
|
| 379 |
const uploadText = serverCard.querySelector('.upload').textContent;
|
|
@@ -388,8 +388,8 @@ htmlTemplate = f"""
|
|
| 388 |
document.getElementById('totalServers').textContent = servers.size;
|
| 389 |
document.getElementById('onlineServers').textContent = online;
|
| 390 |
document.getElementById('offlineServers').textContent = offline;
|
| 391 |
-
document.getElementById('totalUpload').textContent = `${formatBytes(totalUpload)}/s`;
|
| 392 |
-
document.getElementById('totalDownload').textContent = `${formatBytes(totalDownload)}/s`;
|
| 393 |
}}
|
| 394 |
|
| 395 |
function formatBytes(bytes) {{
|
|
@@ -412,9 +412,8 @@ htmlTemplate = f"""
|
|
| 412 |
</html>
|
| 413 |
"""
|
| 414 |
|
| 415 |
-
|
| 416 |
@app.route("/")
|
| 417 |
-
def
|
| 418 |
return render_template_string(htmlTemplate)
|
| 419 |
|
| 420 |
if __name__ == "__main__":
|
|
|
|
| 250 |
|
| 251 |
try {{
|
| 252 |
const eventSource = new EventSource(
|
| 253 |
+
`https://api.hf.space/v1/${{username}}/${{instanceId}}/live-metrics/sse`
|
| 254 |
);
|
| 255 |
|
| 256 |
this.spaceIds.set(instanceId, instanceId);
|
|
|
|
| 261 |
const data = JSON.parse(event.data);
|
| 262 |
updateServerCard(data, instanceId);
|
| 263 |
}} catch (error) {{
|
| 264 |
+
console.error(`解析数据失败 (${{instanceId}}):`, error);
|
| 265 |
}}
|
| 266 |
}});
|
| 267 |
|
| 268 |
eventSource.onerror = (error) => {{
|
| 269 |
+
console.error(`EventSource 错误 (${{instanceId}}):`, error);
|
| 270 |
eventSource.close();
|
| 271 |
}};
|
| 272 |
|
| 273 |
this.eventSources.set(instanceId, eventSource);
|
| 274 |
}} catch (error) {{
|
| 275 |
+
console.error(`连接失败 (${{username}}/${{instanceId}}):`, error);
|
| 276 |
}}
|
| 277 |
}}
|
| 278 |
|
|
|
|
| 296 |
|
| 297 |
function updateServerCard(data, spaceId) {{
|
| 298 |
const serverId = data.replica;
|
| 299 |
+
const serverElement = document.getElementById(`server-${{serverId}}`);
|
| 300 |
const owner = metricsManager.instanceOwners.get(spaceId);
|
| 301 |
|
| 302 |
if (!serverElement) {{
|
| 303 |
const card = document.createElement('div');
|
| 304 |
+
card.id = `server-${{serverId}}`;
|
| 305 |
card.className = 'server-card';
|
| 306 |
card.innerHTML = `
|
| 307 |
<div class="server-header">
|
|
|
|
| 310 |
<svg class="server-flag" width="20" height="20" viewBox="0 0 24 24" fill="currentColor">
|
| 311 |
<path d="M21 3H3C1.9 3 1 3.9 1 5v3c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-1 5H4V6h16v2zm1 4H3c-1.1 0-2 .9-2 2v3c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2v-3c0-1.1-.9-2-2-2zm-1 5H4v-2h16v2zm1 4H3c-1.1 0-2 .9-2 2v3c0 1.1.9 2 2 2h18c1.1 0 2-.9 2-2v-3c0-1.1-.9-2-2-2zm-1 5H4v-2h16v2z"/>
|
| 312 |
</svg>
|
| 313 |
+
<div>${{serverId}} (${{owner}}/${{spaceId}})</div>
|
| 314 |
</div>
|
| 315 |
</div>
|
| 316 |
<div class="metric-grid">
|
|
|
|
| 341 |
document.getElementById('servers').appendChild(card);
|
| 342 |
}}
|
| 343 |
|
| 344 |
+
const card = document.getElementById(`server-${{serverId}}`);
|
| 345 |
const cpuUsage = data.cpu_usage_pct;
|
| 346 |
const memoryUsage = (data.memory_used_bytes / data.memory_total_bytes) * 100;
|
| 347 |
const uploadBps = data.tx_bps;
|
| 348 |
const downloadBps = data.rx_bps;
|
| 349 |
|
| 350 |
+
card.querySelector('.cpu-usage').textContent = `${{cpuUsage.toFixed(2)}}%`;
|
| 351 |
+
card.querySelector('.cpu-progress-bar').style.width = `${{cpuUsage}}%`;
|
| 352 |
|
| 353 |
+
card.querySelector('.memory-usage').textContent = `${{memoryUsage.toFixed(2)}}%`;
|
| 354 |
+
card.querySelector('.memory-progress-bar').style.width = `${{memoryUsage}}%`;
|
| 355 |
|
| 356 |
+
card.querySelector('.upload').textContent = `${{formatBytes(uploadBps)}}/s`;
|
| 357 |
|
| 358 |
+
card.querySelector('.download').textContent = `${{formatBytes(downloadBps)}}/s`;
|
| 359 |
|
| 360 |
servers.set(serverId, Date.now());
|
| 361 |
updateSummary();
|
|
|
|
| 370 |
|
| 371 |
servers.forEach((lastSeen, serverId) => {{
|
| 372 |
const isOnline = (now - lastSeen) < 10000;
|
| 373 |
+
const serverCard = document.getElementById(`server-${{serverId}}`);
|
| 374 |
if (serverCard) {{
|
| 375 |
const statusDot = serverCard.querySelector('.status-dot');
|
| 376 |
+
statusDot.className = `status-dot status-${{isOnline ? 'online' : 'offline'}}`;
|
| 377 |
|
| 378 |
if (isOnline) {{
|
| 379 |
const uploadText = serverCard.querySelector('.upload').textContent;
|
|
|
|
| 388 |
document.getElementById('totalServers').textContent = servers.size;
|
| 389 |
document.getElementById('onlineServers').textContent = online;
|
| 390 |
document.getElementById('offlineServers').textContent = offline;
|
| 391 |
+
document.getElementById('totalUpload').textContent = `${{formatBytes(totalUpload)}}/s`;
|
| 392 |
+
document.getElementById('totalDownload').textContent = `${{formatBytes(totalDownload)}}/s`;
|
| 393 |
}}
|
| 394 |
|
| 395 |
function formatBytes(bytes) {{
|
|
|
|
| 412 |
</html>
|
| 413 |
"""
|
| 414 |
|
|
|
|
| 415 |
@app.route("/")
|
| 416 |
+
def home():
|
| 417 |
return render_template_string(htmlTemplate)
|
| 418 |
|
| 419 |
if __name__ == "__main__":
|