Zwischenstand - ohne Prometheus

Dieser Commit ist enthalten in:
2025-06-19 12:02:25 +02:00
Ursprung c8222bdcbb
Commit c30d974d57
12 geänderte Dateien mit 1408 neuen und 220 gelöschten Zeilen

Datei anzeigen

@@ -59,12 +59,15 @@
margin-top: 20px;
}
.grafana-info {
background: #e7f3ff;
border: 1px solid #b3d9ff;
padding: 15px;
border-radius: 8px;
margin-bottom: 20px;
.loading-spinner {
text-align: center;
padding: 50px;
}
.no-data {
text-align: center;
padding: 30px;
color: #6c757d;
}
</style>
{% endblock %}
@@ -77,21 +80,6 @@
</div>
</div>
<!-- Grafana Integration Info -->
<div class="grafana-info">
<div class="row align-items-center">
<div class="col-md-8">
<h5><i class="bi bi-graph-up"></i> Erweiterte Analytics verfügbar</h5>
<p class="mb-0">Für detaillierte Dashboards und erweiterte Analysen nutzen Sie unser Grafana Dashboard.</p>
</div>
<div class="col-md-4 text-end">
<a href="http://localhost:3000/d/license-server-overview" target="_blank" class="btn btn-primary">
<i class="bi bi-box-arrow-up-right"></i> Grafana öffnen
</a>
</div>
</div>
</div>
<!-- Date Range Selector -->
<div class="date-range-selector">
<div class="row align-items-center">
@@ -115,115 +103,33 @@
<!-- Key Metrics Overview -->
<div class="row mb-4">
<div class="col-md-3">
<div class="col-md-4">
<div class="stat-box">
<div class="stat-value">1,234</div>
<div class="stat-value" id="active-licenses">-</div>
<div class="stat-label">Aktive Lizenzen</div>
<div class="trend-up">
<i class="bi bi-arrow-up"></i> +12% vs. Vormonat
</div>
</div>
</div>
<div class="col-md-3">
<div class="col-md-4">
<div class="stat-box">
<div class="stat-value">45.2K</div>
<div class="stat-value" id="total-validations">-</div>
<div class="stat-label">Validierungen</div>
<div class="trend-up">
<i class="bi bi-arrow-up"></i> +8% vs. Vormonat
</div>
</div>
</div>
<div class="col-md-3">
<div class="col-md-4">
<div class="stat-box">
<div class="stat-value">€12.5K</div>
<div class="stat-label">MRR</div>
<div class="trend-up">
<i class="bi bi-arrow-up"></i> +15% vs. Vormonat
</div>
</div>
</div>
<div class="col-md-3">
<div class="stat-box">
<div class="stat-value">2.3%</div>
<div class="stat-label">Churn Rate</div>
<div class="trend-down">
<i class="bi bi-arrow-down"></i> -0.5% vs. Vormonat
</div>
<div class="stat-value" id="active-devices">-</div>
<div class="stat-label">Aktive Geräte</div>
</div>
</div>
</div>
<!-- Charts Row 1 -->
<div class="row">
<div class="col-md-6">
<div class="analytics-card">
<h5>Lizenz-Nutzung über Zeit</h5>
<div class="chart-container">
<canvas id="usageChart"></canvas>
</div>
</div>
</div>
<div class="col-md-6">
<div class="analytics-card">
<h5>Validierungen nach Stunde</h5>
<div class="chart-container">
<canvas id="validationChart"></canvas>
</div>
</div>
</div>
</div>
<!-- Charts Row 2 -->
<div class="row mt-4">
<div class="col-md-4">
<div class="analytics-card">
<h5>Lizenztyp-Verteilung</h5>
<div class="chart-container">
<canvas id="licenseTypeChart"></canvas>
</div>
</div>
</div>
<div class="col-md-4">
<div class="analytics-card">
<h5>Geografische Verteilung</h5>
<div class="chart-container">
<canvas id="geoChart"></canvas>
</div>
</div>
</div>
<div class="col-md-4">
<div class="analytics-card">
<h5>Top 10 Kunden</h5>
<div style="height: 300px; overflow-y: auto;">
<table class="table table-sm">
<thead>
<tr>
<th>Kunde</th>
<th>Lizenzen</th>
<th>Nutzung</th>
</tr>
</thead>
<tbody>
<tr>
<td>ACME Corp</td>
<td>45</td>
<td><span class="badge bg-success">Hoch</span></td>
</tr>
<tr>
<td>TechStart GmbH</td>
<td>32</td>
<td><span class="badge bg-success">Hoch</span></td>
</tr>
<tr>
<td>Global Solutions</td>
<td>28</td>
<td><span class="badge bg-warning">Mittel</span></td>
</tr>
<!-- More rows... -->
</tbody>
</table>
</div>
</div>
<!-- Analytics Notice -->
<div class="analytics-card">
<div class="no-data">
<i class="bi bi-info-circle" style="font-size: 3rem; color: #6c757d;"></i>
<h5 class="mt-3">Analytics-Daten werden gesammelt</h5>
<p>Die detaillierten Analysen stehen zur Verfügung, sobald genügend Daten vorhanden sind.</p>
<p>Nutzen Sie das <a href="{{ url_for('monitoring.live_dashboard') }}">Live Dashboard</a> für Echtzeit-Statistiken.</p>
</div>
</div>
@@ -245,114 +151,43 @@
{% endblock %}
{% block extra_js %}
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.js"></script>
<script>
let usageChart, validationChart, licenseTypeChart, geoChart;
function initCharts() {
// Usage over time
const usageCtx = document.getElementById('usageChart').getContext('2d');
usageChart = new Chart(usageCtx, {
type: 'line',
data: {
labels: ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'],
datasets: [{
label: 'Aktive Lizenzen',
data: [1180, 1205, 1195, 1220, 1234, 1150, 1100],
borderColor: 'rgb(75, 192, 192)',
backgroundColor: 'rgba(75, 192, 192, 0.1)',
tension: 0.1
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
// Validations by hour
const validationCtx = document.getElementById('validationChart').getContext('2d');
validationChart = new Chart(validationCtx, {
type: 'bar',
data: {
labels: ['00', '04', '08', '12', '16', '20'],
datasets: [{
label: 'Validierungen',
data: [120, 80, 450, 680, 520, 340],
backgroundColor: 'rgba(54, 162, 235, 0.5)',
borderColor: 'rgba(54, 162, 235, 1)',
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
// License type distribution
const typeCtx = document.getElementById('licenseTypeChart').getContext('2d');
licenseTypeChart = new Chart(typeCtx, {
type: 'doughnut',
data: {
labels: ['Professional', 'Enterprise', 'Starter', 'Trial'],
datasets: [{
data: [45, 30, 20, 5],
backgroundColor: [
'rgba(255, 99, 132, 0.5)',
'rgba(54, 162, 235, 0.5)',
'rgba(255, 205, 86, 0.5)',
'rgba(75, 192, 192, 0.5)'
]
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
// Geographic distribution
const geoCtx = document.getElementById('geoChart').getContext('2d');
geoChart = new Chart(geoCtx, {
type: 'bar',
data: {
labels: ['DE', 'AT', 'CH', 'US', 'UK'],
datasets: [{
label: 'Aktive Nutzer',
data: [580, 230, 180, 120, 90],
backgroundColor: 'rgba(153, 102, 255, 0.5)',
borderColor: 'rgba(153, 102, 255, 1)',
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
indexAxis: 'y'
}
});
function loadAnalyticsData() {
// Load basic statistics from database
fetch('/monitoring/api/live-stats')
.then(response => response.json())
.then(data => {
document.getElementById('active-licenses').textContent = data.active_licenses || '0';
document.getElementById('total-validations').textContent = data.validations_last_minute || '0';
document.getElementById('active-devices').textContent = data.active_devices || '0';
})
.catch(error => {
console.error('Error loading analytics:', error);
document.getElementById('active-licenses').textContent = '0';
document.getElementById('total-validations').textContent = '0';
document.getElementById('active-devices').textContent = '0';
});
}
function updateAnalytics() {
const range = document.getElementById('date-range').value;
// In production, this would fetch new data based on the selected range
console.log('Updating analytics for range:', range);
loadAnalyticsData();
}
function refreshAnalytics() {
// Refresh all data
location.reload();
loadAnalyticsData();
}
function exportReport(format) {
alert(`Exporting report as ${format.toUpperCase()}...`);
// In production, this would trigger actual export
alert(`Export-Funktion wird implementiert für Format: ${format.toUpperCase()}`);
}
// Initialize charts on page load
// Load data on page load
document.addEventListener('DOMContentLoaded', function() {
initCharts();
loadAnalyticsData();
// Refresh every 30 seconds
setInterval(loadAnalyticsData, 30000);
});
</script>
{% endblock %}