Initial commit: project openvpn-monitor
This commit is contained in:
122
openvpn-monitor/assets/script.js
Normal file
122
openvpn-monitor/assets/script.js
Normal file
@@ -0,0 +1,122 @@
|
||||
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);
|
||||
});
|
||||
Reference in New Issue
Block a user