Files
node-monitor/app/web/templates/index.html

94 lines
5.1 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Node Monitor</title>
<link rel="stylesheet" href="{{ url_for('static', path='/style.css') }}">
</head>
<body>
<div class="header-container">
<h1>Node Monitoring System</h1>
<p>Total Nodes: <span id="node-count">{{ nodes|length }}</span></p>
<p>Service UUID: <code>{{ service_uuid }}</code></p>
</div>
<div id="node-grid-container">
{% if nodes %}
<div class="connection-grid" style="grid-template-columns: minmax(100px, 1fr) repeat({{ nodes|length }}, minmax(100px, 1fr));">
<!-- Header Row (Column UUIDs) -->
<div class="grid-row header-row">
<div class="grid-cell empty-cell"></div> {# Top-left corner #}
{% for node in nodes %}
<div class="grid-cell header-cell">
<div class="node-uuid" title="{{ node.uuid }}">{{ node.uuid[:8] }}...</div>
</div>
{% endfor %}
</div>
<!-- Data Rows -->
{% for row_node in nodes %}
<div class="grid-row">
<!-- Row Header (UUID) -->
<div class="grid-cell header-cell">
<div class="node-uuid" title="{{ row_node.uuid }}">{{ row_node.uuid[:8] }}...</div>
</div>
<!-- Cells for connections/status -->
{% for col_node in nodes %}
<div class="grid-cell
{% if row_node.uuid == col_node.uuid %}
node-{{ row_node.health_status }}
{% else %}
{% set latency = row_node.connections[col_node.uuid] if col_node.uuid in row_node.connections else None %}
{% if latency is not none and latency is not equalto 0.0 %}
{% if latency <= 200 %}latency-low
{% elif latency <= 1000 %}latency-medium
{% else %}latency-high
{% endif %}
{% else %}
latency-unavailable
{% endif %}
{% endif %}
">
{% if row_node.uuid == col_node.uuid %}
<div class="node-status-text">Status: {{ row_node.health_status.upper() }}</div>
<div class="node-tooltip">
<p><strong>UUID:</strong> {{ row_node.uuid }}</p>
<p><strong>IP:</strong> {{ row_node.ip }}</p>
<p><strong>Last Seen:</strong> {{ row_node.formatted_last_seen }}</p>
<p><strong>Uptime:</strong> {{ row_node.formatted_uptime }}</p>
<p><strong>Load Avg (1m, 5m, 15m):</strong> {{ row_node.load_avg | map('%.2f' | format) | join(', ') if row_node.load_avg else 'N/A' }}</p>
<p><strong>Memory Usage:</strong> {{ '%.2f' | format(row_node.memory_usage_percent) + '%' if row_node.memory_usage_percent is not none else 'N/A' }}</p>
</div>
{% else %}
{% set latency = row_node.connections[col_node.uuid] if col_node.uuid in row_node.connections else None %}
{% set display_latency = 'N/A' %}
{% if latency is not none and latency is not equalto 0.0 %}
{% set display_latency = '%.1f ms' | format(latency) %}
{% endif %}
<div class="conn-status-text">Ping: {{ display_latency }}</div>
<div class="node-tooltip">
<p><strong>From:</strong> {{ row_node.uuid[:8] }}...</p>
<p><strong>to:</strong> {{ col_node.uuid[:8] }}...</p>
<p><strong>Latency:</strong> {{ display_latency }}</p>
</div>
{% endif %}
</div>
{% endfor %}
</div>
{% endfor %}
</div>
{% else %}
<p class="loading-message">No nodes reporting yet. Start a client!</p>
{% endif %}
</div>
<script>
// Pass the base path for API calls if mounted under a subpath
window.API_BASE_PATH = "{{ root_path }}";
</script>
<script src="{{ url_for('static', path='/script.js') }}"></script>
</body>
</html>