hospital-management/templates/core/system_monitoring.html
2025-08-12 13:33:25 +03:00

482 lines
20 KiB
HTML

{% extends 'base.html' %}
{% load static %}
{% block title %}System Monitoring{% endblock %}
{% block css %}
<link href="{% static 'assets/plugins/chart.js/dist/Chart.min.css' %}" rel="stylesheet" />
{% endblock %}
{% block content %}
<div id="content" class="app-content">
<div class="container">
<ul class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">Dashboard</a></li>
<li class="breadcrumb-item active">System Monitoring</li>
</ul>
<div class="row align-items-center mb-3">
<div class="col">
<h1 class="page-header">System Monitoring</h1>
<p class="text-muted">Real-time system performance and health monitoring</p>
</div>
<div class="col-auto">
<div class="btn-group">
<button type="button" class="btn btn-outline-primary" onclick="refreshMetrics()">
<i class="fa fa-refresh me-2"></i>Refresh
</button>
<button type="button" class="btn btn-outline-secondary" onclick="toggleAutoRefresh()">
<i class="fa fa-play me-2" id="autoRefreshIcon"></i>Auto Refresh
</button>
</div>
</div>
</div>
<!-- System Status Overview -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<div class="w-60px h-60px bg-{{ system_status.color }} bg-opacity-20 d-flex align-items-center justify-content-center rounded-circle mx-auto mb-3">
<i class="fa fa-{{ system_status.icon }} fa-2x text-{{ system_status.color }}"></i>
</div>
<h5>System Status</h5>
<div class="fs-18px fw-600 text-{{ system_status.color }}">{{ system_status.status }}</div>
<div class="text-muted small">{{ system_status.uptime }}</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<div class="w-60px h-60px bg-primary bg-opacity-20 d-flex align-items-center justify-content-center rounded-circle mx-auto mb-3">
<i class="fa fa-microchip fa-2x text-primary"></i>
</div>
<h5>CPU Usage</h5>
<div class="fs-24px fw-600 text-primary">{{ cpu_usage }}%</div>
<div class="progress mt-2" style="height: 6px;">
<div class="progress-bar bg-primary" style="width: {{ cpu_usage }}%"></div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<div class="w-60px h-60px bg-info bg-opacity-20 d-flex align-items-center justify-content-center rounded-circle mx-auto mb-3">
<i class="fa fa-memory fa-2x text-info"></i>
</div>
<h5>Memory Usage</h5>
<div class="fs-24px fw-600 text-info">{{ memory_usage }}%</div>
<div class="progress mt-2" style="height: 6px;">
<div class="progress-bar bg-info" style="width: {{ memory_usage }}%"></div>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card text-center">
<div class="card-body">
<div class="w-60px h-60px bg-warning bg-opacity-20 d-flex align-items-center justify-content-center rounded-circle mx-auto mb-3">
<i class="fa fa-hdd fa-2x text-warning"></i>
</div>
<h5>Disk Usage</h5>
<div class="fs-24px fw-600 text-warning">{{ disk_usage }}%</div>
<div class="progress mt-2" style="height: 6px;">
<div class="progress-bar bg-warning" style="width: {{ disk_usage }}%"></div>
</div>
</div>
</div>
</div>
</div>
<!-- Performance Charts -->
<div class="row mb-4">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4 class="card-title">CPU & Memory Usage</h4>
<div class="card-toolbar">
<select class="form-select form-select-sm" onchange="updateTimeRange(this.value)">
<option value="1h">Last Hour</option>
<option value="6h">Last 6 Hours</option>
<option value="24h" selected>Last 24 Hours</option>
<option value="7d">Last 7 Days</option>
</select>
</div>
</div>
<div class="card-body">
<canvas id="performanceChart" height="300"></canvas>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4 class="card-title">Network Traffic</h4>
</div>
<div class="card-body">
<canvas id="networkChart" height="300"></canvas>
</div>
</div>
</div>
</div>
<!-- Database Performance -->
<div class="row mb-4">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4 class="card-title">Database Performance</h4>
</div>
<div class="card-body">
<div class="row">
<div class="col-6">
<div class="text-center">
<div class="fs-24px fw-600 text-primary">{{ db_connections }}</div>
<div class="text-muted">Active Connections</div>
</div>
</div>
<div class="col-6">
<div class="text-center">
<div class="fs-24px fw-600 text-info">{{ db_queries_per_sec }}</div>
<div class="text-muted">Queries/sec</div>
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col-6">
<div class="text-center">
<div class="fs-20px fw-600 text-success">{{ db_avg_response_time }}ms</div>
<div class="text-muted">Avg Response Time</div>
</div>
</div>
<div class="col-6">
<div class="text-center">
<div class="fs-20px fw-600 text-warning">{{ db_slow_queries }}</div>
<div class="text-muted">Slow Queries</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4 class="card-title">Application Metrics</h4>
</div>
<div class="card-body">
<div class="row">
<div class="col-6">
<div class="text-center">
<div class="fs-24px fw-600 text-primary">{{ active_users }}</div>
<div class="text-muted">Active Users</div>
</div>
</div>
<div class="col-6">
<div class="text-center">
<div class="fs-24px fw-600 text-info">{{ requests_per_min }}</div>
<div class="text-muted">Requests/min</div>
</div>
</div>
</div>
<hr>
<div class="row">
<div class="col-6">
<div class="text-center">
<div class="fs-20px fw-600 text-success">{{ avg_response_time }}ms</div>
<div class="text-muted">Avg Response Time</div>
</div>
</div>
<div class="col-6">
<div class="text-center">
<div class="fs-20px fw-600 text-danger">{{ error_rate }}%</div>
<div class="text-muted">Error Rate</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Service Status -->
<div class="row mb-4">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<h4 class="card-title">Service Status</h4>
</div>
<div class="card-body">
<div class="row">
{% for service in services %}
<div class="col-md-3 mb-3">
<div class="d-flex align-items-center">
<div class="w-40px h-40px bg-{{ service.status_color }} bg-opacity-20 d-flex align-items-center justify-content-center rounded-circle me-3">
<i class="fa fa-{{ service.icon }} text-{{ service.status_color }}"></i>
</div>
<div>
<div class="fw-bold">{{ service.name }}</div>
<div class="text-muted small">
<span class="badge bg-{{ service.status_color }}">{{ service.status }}</span>
{% if service.response_time %}
<span class="ms-2">{{ service.response_time }}ms</span>
{% endif %}
</div>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
<!-- Recent Alerts -->
<div class="row">
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4 class="card-title">Recent Alerts</h4>
<div class="card-toolbar">
<a href="{% url 'core:system_alerts' %}" class="btn btn-outline-primary btn-sm">
View All
</a>
</div>
</div>
<div class="card-body">
{% for alert in recent_alerts %}
<div class="d-flex align-items-center mb-3">
<div class="w-40px h-40px bg-{{ alert.severity_color }} bg-opacity-20 d-flex align-items-center justify-content-center rounded-circle me-3">
<i class="fa fa-{{ alert.icon }} text-{{ alert.severity_color }}"></i>
</div>
<div class="flex-1">
<div class="fw-bold">{{ alert.title }}</div>
<div class="text-muted small">{{ alert.message|truncatechars:50 }}</div>
<div class="text-muted small">{{ alert.created_at|timesince }} ago</div>
</div>
<div>
<span class="badge bg-{{ alert.severity_color }}">{{ alert.get_severity_display }}</span>
</div>
</div>
{% empty %}
<div class="text-center text-muted">
<i class="fa fa-check-circle fa-3x mb-3"></i>
<div>No recent alerts</div>
</div>
{% endfor %}
</div>
</div>
</div>
<div class="col-md-6">
<div class="card">
<div class="card-header">
<h4 class="card-title">System Logs</h4>
<div class="card-toolbar">
<a href="{% url 'core:log_viewer' %}" class="btn btn-outline-primary btn-sm">
View All
</a>
</div>
</div>
<div class="card-body">
{% for log in recent_logs %}
<div class="d-flex align-items-center mb-3">
<div class="w-40px h-40px bg-{{ log.level_color }} bg-opacity-20 d-flex align-items-center justify-content-center rounded-circle me-3">
<i class="fa fa-{{ log.level_icon }} text-{{ log.level_color }}"></i>
</div>
<div class="flex-1">
<div class="fw-bold">{{ log.message|truncatechars:40 }}</div>
<div class="text-muted small">{{ log.logger_name }} - {{ log.created_at|timesince }} ago</div>
</div>
<div>
<span class="badge bg-{{ log.level_color }}">{{ log.get_level_display }}</span>
</div>
</div>
{% empty %}
<div class="text-center text-muted">
<i class="fa fa-file-text fa-3x mb-3"></i>
<div>No recent logs</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block js %}
<script src="{% static 'assets/plugins/chart.js/dist/Chart.min.js' %}"></script>
<script>
var performanceChart, networkChart;
var autoRefreshInterval;
var autoRefreshEnabled = false;
$(document).ready(function() {
initializeCharts();
});
function initializeCharts() {
// Performance Chart
var performanceCtx = document.getElementById('performanceChart').getContext('2d');
performanceChart = new Chart(performanceCtx, {
type: 'line',
data: {
labels: {{ performance_labels|safe }},
datasets: [{
label: 'CPU Usage (%)',
data: {{ cpu_data|safe }},
borderColor: 'rgb(54, 162, 235)',
backgroundColor: 'rgba(54, 162, 235, 0.1)',
tension: 0.4
}, {
label: 'Memory Usage (%)',
data: {{ memory_data|safe }},
borderColor: 'rgb(255, 99, 132)',
backgroundColor: 'rgba(255, 99, 132, 0.1)',
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
max: 100
}
},
plugins: {
legend: {
position: 'top'
}
}
}
});
// Network Chart
var networkCtx = document.getElementById('networkChart').getContext('2d');
networkChart = new Chart(networkCtx, {
type: 'line',
data: {
labels: {{ network_labels|safe }},
datasets: [{
label: 'Incoming (MB/s)',
data: {{ network_in_data|safe }},
borderColor: 'rgb(75, 192, 192)',
backgroundColor: 'rgba(75, 192, 192, 0.1)',
tension: 0.4
}, {
label: 'Outgoing (MB/s)',
data: {{ network_out_data|safe }},
borderColor: 'rgb(255, 205, 86)',
backgroundColor: 'rgba(255, 205, 86, 0.1)',
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true
}
},
plugins: {
legend: {
position: 'top'
}
}
}
});
}
function refreshMetrics() {
$.get('{% url "core:system_metrics" %}', function(data) {
// Update metric cards
updateMetricCards(data);
// Update charts
updateCharts(data);
toastr.success('Metrics refreshed');
}).fail(function() {
toastr.error('Failed to refresh metrics');
});
}
function updateMetricCards(data) {
// Update CPU usage
$('.cpu-usage').text(data.cpu_usage + '%');
$('.cpu-progress').css('width', data.cpu_usage + '%');
// Update Memory usage
$('.memory-usage').text(data.memory_usage + '%');
$('.memory-progress').css('width', data.memory_usage + '%');
// Update Disk usage
$('.disk-usage').text(data.disk_usage + '%');
$('.disk-progress').css('width', data.disk_usage + '%');
// Update other metrics
$('.active-users').text(data.active_users);
$('.requests-per-min').text(data.requests_per_min);
$('.avg-response-time').text(data.avg_response_time + 'ms');
$('.error-rate').text(data.error_rate + '%');
}
function updateCharts(data) {
// Update performance chart
performanceChart.data.labels = data.performance_labels;
performanceChart.data.datasets[0].data = data.cpu_data;
performanceChart.data.datasets[1].data = data.memory_data;
performanceChart.update();
// Update network chart
networkChart.data.labels = data.network_labels;
networkChart.data.datasets[0].data = data.network_in_data;
networkChart.data.datasets[1].data = data.network_out_data;
networkChart.update();
}
function updateTimeRange(range) {
$.get('{% url "core:system_metrics" %}', {
'time_range': range
}, function(data) {
updateCharts(data);
}).fail(function() {
toastr.error('Failed to update time range');
});
}
function toggleAutoRefresh() {
if (autoRefreshEnabled) {
clearInterval(autoRefreshInterval);
autoRefreshEnabled = false;
$('#autoRefreshIcon').removeClass('fa-pause').addClass('fa-play');
toastr.info('Auto-refresh disabled');
} else {
autoRefreshInterval = setInterval(function() {
refreshMetrics();
}, 30000); // Refresh every 30 seconds
autoRefreshEnabled = true;
$('#autoRefreshIcon').removeClass('fa-play').addClass('fa-pause');
toastr.info('Auto-refresh enabled (30s interval)');
}
}
// Cleanup on page unload
$(window).on('beforeunload', function() {
if (autoRefreshInterval) {
clearInterval(autoRefreshInterval);
}
});
</script>
{% endblock %}