Files
miku-discord/bot/static/system.html

409 lines
14 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🎛️ System Settings - Logging Configuration</title>
<link rel="icon" href="/static/miku-favicon.png" type="image/png">
<style>
body {
margin: 0;
font-family: monospace;
background-color: #121212;
color: #fff;
}
.container {
padding: 2rem;
max-width: 1600px;
margin: 0 auto;
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
padding-bottom: 1rem;
border-bottom: 2px solid #333;
}
h1 {
color: #61dafb;
margin: 0;
font-size: 1.8rem;
}
h2 {
color: #61dafb;
font-size: 1.3rem;
margin: 0 0 1rem 0;
}
.header-actions {
display: flex;
gap: 0.5rem;
}
button, select {
padding: 0.4rem 0.8rem;
background: #333;
color: #fff;
border: 1px solid #555;
font-family: monospace;
cursor: pointer;
font-size: 0.9rem;
}
button:hover, select:hover {
background: #444;
border-color: #666;
}
.btn-primary {
background: #61dafb;
color: #000;
border-color: #61dafb;
font-weight: bold;
}
.btn-primary:hover {
background: #4fa8c5;
}
.btn-secondary {
background: #555;
border-color: #666;
}
.btn-danger {
background: #d32f2f;
border-color: #d32f2f;
}
.btn-danger:hover {
background: #b71c1c;
}
.content {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2rem;
}
.card {
background: #1e1e1e;
border: 1px solid #333;
border-radius: 8px;
padding: 1.5rem;
}
.components-table {
width: 100%;
border-collapse: collapse;
margin-top: 1rem;
}
.components-table th {
background: #2a2a2a;
color: #61dafb;
padding: 0.8rem;
text-align: left;
font-weight: bold;
border-bottom: 2px solid #444;
}
.components-table td {
padding: 0.8rem;
border-bottom: 1px solid #2a2a2a;
vertical-align: top;
}
.components-table tr:hover {
background: #252525;
}
.component-description {
font-size: 0.8rem;
color: #999;
margin-top: 0.3rem;
}
.toggle {
position: relative;
display: inline-block;
width: 50px;
height: 24px;
}
.toggle input {
opacity: 0;
width: 0;
height: 0;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: #555;
transition: 0.3s;
border-radius: 24px;
}
.slider:before {
position: absolute;
content: "";
height: 18px;
width: 18px;
left: 3px;
bottom: 3px;
background-color: white;
transition: 0.3s;
border-radius: 50%;
}
input:checked + .slider {
background-color: #61dafb;
}
input:checked + .slider:before {
transform: translateX(26px);
}
.level-checkboxes {
display: flex;
gap: 0.5rem;
flex-wrap: wrap;
}
.level-checkbox {
display: flex;
align-items: center;
gap: 0.3rem;
}
.level-checkbox input[type="checkbox"] {
width: auto;
margin: 0;
cursor: pointer;
}
.level-checkbox label {
font-size: 0.85rem;
cursor: pointer;
}
.status-indicator {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
margin-right: 0.3rem;
}
.status-active {
background-color: #4CAF50;
}
.status-inactive {
background-color: #555;
}
.api-filters {
background: #2a2a2a;
border: 1px solid #444;
padding: 1rem;
margin-top: 1rem;
border-radius: 8px;
}
.api-filters h3 {
color: #61dafb;
font-size: 1rem;
margin-bottom: 0.8rem;
}
.filter-row {
margin-bottom: 0.8rem;
}
.filter-row label {
display: block;
font-weight: bold;
margin-bottom: 0.3rem;
color: #ccc;
}
.setting-row {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 0.8rem;
}
.setting-row label {
font-weight: bold;
color: #ccc;
}
input[type="text"], input[type="number"] {
width: 100%;
padding: 0.5rem;
background: #333;
color: #fff;
border: 1px solid #555;
font-family: monospace;
}
.log-preview {
background: #000;
color: #0f0;
padding: 1rem;
border-radius: 8px;
font-family: monospace;
font-size: 0.85rem;
max-height: 600px;
overflow-y: auto;
white-space: pre-wrap;
word-wrap: break-word;
border: 1px solid #333;
}
.log-preview-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 1rem;
}
.log-line {
margin-bottom: 3px;
line-height: 1.4;
}
.notification {
position: fixed;
bottom: 20px;
right: 20px;
background-color: #222;
color: #fff;
padding: 1rem;
border: 1px solid #555;
border-radius: 8px;
opacity: 0.95;
z-index: 1000;
font-size: 0.9rem;
animation: slideIn 0.3s ease-out;
}
.notification-success {
border-color: #4CAF50;
background: #1b4d1b;
}
.notification-error {
border-color: #d32f2f;
background: #4d1b1b;
}
@keyframes slideIn {
from {
transform: translateX(400px);
opacity: 0;
}
to {
transform: translateX(0);
opacity: 1;
}
}
.loading {
text-align: center;
padding: 2rem;
color: #999;
}
@media (max-width: 1200px) {
.content {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>🎛️ System Settings - Logging Configuration</h1>
<div class="header-actions">
<button class="btn-secondary" onclick="window.location.href='/'">← Back to Dashboard</button>
<button class="btn-primary" onclick="saveAllSettings()">💾 Save All</button>
<button class="btn-danger" onclick="resetToDefaults()">🔄 Reset to Defaults</button>
</div>
</div>
<div class="content">
<div class="card">
<h2>📊 Logging Components</h2>
<p style="color: #999; margin-bottom: 1rem; font-size: 0.9rem;">
Enable or disable specific log levels for each component. You can toggle any combination of levels.
</p>
<div class="api-filters" style="margin-bottom: 1.5rem;">
<h3>🌍 Global Level Controls</h3>
<p style="color: #999; font-size: 0.85rem; margin-bottom: 0.8rem;">
Quickly enable/disable a log level across all components
</p>
<div class="level-checkboxes">
<div class="level-checkbox">
<input type="checkbox" id="global_DEBUG" checked onchange="updateGlobalLevel('DEBUG', this.checked)">
<label for="global_DEBUG">🔍 DEBUG</label>
</div>
<div class="level-checkbox">
<input type="checkbox" id="global_INFO" checked onchange="updateGlobalLevel('INFO', this.checked)">
<label for="global_INFO"> INFO</label>
</div>
<div class="level-checkbox">
<input type="checkbox" id="global_WARNING" checked onchange="updateGlobalLevel('WARNING', this.checked)">
<label for="global_WARNING">⚠️ WARNING</label>
</div>
<div class="level-checkbox">
<input type="checkbox" id="global_ERROR" checked onchange="updateGlobalLevel('ERROR', this.checked)">
<label for="global_ERROR">❌ ERROR</label>
</div>
<div class="level-checkbox">
<input type="checkbox" id="global_CRITICAL" checked onchange="updateGlobalLevel('CRITICAL', this.checked)">
<label for="global_CRITICAL">🔥 CRITICAL</label>
</div>
<div class="level-checkbox">
<input type="checkbox" id="global_API" checked onchange="updateGlobalLevel('API', this.checked)">
<label for="global_API">🌐 API</label>
</div>
</div>
</div>
<div class="api-filters" style="margin-bottom: 1.5rem;">
<h3>🕐 Timestamp Format</h3>
<p style="color: #999; font-size: 0.85rem; margin-bottom: 0.8rem;">
Control how timestamps appear in logs
</p>
<div class="setting-row">
<label>Format:</label>
<select id="timestampFormat" onchange="updateTimestampFormat(this.value)">
<option value="datetime">Date + Time (2026-01-10 20:30:45)</option>
<option value="time">Time Only (20:30:45)</option>
<option value="date">Date Only (2026-01-10)</option>
<option value="off">No Timestamp</option>
</select>
</div>
</div>
<table class="components-table">
<thead>
<tr>
<th>Component</th>
<th>Enabled</th>
<th>Log Levels</th>
<th>Status</th>
</tr>
</thead>
<tbody id="componentsTable">
<tr><td colspan="4" class="loading">Loading components...</td></tr>
</tbody>
</table>
<div id="apiFilters" class="api-filters" style="display: none;">
<h3>🌐 API Request Filters</h3>
<div class="filter-row">
<label>Exclude Paths (comma-separated):</label>
<input type="text" id="excludePaths" placeholder="/health, /static/*">
</div>
<div class="filter-row">
<label>Exclude Status Codes (comma-separated):</label>
<input type="text" id="excludeStatus" placeholder="200, 304">
</div>
<div class="setting-row">
<label>Log Slow Requests (>1000ms):</label>
<label class="toggle">
<input type="checkbox" id="includeSlowRequests" checked>
<span class="slider"></span>
</label>
</div>
<div class="filter-row">
<label>Slow Request Threshold (ms):</label>
<input type="number" id="slowThreshold" value="1000" min="100" step="100">
</div>
<button class="btn-primary" onclick="saveApiFilters()" style="margin-top: 0.5rem;">Save API Filters</button>
</div>
</div>
<div class="card">
<h2>📜 Live Log Preview</h2>
<div class="log-preview-header">
<div>
<label>Component: </label>
<select id="previewComponent" onchange="loadLogPreview()"><option value="bot">Bot</option></select>
</div>
<button class="btn-secondary" onclick="loadLogPreview()">🔄 Refresh</button>
</div>
<div class="log-preview" id="logPreview">
<div class="loading">Select a component to view logs...</div>
</div>
</div>
</div>
</div>
<script src="/static/system-logic.js"></script>
</body>
</html>