"feat: Update database configuration and documentation for monitoring system"
This commit is contained in:
@@ -49,6 +49,9 @@ class AdminLiveDashboard {
|
||||
|
||||
// Initial Load
|
||||
this.loadLiveStats();
|
||||
|
||||
// Error Monitoring System
|
||||
this.initErrorMonitoring();
|
||||
}
|
||||
|
||||
bindEvents() {
|
||||
@@ -366,6 +369,211 @@ class AdminLiveDashboard {
|
||||
const meta = document.querySelector('meta[name="csrf-token"]');
|
||||
return meta ? meta.getAttribute('content') : '';
|
||||
}
|
||||
|
||||
// Error Monitoring System
|
||||
initErrorMonitoring() {
|
||||
// Check system health every 30 seconds
|
||||
this.checkSystemHealth();
|
||||
setInterval(() => this.checkSystemHealth(), 30000);
|
||||
|
||||
// Setup error alert event handlers
|
||||
this.setupErrorAlertHandlers();
|
||||
}
|
||||
|
||||
async checkSystemHealth() {
|
||||
try {
|
||||
const response = await fetch('/api/admin/system-health');
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
this.updateHealthDisplay(data);
|
||||
this.updateErrorAlerts(data);
|
||||
} else {
|
||||
console.error('System health check failed:', data.error);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking system health:', error);
|
||||
}
|
||||
}
|
||||
|
||||
updateHealthDisplay(data) {
|
||||
// Update database health status
|
||||
const statusIndicator = document.getElementById('db-status-indicator');
|
||||
const statusText = document.getElementById('db-status-text');
|
||||
const lastMigration = document.getElementById('last-migration');
|
||||
const schemaIntegrity = document.getElementById('schema-integrity');
|
||||
const recentErrorsCount = document.getElementById('recent-errors-count');
|
||||
|
||||
if (statusIndicator && statusText) {
|
||||
if (data.health_status === 'critical') {
|
||||
statusIndicator.className = 'w-3 h-3 bg-red-500 rounded-full animate-pulse';
|
||||
statusText.textContent = 'Kritisch';
|
||||
statusText.className = 'text-sm font-medium text-red-600 dark:text-red-400';
|
||||
} else if (data.health_status === 'warning') {
|
||||
statusIndicator.className = 'w-3 h-3 bg-yellow-500 rounded-full animate-pulse';
|
||||
statusText.textContent = 'Warnung';
|
||||
statusText.className = 'text-sm font-medium text-yellow-600 dark:text-yellow-400';
|
||||
} else {
|
||||
statusIndicator.className = 'w-3 h-3 bg-green-400 rounded-full animate-pulse';
|
||||
statusText.textContent = 'Gesund';
|
||||
statusText.className = 'text-sm font-medium text-green-600 dark:text-green-400';
|
||||
}
|
||||
}
|
||||
|
||||
if (lastMigration) {
|
||||
lastMigration.textContent = data.last_migration || 'Unbekannt';
|
||||
}
|
||||
|
||||
if (schemaIntegrity) {
|
||||
schemaIntegrity.textContent = data.schema_integrity || 'Prüfung';
|
||||
if (data.schema_integrity === 'FEHLER') {
|
||||
schemaIntegrity.className = 'text-lg font-semibold text-red-600 dark:text-red-400';
|
||||
} else {
|
||||
schemaIntegrity.className = 'text-lg font-semibold text-green-600 dark:text-green-400';
|
||||
}
|
||||
}
|
||||
|
||||
if (recentErrorsCount) {
|
||||
const errorCount = data.recent_errors_count || 0;
|
||||
recentErrorsCount.textContent = errorCount;
|
||||
if (errorCount > 0) {
|
||||
recentErrorsCount.className = 'text-lg font-semibold text-red-600 dark:text-red-400';
|
||||
} else {
|
||||
recentErrorsCount.className = 'text-lg font-semibold text-green-600 dark:text-green-400';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateErrorAlerts(data) {
|
||||
const alertContainer = document.getElementById('critical-errors-alert');
|
||||
const errorList = document.getElementById('error-list');
|
||||
|
||||
if (!alertContainer || !errorList) return;
|
||||
|
||||
const allErrors = [...(data.critical_errors || []), ...(data.warnings || [])];
|
||||
|
||||
if (allErrors.length > 0) {
|
||||
// Show alert container
|
||||
alertContainer.classList.remove('hidden');
|
||||
|
||||
// Clear previous errors
|
||||
errorList.innerHTML = '';
|
||||
|
||||
// Add each error
|
||||
allErrors.forEach(error => {
|
||||
const errorElement = document.createElement('div');
|
||||
errorElement.className = `p-3 rounded-lg border-l-4 ${
|
||||
error.severity === 'critical' ? 'bg-red-50 dark:bg-red-900/30 border-red-500' :
|
||||
error.severity === 'high' ? 'bg-orange-50 dark:bg-orange-900/30 border-orange-500' :
|
||||
'bg-yellow-50 dark:bg-yellow-900/30 border-yellow-500'
|
||||
}`;
|
||||
|
||||
errorElement.innerHTML = `
|
||||
<div class="flex items-start justify-between">
|
||||
<div class="flex-1">
|
||||
<h4 class="font-medium ${
|
||||
error.severity === 'critical' ? 'text-red-800 dark:text-red-200' :
|
||||
error.severity === 'high' ? 'text-orange-800 dark:text-orange-200' :
|
||||
'text-yellow-800 dark:text-yellow-200'
|
||||
}">${error.message}</h4>
|
||||
<p class="text-sm mt-1 ${
|
||||
error.severity === 'critical' ? 'text-red-600 dark:text-red-300' :
|
||||
error.severity === 'high' ? 'text-orange-600 dark:text-orange-300' :
|
||||
'text-yellow-600 dark:text-yellow-300'
|
||||
}">💡 ${error.suggested_fix}</p>
|
||||
<p class="text-xs mt-1 text-gray-500 dark:text-gray-400">
|
||||
📅 ${new Date(error.timestamp).toLocaleString('de-DE')}
|
||||
</p>
|
||||
</div>
|
||||
<span class="ml-2 px-2 py-1 text-xs font-medium rounded-full ${
|
||||
error.severity === 'critical' ? 'bg-red-100 text-red-800 dark:bg-red-800 dark:text-red-100' :
|
||||
error.severity === 'high' ? 'bg-orange-100 text-orange-800 dark:bg-orange-800 dark:text-orange-100' :
|
||||
'bg-yellow-100 text-yellow-800 dark:bg-yellow-800 dark:text-yellow-100'
|
||||
}">
|
||||
${error.severity.toUpperCase()}
|
||||
</span>
|
||||
</div>
|
||||
`;
|
||||
|
||||
errorList.appendChild(errorElement);
|
||||
});
|
||||
} else {
|
||||
// Hide alert container
|
||||
alertContainer.classList.add('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
setupErrorAlertHandlers() {
|
||||
// Fix errors button
|
||||
const fixErrorsBtn = document.getElementById('fix-errors-btn');
|
||||
if (fixErrorsBtn) {
|
||||
fixErrorsBtn.addEventListener('click', async () => {
|
||||
await this.fixErrors();
|
||||
});
|
||||
}
|
||||
|
||||
// Dismiss errors button
|
||||
const dismissErrorsBtn = document.getElementById('dismiss-errors-btn');
|
||||
if (dismissErrorsBtn) {
|
||||
dismissErrorsBtn.addEventListener('click', () => {
|
||||
const alertContainer = document.getElementById('critical-errors-alert');
|
||||
if (alertContainer) {
|
||||
alertContainer.classList.add('hidden');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// View details button
|
||||
const viewDetailsBtn = document.getElementById('view-error-details-btn');
|
||||
if (viewDetailsBtn) {
|
||||
viewDetailsBtn.addEventListener('click', () => {
|
||||
// Redirect to logs tab
|
||||
window.location.href = '/admin-dashboard?tab=logs';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async fixErrors() {
|
||||
const fixBtn = document.getElementById('fix-errors-btn');
|
||||
if (!fixBtn) return;
|
||||
|
||||
// Show loading state
|
||||
const originalText = fixBtn.innerHTML;
|
||||
fixBtn.innerHTML = '🔄 Repariere...';
|
||||
fixBtn.disabled = true;
|
||||
|
||||
try {
|
||||
const response = await fetch('/api/admin/fix-errors', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (data.success) {
|
||||
// Show success message
|
||||
this.showNotification('✅ Automatische Reparatur erfolgreich durchgeführt!', 'success');
|
||||
|
||||
// Refresh health check
|
||||
setTimeout(() => {
|
||||
this.checkSystemHealth();
|
||||
}, 2000);
|
||||
} else {
|
||||
// Show error message
|
||||
this.showNotification(`❌ Reparatur fehlgeschlagen: ${data.error}`, 'error');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('Error fixing errors:', error);
|
||||
this.showNotification('❌ Fehler bei der automatischen Reparatur', 'error');
|
||||
} finally {
|
||||
// Restore button
|
||||
fixBtn.innerHTML = originalText;
|
||||
fixBtn.disabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize when DOM is ready
|
||||
|
Reference in New Issue
Block a user