Files
gateway01/openvpn-monitor/assets/script.js

123 lines
3.8 KiB
JavaScript

function loadClients() {
fetch('clients.php')
.then(response => response.json())
.then(data => {
console.log('Загруженные клиенты:', data);
renderClientTable(data);
})
.catch(error => {
console.error('Ошибка загрузки данных:', error);
document.getElementById('client-table').innerHTML = '<tr><td colspan="12">Ошибка загрузки</td></tr>';
});
}
function renderClientTable(clients) {
const table = document.getElementById('client-table');
table.innerHTML = '';
const stats = { LZO: 0, ADAPTIVE: 0, STUB: 0, '—': 0 };
clients.forEach(client => {
const row = document.createElement('tr');
// TLS ошибка
if (client.tls_error) {
row.classList.add('tls-error');
row.title = client.tls_error;
}
// Сжатие
const compression = (client.compression || '—').toUpperCase();
stats[compression] = (stats[compression] || 0) + 1;
let compressionClass = 'compression-none';
if (compression === 'LZO') compressionClass = 'compression-lzo';
else if (compression === 'ADAPTIVE') compressionClass = 'compression-adaptive';
else if (compression === 'STUB') compressionClass = 'compression-stub';
// Потери
let lossClass = '';
if (client.loss_rate >= 10) lossClass = 'loss-high';
else if (client.loss_rate >= 1) lossClass = 'loss-medium';
row.innerHTML = `
<td>${client.name}</td>
<td>${client.real_ip}</td>
<td>${client.virtual_ip}</td>
<td>${client.connectedSince}</td>
<td>${formatBytes(client.bytes_received)}</td>
<td>${formatBytes(client.bytes_sent)}</td>
<td>${client.statusLabel}</td>
<td>${client.idleTime || '—'}</td>
<td class="${compressionClass}">${compression}</td>
<td>${client.packets_received ?? '—'}</td>
<td>${client.packets_lost ?? '—'}</td>
<td class="${lossClass}">${client.loss_rate ?? '—'}%</td>
`;
table.appendChild(row);
});
renderCompressionStats(stats);
}
function renderCompressionStats(stats) {
const container = document.getElementById('compression-stats');
container.innerHTML = `
<strong>Сжатие:</strong>
LZO: ${stats.LZO || 0},
Adaptive: ${stats.ADAPTIVE || 0},
Stub: ${stats.STUB || 0},
Нет: ${stats['—'] || 0}
`;
}
function formatBytes(bytes) {
if (bytes < 1024) return bytes + ' B';
if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + ' KB';
return (bytes / (1024 * 1024)).toFixed(1) + ' MB';
}
function loadTlsErrors() {
fetch('api/tls-errors.php')
.then(res => res.json())
.then(data => {
const container = document.getElementById('tls-errors');
container.innerHTML = '';
if (data.tls_errors && data.tls_errors.length > 0) {
data.tls_errors.forEach(err => {
const div = document.createElement('div');
div.textContent = err;
container.appendChild(div);
});
} else {
container.textContent = 'Нет TLS ошибок.';
}
})
.catch(() => {
document.getElementById('tls-errors').textContent = 'Ошибка загрузки данных.';
});
}
document.addEventListener('DOMContentLoaded', () => {
// Вкладки
const buttons = document.querySelectorAll('.tab-button');
const tabs = document.querySelectorAll('.tab-content');
buttons.forEach(btn => {
btn.addEventListener('click', () => {
buttons.forEach(b => b.classList.remove('active'));
tabs.forEach(t => t.classList.remove('active'));
btn.classList.add('active');
document.getElementById('tab-' + btn.dataset.tab).classList.add('active');
});
});
// Загрузка данных
loadClients();
loadTlsErrors();
setInterval(loadClients, 5000);
setInterval(loadTlsErrors, 10000);
});