- Move 12 markdown files from root to docs/ subdirectories - Organize documentation by category: • docs/troubleshooting/ (1 file) - Technical troubleshooting guides • docs/deployment/ (4 files) - Deployment and security documentation • docs/guides/ (3 files) - Feature-specific guides • docs/planning/ (4 files) - Planning and improvement proposals Root directory cleanup: - Reduced from 16 to 4 markdown files in root - Only essential project files remain: • CLAUDE.md (AI instructions) • README.md (Main project readme) • CLEANUP_PLAN.md (Current cleanup plan) • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements) This improves: ✅ Documentation discoverability ✅ Logical organization by purpose ✅ Clean root directory ✅ Better maintainability
211 lines
9.1 KiB
PHP
211 lines
9.1 KiB
PHP
<layout name="layouts/admin" />
|
|
|
|
<div class="section">
|
|
<h2>Cache Metrics</h2>
|
|
<p class="section-description">Cache Performance Monitoring und Statistiken</p>
|
|
|
|
<!-- Cache Overview Cards -->
|
|
<div class="admin-grid admin-grid--4col">
|
|
<div class="admin-card metric-card">
|
|
<div class="metric-card__value">{{ hit_rate }}%</div>
|
|
<div class="metric-card__label">Hit Rate</div>
|
|
<div class="metric-card__change metric-card__change--{{ hit_rate >= 80 ? 'positive' : 'negative' }}">
|
|
{{ hit_rate >= 80 ? 'Excellent' : (hit_rate >= 60 ? 'Good' : 'Needs Improvement') }}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="admin-card metric-card">
|
|
<div class="metric-card__value">{{ total_operations }}</div>
|
|
<div class="metric-card__label">Total Operations</div>
|
|
<div class="metric-card__change">Since startup</div>
|
|
</div>
|
|
|
|
<div class="admin-card metric-card">
|
|
<div class="metric-card__value">{{ avg_latency_ms }}ms</div>
|
|
<div class="metric-card__label">Average Latency</div>
|
|
<div class="metric-card__change metric-card__change--{{ avg_latency_ms <= 5 ? 'positive' : 'negative' }}">
|
|
{{ avg_latency_ms <= 5 ? 'Fast' : 'Slow' }}
|
|
</div>
|
|
</div>
|
|
|
|
<div class="admin-card metric-card">
|
|
<div class="metric-card__value">{{ total_size_mb }}MB</div>
|
|
<div class="metric-card__label">Total Cache Size</div>
|
|
<div class="metric-card__change">{{ active_drivers }} active drivers</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Health Status -->
|
|
<div class="admin-card">
|
|
<div class="admin-card__header">
|
|
<h3 class="admin-card__title">Cache Health Status</h3>
|
|
<span class="admin-table__status admin-table__status--{{ health_status === 'healthy' ? 'success' : (health_status === 'warning' ? 'warning' : 'error') }}">
|
|
<span class="status-indicator status-indicator--{{ health_status === 'healthy' ? 'success' : (health_status === 'warning' ? 'warning' : 'error') }}"></span>
|
|
{{ health_status|upper }}
|
|
</span>
|
|
</div>
|
|
<div class="admin-card__content">
|
|
<p>Cache system efficiency rating: <strong>{{ efficiency_rating }}</strong></p>
|
|
<if condition="{{ recommendations_count > 0 }}">
|
|
<p class="text-warning">{{ recommendations_count }} recommendations available for optimization.</p>
|
|
</if>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Driver Statistics -->
|
|
<if condition="{{ active_drivers > 0 }}">
|
|
<div class="admin-card">
|
|
<div class="admin-card__header">
|
|
<h3 class="admin-card__title">Driver Statistics</h3>
|
|
</div>
|
|
<div class="admin-card__content">
|
|
<div class="admin-table-wrapper">
|
|
<table class="admin-table">
|
|
<thead>
|
|
<tr>
|
|
<th>Driver</th>
|
|
<th>Hit Rate</th>
|
|
<th>Operations</th>
|
|
<th>Avg Latency</th>
|
|
<th>Size (MB)</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<for items="{{ driver_stats }}" key="driver" value="stats">
|
|
<tr>
|
|
<td class="font-mono">{{ driver }}</td>
|
|
<td>{{ stats.hit_rate }}%</td>
|
|
<td>{{ stats.operations }}</td>
|
|
<td>{{ stats.avg_latency }}ms</td>
|
|
<td>{{ stats.size }}MB</td>
|
|
</tr>
|
|
</for>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</if>
|
|
|
|
<!-- Real-time Metrics (JavaScript will update these) -->
|
|
<div class="admin-card">
|
|
<div class="admin-card__header">
|
|
<h3 class="admin-card__title">Real-time Metrics</h3>
|
|
<button id="refresh-metrics" class="admin-button admin-button--small">Refresh</button>
|
|
</div>
|
|
<div class="admin-card__content">
|
|
<div id="real-time-metrics">
|
|
<p>Loading real-time data...</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Actions -->
|
|
<div class="admin-card">
|
|
<div class="admin-card__header">
|
|
<h3 class="admin-card__title">Cache Actions</h3>
|
|
</div>
|
|
<div class="admin-card__content">
|
|
<div class="admin-actions">
|
|
<button id="reset-metrics" class="admin-button admin-button--warning">Reset Metrics</button>
|
|
<button id="generate-test-data" class="admin-button admin-button--secondary">Generate Test Data</button>
|
|
<a href="/admin/infrastructure/cache/metrics" class="admin-button admin-button--secondary">View JSON API</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
// Real-time metrics updating
|
|
function updateMetrics() {
|
|
fetch('/admin/infrastructure/cache/metrics')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.status === 'success') {
|
|
const container = document.getElementById('real-time-metrics');
|
|
const realTime = data.data.real_time;
|
|
const performance = data.data.performance_summary;
|
|
|
|
container.innerHTML = `
|
|
<div class="metrics-grid">
|
|
<div class="metric">
|
|
<strong>Current Hit Rate:</strong> ${(realTime.current_hit_rate * 100).toFixed(2)}%
|
|
</div>
|
|
<div class="metric">
|
|
<strong>Operations/sec:</strong> ${performance.ops_per_second}
|
|
</div>
|
|
<div class="metric">
|
|
<strong>Framework Activity:</strong> ${realTime.framework_cache_activity} keys
|
|
</div>
|
|
<div class="metric">
|
|
<strong>Last Updated:</strong> ${new Date(realTime.timestamp * 1000).toLocaleTimeString()}
|
|
</div>
|
|
</div>
|
|
<p class="text-muted">${realTime.sampling_note}</p>
|
|
`;
|
|
}
|
|
})
|
|
.catch(err => {
|
|
console.error('Error fetching metrics:', err);
|
|
});
|
|
}
|
|
|
|
// Auto-refresh every 5 seconds
|
|
setInterval(updateMetrics, 5000);
|
|
updateMetrics(); // Initial load
|
|
|
|
// Manual refresh button
|
|
document.getElementById('refresh-metrics').addEventListener('click', updateMetrics);
|
|
|
|
// Reset metrics button
|
|
document.getElementById('reset-metrics').addEventListener('click', function() {
|
|
if (confirm('Are you sure you want to reset all cache metrics?')) {
|
|
fetch('/admin/cache/metrics/reset', { method: 'POST' })
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
if (data.status === 'success') {
|
|
alert('Cache metrics have been reset');
|
|
location.reload();
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
// Generate test data button
|
|
document.getElementById('generate-test-data').addEventListener('click', function() {
|
|
fetch('/admin/cache/debug')
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
alert('Test cache operations generated');
|
|
updateMetrics();
|
|
});
|
|
});
|
|
</script>
|
|
|
|
<style>
|
|
.metrics-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
gap: 1rem;
|
|
margin-bottom: 1rem;
|
|
}
|
|
|
|
.metric {
|
|
padding: 0.5rem;
|
|
background: var(--bg-alt);
|
|
border-radius: var(--radius-md);
|
|
}
|
|
|
|
.admin-actions {
|
|
display: flex;
|
|
gap: 1rem;
|
|
flex-wrap: wrap;
|
|
}
|
|
|
|
.text-muted {
|
|
color: var(--muted);
|
|
font-size: 0.875rem;
|
|
font-style: italic;
|
|
}
|
|
</style> |