377 lines
21 KiB
HTML
377 lines
21 KiB
HTML
{% extends "base.html" %}
|
|
{% block content %}
|
|
<div class="d-flex justify-content-between align-items-center mb-4">
|
|
<div>
|
|
<h1 class="h3 mb-1 fw-bold">System Metrics</h1>
|
|
<p class="text-muted mb-0">Real-time server performance and storage usage</p>
|
|
</div>
|
|
<div class="d-flex gap-2 align-items-center">
|
|
<span class="d-flex align-items-center gap-2 text-muted small" id="metricsLiveIndicator">
|
|
<span class="live-indicator"></span>
|
|
Auto-refresh: <span id="refreshCountdown">5</span>s
|
|
</span>
|
|
<button class="btn btn-outline-secondary btn-sm" id="refreshMetricsBtn">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" class="bi bi-arrow-clockwise me-1" viewBox="0 0 16 16">
|
|
<path fill-rule="evenodd" d="M8 3a5 5 0 1 0 4.546 2.914.5.5 0 0 1 .908-.417A6 6 0 1 1 8 2v1z"/>
|
|
<path d="M8 4.466V.534a.25.25 0 0 1 .41-.192l2.36 1.966c.12.1.12.284 0 .384L8.41 4.658A.25.25 0 0 1 8 4.466z"/>
|
|
</svg>
|
|
Refresh
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4 mb-4">
|
|
<div class="col-md-6 col-xl-3">
|
|
<div class="card shadow-sm h-100 border-0 metric-card">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center justify-content-between mb-3">
|
|
<h6 class="card-subtitle text-muted text-uppercase small fw-bold mb-0">CPU Usage</h6>
|
|
<div class="icon-box bg-primary-subtle text-primary rounded-circle p-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-cpu" viewBox="0 0 16 16">
|
|
<path d="M5 0a.5.5 0 0 1 .5.5V2h1V.5a.5.5 0 0 1 1 0V2h1V.5a.5.5 0 0 1 1 0V2h1V.5a.5.5 0 0 1 1 0V2A2.5 2.5 0 0 1 14 4.5h1.5a.5.5 0 0 1 0 1H14v1h1.5a.5.5 0 0 1 0 1H14v1h1.5a.5.5 0 0 1 0 1H14v1h1.5a.5.5 0 0 1 0 1H14a2.5 2.5 0 0 1-2.5 2.5v1.5a.5.5 0 0 1-1 0V14h-1v1.5a.5.5 0 0 1-1 0V14h-1v1.5a.5.5 0 0 1-1 0V14h-1v1.5a.5.5 0 0 1-1 0V14A2.5 2.5 0 0 1 2 11.5H.5a.5.5 0 0 1 0-1H2v-1H.5a.5.5 0 0 1 0-1H2v-1H.5a.5.5 0 0 1 0-1H2v-1H.5a.5.5 0 0 1 0-1H2A2.5 2.5 0 0 1 4.5 2V.5a.5.5 0 0 1 .5-.5zM5 4H5v8h6V4H5z"/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<h2 class="display-6 fw-bold mb-2 stat-value"><span data-metric="cpu_percent">{{ cpu_percent }}</span><span class="fs-4 fw-normal text-muted">%</span></h2>
|
|
<div class="progress" style="height: 8px; border-radius: 4px;">
|
|
<div class="progress-bar bg-primary" data-metric="cpu_bar" role="progressbar" style="width: {{ cpu_percent }}%"></div>
|
|
</div>
|
|
<div class="mt-2 d-flex justify-content-between">
|
|
<small class="text-muted">Current load</small>
|
|
<small data-metric="cpu_status" class="text-success">Normal</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6 col-xl-3">
|
|
<div class="card shadow-sm h-100 border-0 metric-card">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center justify-content-between mb-3">
|
|
<h6 class="card-subtitle text-muted text-uppercase small fw-bold mb-0">Memory</h6>
|
|
<div class="icon-box bg-info-subtle text-info rounded-circle p-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-memory" viewBox="0 0 16 16">
|
|
<path d="M1 3a1 1 0 0 0-1 1v8a1 1 0 0 0 1 1h4.586a1 1 0 0 0 .707-.293l.353-.353a.5.5 0 0 1 .708 0l.353.353a1 1 0 0 0 .707.293H15a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H1Zm.5 1h3a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-4a.5.5 0 0 1 .5-.5Zm5 0h3a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-4a.5.5 0 0 1 .5-.5Zm4.5.5a.5.5 0 0 1 .5-.5h3a.5.5 0 0 1 .5.5v4a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-4Z"/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<h2 class="display-6 fw-bold mb-2 stat-value"><span data-metric="memory_percent">{{ memory.percent }}</span><span class="fs-4 fw-normal text-muted">%</span></h2>
|
|
<div class="progress" style="height: 8px; border-radius: 4px;">
|
|
<div class="progress-bar bg-info" data-metric="memory_bar" role="progressbar" style="width: {{ memory.percent }}%"></div>
|
|
</div>
|
|
<div class="mt-2 d-flex justify-content-between">
|
|
<small class="text-muted"><span data-metric="memory_used">{{ memory.used }}</span> used</small>
|
|
<small class="text-muted"><span data-metric="memory_total">{{ memory.total }}</span> total</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6 col-xl-3">
|
|
<div class="card shadow-sm h-100 border-0 metric-card">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center justify-content-between mb-3">
|
|
<h6 class="card-subtitle text-muted text-uppercase small fw-bold mb-0">Disk Space</h6>
|
|
<div class="icon-box bg-warning-subtle text-warning rounded-circle p-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-hdd" viewBox="0 0 16 16">
|
|
<path d="M4.5 11a.5.5 0 1 0 0-1 .5.5 0 0 0 0 1zM3 10.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0z"/>
|
|
<path d="M16 11a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V9.51c0-.418.105-.83.305-1.197l2.472-4.531A1.5 1.5 0 0 1 4.094 3h7.812a1.5 1.5 0 0 1 1.317.782l2.472 4.53c.2.368.305.78.305 1.198V11zM3.655 4.26 1.592 8.043C1.724 8.014 1.86 8 2 8h12c.14 0 .276.014.408.042L12.345 4.26a.5.5 0 0 0-.439-.26H4.094a.5.5 0 0 0-.439.26zM1 10v1a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1v-1a1 1 0 0 0-1-1H2a1 1 0 0 0-1 1z"/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<h2 class="display-6 fw-bold mb-2 stat-value"><span data-metric="disk_percent">{{ disk.percent }}</span><span class="fs-4 fw-normal text-muted">%</span></h2>
|
|
<div class="progress" style="height: 8px; border-radius: 4px;">
|
|
<div class="progress-bar bg-warning" data-metric="disk_bar" role="progressbar" style="width: {{ disk.percent }}%"></div>
|
|
</div>
|
|
<div class="mt-2 d-flex justify-content-between">
|
|
<small class="text-muted"><span data-metric="disk_free">{{ disk.free }}</span> free</small>
|
|
<small class="text-muted"><span data-metric="disk_total">{{ disk.total }}</span> total</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-md-6 col-xl-3">
|
|
<div class="card shadow-sm h-100 border-0 metric-card">
|
|
<div class="card-body">
|
|
<div class="d-flex align-items-center justify-content-between mb-3">
|
|
<h6 class="card-subtitle text-muted text-uppercase small fw-bold mb-0">Storage</h6>
|
|
<div class="icon-box bg-success-subtle text-success rounded-circle p-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" fill="currentColor" class="bi bi-database" viewBox="0 0 16 16">
|
|
<path d="M4.318 2.687C5.234 2.271 6.536 2 8 2s2.766.27 3.682.687C12.644 3.125 13 3.627 13 4c0 .374-.356.875-1.318 1.313C10.766 5.729 9.464 6 8 6s-2.766-.27-3.682-.687C3.356 4.875 3 4.373 3 4c0-.374.356-.875 1.318-1.313ZM13 5.698V7c0 .374-.356.875-1.318 1.313C10.766 8.729 9.464 9 8 9s-2.766-.27-3.682-.687C3.356 7.875 3 7.373 3 7V5.698c.271.202.58.378.904.525C4.978 6.711 6.427 7 8 7s3.022-.289 4.096-.777A4.92 4.92 0 0 0 13 5.698ZM14 4c0-1.007-.875-1.755-1.904-2.223C11.022 1.289 9.573 1 8 1s-3.022.289-4.096.777C2.875 2.245 2 2.993 2 4v9c0 1.007.875 1.755 1.904 2.223C4.978 15.71 6.427 16 8 16s3.022-.289 4.096-.777C13.125 14.755 14 14.007 14 13V4Zm-1 4.698V10c0 .374-.356.875-1.318 1.313C10.766 11.729 9.464 12 8 12s-2.766-.27-3.682-.687C3.356 10.875 3 10.373 3 10V8.698c.271.202.58.378.904.525C4.978 9.71 6.427 10 8 10s3.022-.289 4.096-.777A4.92 4.92 0 0 0 13 8.698Zm0 3V13c0 .374-.356.875-1.318 1.313C10.766 14.729 9.464 15 8 15s-2.766-.27-3.682-.687C3.356 13.875 3 13.373 3 13v-1.302c.271.202.58.378.904.525C4.978 12.71 6.427 13 8 13s3.022-.289 4.096-.777c.324-.147.633-.323.904-.525Z"/>
|
|
</svg>
|
|
</div>
|
|
</div>
|
|
<h2 class="display-6 fw-bold mb-2 stat-value" data-metric="storage_used">{{ app.storage_used }}</h2>
|
|
<div class="d-flex gap-3 mt-3">
|
|
<div class="text-center flex-fill">
|
|
<div class="h5 fw-bold mb-0" data-metric="buckets_count">{{ app.buckets }}</div>
|
|
<small class="text-muted">Buckets</small>
|
|
</div>
|
|
<div class="vr"></div>
|
|
<div class="text-center flex-fill">
|
|
<div class="h5 fw-bold mb-0" data-metric="objects_count">{{ app.objects }}</div>
|
|
<small class="text-muted">Objects</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row g-4">
|
|
<div class="col-lg-8">
|
|
<div class="card shadow-sm border-0">
|
|
<div class="card-header bg-transparent border-0 pt-4 px-4 d-flex justify-content-between align-items-center">
|
|
<h5 class="card-title mb-0 fw-semibold">System Overview</h5>
|
|
</div>
|
|
<div class="card-body p-4">
|
|
<div class="table-responsive">
|
|
<table class="table table-hover align-middle mb-0">
|
|
<thead>
|
|
<tr class="text-muted small text-uppercase">
|
|
<th class="fw-semibold border-0 pb-3">Resource</th>
|
|
<th class="fw-semibold border-0 pb-3">Value</th>
|
|
<th class="fw-semibold border-0 pb-3">Status</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="py-3">
|
|
<div class="d-flex align-items-center gap-2">
|
|
<div class="bg-secondary-subtle rounded p-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-hdd-stack text-secondary" viewBox="0 0 16 16">
|
|
<path d="M14 10a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1v-1a1 1 0 0 1 1-1h12zM2 9a2 2 0 0 0-2 2v1a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-1a2 2 0 0 0-2-2H2z"/>
|
|
<path d="M5 11.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm-2 0a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zM14 3a1 1 0 0 1 1 1v1a1 1 0 0 1-1 1H2a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h12zM2 2a2 2 0 0 0-2 2v1a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V4a2 2 0 0 0-2-2H2z"/>
|
|
<path d="M5 4.5a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0zm-2 0a.5.5 0 1 1-1 0 .5.5 0 0 1 1 0z"/>
|
|
</svg>
|
|
</div>
|
|
<span class="fw-medium">Total Disk Capacity</span>
|
|
</div>
|
|
</td>
|
|
<td class="py-3 fw-semibold">{{ disk.total }}</td>
|
|
<td class="py-3"><span class="badge bg-secondary-subtle text-secondary">Hardware</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="py-3">
|
|
<div class="d-flex align-items-center gap-2">
|
|
<div class="bg-success-subtle rounded p-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check-circle text-success" viewBox="0 0 16 16">
|
|
<path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/>
|
|
<path d="M10.97 4.97a.235.235 0 0 0-.02.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-1.071-1.05z"/>
|
|
</svg>
|
|
</div>
|
|
<span class="fw-medium">Available Space</span>
|
|
</div>
|
|
</td>
|
|
<td class="py-3 fw-semibold">{{ disk.free }}</td>
|
|
<td class="py-3">
|
|
{% if disk.percent > 90 %}
|
|
<span class="status-badge status-badge-danger badge bg-danger-subtle text-danger">
|
|
<span class="status-badge-dot"></span>Critical
|
|
</span>
|
|
{% elif disk.percent > 75 %}
|
|
<span class="status-badge status-badge-warning badge bg-warning-subtle text-warning">
|
|
<span class="status-badge-dot"></span>Low
|
|
</span>
|
|
{% else %}
|
|
<span class="status-badge status-badge-success badge bg-success-subtle text-success">
|
|
<span class="status-badge-dot"></span>Good
|
|
</span>
|
|
{% endif %}
|
|
</td>
|
|
</tr>
|
|
<tr>
|
|
<td class="py-3">
|
|
<div class="d-flex align-items-center gap-2">
|
|
<div class="bg-primary-subtle rounded p-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-bucket text-primary" viewBox="0 0 16 16">
|
|
<path d="M2.522 5H2a.5.5 0 0 0-.494.574l1.372 9.149A1.5 1.5 0 0 0 4.36 16h7.278a1.5 1.5 0 0 0 1.483-1.277l1.373-9.149A.5.5 0 0 0 14 5h-.522A5.5 5.5 0 0 0 2.522 5zm1.005 0a4.5 4.5 0 0 1 8.945 0H3.527z"/>
|
|
</svg>
|
|
</div>
|
|
<span class="fw-medium">MyFSIO Data</span>
|
|
</div>
|
|
</td>
|
|
<td class="py-3 fw-semibold">{{ app.storage_used }}</td>
|
|
<td class="py-3"><span class="badge bg-primary-subtle text-primary">Application</span></td>
|
|
</tr>
|
|
<tr>
|
|
<td class="py-3">
|
|
<div class="d-flex align-items-center gap-2">
|
|
<div class="bg-info-subtle rounded p-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-file-earmark text-info" viewBox="0 0 16 16">
|
|
<path d="M14 4.5V14a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V2a2 2 0 0 1 2-2h5.5L14 4.5zm-3 0A1.5 1.5 0 0 1 9.5 3V1H4a1 1 0 0 0-1 1v12a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4.5h-2z"/>
|
|
</svg>
|
|
</div>
|
|
<span class="fw-medium">Total Objects</span>
|
|
</div>
|
|
</td>
|
|
<td class="py-3 fw-semibold">{{ app.objects }}</td>
|
|
<td class="py-3"><span class="badge bg-info-subtle text-info">Count</span></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="col-lg-4">
|
|
{% set has_issues = (cpu_percent > 80) or (memory.percent > 85) or (disk.percent > 90) %}
|
|
<div class="card shadow-sm border-0 h-100 overflow-hidden" style="background: linear-gradient(135deg, {% if has_issues %}#ef4444 0%, #f97316{% else %}#3b82f6 0%, #8b5cf6{% endif %} 100%);">
|
|
<div class="card-body p-4 d-flex flex-column justify-content-center text-white position-relative">
|
|
<div class="position-absolute top-0 end-0 opacity-25" style="transform: translate(20%, -20%);">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="160" height="160" fill="currentColor" class="bi bi-{% if has_issues %}exclamation-triangle{% else %}cloud-check{% endif %}" viewBox="0 0 16 16">
|
|
{% if has_issues %}
|
|
<path d="M7.938 2.016A.13.13 0 0 1 8.002 2a.13.13 0 0 1 .063.016.146.146 0 0 1 .054.057l6.857 11.667c.036.06.035.124.002.183a.163.163 0 0 1-.054.06.116.116 0 0 1-.066.017H1.146a.115.115 0 0 1-.066-.017.163.163 0 0 1-.054-.06.176.176 0 0 1 .002-.183L7.884 2.073a.147.147 0 0 1 .054-.057zm1.044-.45a1.13 1.13 0 0 0-1.96 0L.165 13.233c-.457.778.091 1.767.98 1.767h13.713c.889 0 1.438-.99.98-1.767L8.982 1.566z"/>
|
|
<path d="M7.002 12a1 1 0 1 1 2 0 1 1 0 0 1-2 0zM7.1 5.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 5.995z"/>
|
|
{% else %}
|
|
<path fill-rule="evenodd" d="M10.354 6.146a.5.5 0 0 1 0 .708l-3 3a.5.5 0 0 1-.708 0l-1.5-1.5a.5.5 0 1 1 .708-.708L7 8.793l2.646-2.647a.5.5 0 0 1 .708 0z"/>
|
|
<path d="M4.406 3.342A5.53 5.53 0 0 1 8 2c2.69 0 4.923 2 5.166 4.579C14.758 6.804 16 8.137 16 9.773 16 11.569 14.502 13 12.687 13H3.781C1.708 13 0 11.366 0 9.318c0-1.763 1.266-3.223 2.942-3.593.143-.863.698-1.723 1.464-2.383z"/>
|
|
{% endif %}
|
|
</svg>
|
|
</div>
|
|
<div class="mb-3">
|
|
<span class="badge bg-white {% if has_issues %}text-danger{% else %}text-primary{% endif %} fw-semibold px-3 py-2">
|
|
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="currentColor" class="bi bi-{% if has_issues %}exclamation-circle-fill{% else %}check-circle-fill{% endif %} me-1" viewBox="0 0 16 16">
|
|
{% if has_issues %}
|
|
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8 4a.905.905 0 0 0-.9.995l.35 3.507a.552.552 0 0 0 1.1 0l.35-3.507A.905.905 0 0 0 8 4zm.002 6a1 1 0 1 0 0 2 1 1 0 0 0 0-2z"/>
|
|
{% else %}
|
|
<path d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zm-3.97-3.03a.75.75 0 0 0-1.08.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-.01-1.05z"/>
|
|
{% endif %}
|
|
</svg>
|
|
v{{ app.version }}
|
|
</span>
|
|
</div>
|
|
<h4 class="card-title fw-bold mb-3">System Health</h4>
|
|
{% if has_issues %}
|
|
<ul class="list-unstyled small mb-4 opacity-90">
|
|
{% if cpu_percent > 80 %}<li class="mb-1">CPU usage is high ({{ cpu_percent }}%)</li>{% endif %}
|
|
{% if memory.percent > 85 %}<li class="mb-1">Memory usage is high ({{ memory.percent }}%)</li>{% endif %}
|
|
{% if disk.percent > 90 %}<li class="mb-1">Disk space is critically low ({{ disk.percent }}% used)</li>{% endif %}
|
|
</ul>
|
|
{% else %}
|
|
<p class="card-text opacity-90 mb-4 small">All resources are within normal operating parameters.</p>
|
|
{% endif %}
|
|
<div class="d-flex gap-4">
|
|
<div>
|
|
<div class="h3 fw-bold mb-0">{{ app.uptime_days }}d</div>
|
|
<small class="opacity-75">Uptime</small>
|
|
</div>
|
|
<div>
|
|
<div class="h3 fw-bold mb-0">{{ app.buckets }}</div>
|
|
<small class="opacity-75">Active Buckets</small>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block extra_scripts %}
|
|
<script>
|
|
(function() {
|
|
var refreshInterval = 5000;
|
|
var countdown = 5;
|
|
var countdownEl = document.getElementById('refreshCountdown');
|
|
var refreshBtn = document.getElementById('refreshMetricsBtn');
|
|
var countdownTimer = null;
|
|
var fetchTimer = null;
|
|
|
|
function updateMetrics() {
|
|
fetch('/ui/metrics/api')
|
|
.then(function(resp) { return resp.json(); })
|
|
.then(function(data) {
|
|
var el;
|
|
el = document.querySelector('[data-metric="cpu_percent"]');
|
|
if (el) el.textContent = data.cpu_percent;
|
|
el = document.querySelector('[data-metric="cpu_bar"]');
|
|
if (el) {
|
|
el.style.width = data.cpu_percent + '%';
|
|
el.className = 'progress-bar ' + (data.cpu_percent > 80 ? 'bg-danger' : data.cpu_percent > 50 ? 'bg-warning' : 'bg-primary');
|
|
}
|
|
el = document.querySelector('[data-metric="cpu_status"]');
|
|
if (el) {
|
|
el.textContent = data.cpu_percent > 80 ? 'High' : data.cpu_percent > 50 ? 'Medium' : 'Normal';
|
|
el.className = data.cpu_percent > 80 ? 'text-danger' : data.cpu_percent > 50 ? 'text-warning' : 'text-success';
|
|
}
|
|
|
|
el = document.querySelector('[data-metric="memory_percent"]');
|
|
if (el) el.textContent = data.memory.percent;
|
|
el = document.querySelector('[data-metric="memory_bar"]');
|
|
if (el) el.style.width = data.memory.percent + '%';
|
|
el = document.querySelector('[data-metric="memory_used"]');
|
|
if (el) el.textContent = data.memory.used;
|
|
el = document.querySelector('[data-metric="memory_total"]');
|
|
if (el) el.textContent = data.memory.total;
|
|
|
|
el = document.querySelector('[data-metric="disk_percent"]');
|
|
if (el) el.textContent = data.disk.percent;
|
|
el = document.querySelector('[data-metric="disk_bar"]');
|
|
if (el) {
|
|
el.style.width = data.disk.percent + '%';
|
|
el.className = 'progress-bar ' + (data.disk.percent > 90 ? 'bg-danger' : 'bg-warning');
|
|
}
|
|
el = document.querySelector('[data-metric="disk_free"]');
|
|
if (el) el.textContent = data.disk.free;
|
|
el = document.querySelector('[data-metric="disk_total"]');
|
|
if (el) el.textContent = data.disk.total;
|
|
|
|
el = document.querySelector('[data-metric="storage_used"]');
|
|
if (el) el.textContent = data.app.storage_used;
|
|
el = document.querySelector('[data-metric="buckets_count"]');
|
|
if (el) el.textContent = data.app.buckets;
|
|
el = document.querySelector('[data-metric="objects_count"]');
|
|
if (el) el.textContent = data.app.objects;
|
|
|
|
countdown = 5;
|
|
})
|
|
.catch(function(err) {
|
|
console.error('Metrics fetch error:', err);
|
|
});
|
|
}
|
|
|
|
function startCountdown() {
|
|
if (countdownTimer) clearInterval(countdownTimer);
|
|
countdown = 5;
|
|
if (countdownEl) countdownEl.textContent = countdown;
|
|
countdownTimer = setInterval(function() {
|
|
countdown--;
|
|
if (countdownEl) countdownEl.textContent = countdown;
|
|
if (countdown <= 0) {
|
|
countdown = 5;
|
|
}
|
|
}, 1000);
|
|
}
|
|
|
|
function startPolling() {
|
|
if (fetchTimer) clearInterval(fetchTimer);
|
|
fetchTimer = setInterval(function() {
|
|
if (!document.hidden) {
|
|
updateMetrics();
|
|
}
|
|
}, refreshInterval);
|
|
startCountdown();
|
|
}
|
|
|
|
if (refreshBtn) {
|
|
refreshBtn.addEventListener('click', function() {
|
|
updateMetrics();
|
|
countdown = 5;
|
|
if (countdownEl) countdownEl.textContent = countdown;
|
|
});
|
|
}
|
|
|
|
document.addEventListener('visibilitychange', function() {
|
|
if (!document.hidden) {
|
|
updateMetrics();
|
|
startPolling();
|
|
}
|
|
});
|
|
|
|
startPolling();
|
|
})();
|
|
</script>
|
|
{% endblock %}
|