3ebc115c创建于 2025年11月26日历史提交
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>log - go2rtc</title>
    <style>
        main > div {
            display: flex;
            flex-wrap: wrap;
            gap: 10px;
        }

        table tbody {
            font-size: 13px;
        }

        .trace {
            color: #585858 !important;
        }

        .debug {
            color: #808080 !important;
        }

        .info {
            color: #0174DF !important;
        }

        .warn {
            color: #FF9966 !important;
        }

        .error {
            color: #DF0101 !important;
        }
    </style>
</head>
<body>

<script src="main.js"></script>

<main>
    <div>
        <button id="clean">Clean</button>
        <button id="update">Auto Update: ON</button>
        <button id="reverse">Reverse Log Order: OFF</button>
    </div>
    <table>
        <thead>
        <tr>
            <th style="width: 100px">Time</th>
            <th style="width: 40px">Level</th>
            <th>Message</th>
        </tr>
        </thead>
        <tbody id="log">
        </tbody>
    </table>
</main>

<script>
    document.getElementById('clean').addEventListener('click', async () => {
        const r = await fetch('api/log', {method: 'DELETE'});
        if (r.ok) reload();
        alert(await r.text());
    });

    // Sanitizes the input text to prevent XSS when inserting into the DOM
    function escapeHTML(text) {
        return text
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#039;')
            .replace(/\n/g, '<br>');
    }

    const reverseBtn = document.getElementById('reverse');
    const update = document.getElementById('update');

    let reverseOrder = false;
    let autoUpdateEnabled = true;

    reverseBtn.textContent = `Reverse Log Order: ${reverseOrder ? 'ON' : 'OFF'}`;
    update.textContent = `Auto Update: ${autoUpdateEnabled ? 'ON' : 'OFF'}`;

    function applyLogStyling(jsonlines) {
        const KEYS = ['time', 'level', 'message'];
        let lines = JSON.parse('[' + jsonlines.trimEnd().replaceAll('\n', ',') + ']');
        if (reverseOrder) {
            lines = lines.reverse();
        }
        return lines.map(line => {
            const ts = new Date(line['time']).toLocaleString(undefined, {
                hour: 'numeric',
                minute: 'numeric',
                second: 'numeric',
                fractionalSecondDigits: 3
            });
            const msg = Object.keys(line).reduce((msg, key) => {
                return KEYS.indexOf(key) < 0 ? `${msg} ${key}=${line[key]}` : msg;
            }, line['message']);
            return `<tr class="${line['level']}"><td>${ts}</td><td>${line['level']}</td><td>${escapeHTML(msg)}</td></tr>`;
        }).join('');
    }

    function reload() {
        const url = new URL('api/log', location.href);
        fetch(url, {cache: 'no-cache'})
            .then(response => response.text())
            .then(data => {
                // Apply styling to the log data
                document.getElementById('log').innerHTML = applyLogStyling(data);
            })
            .catch(error => {
                console.error('An error occurred:', error);
            });
    }

    reload();

    update.textContent = `Auto Update: ${autoUpdateEnabled ? 'ON' : 'OFF'}`;
    update.addEventListener('click', () => {
        autoUpdateEnabled = !autoUpdateEnabled;
        update.textContent = `Auto Update: ${autoUpdateEnabled ? 'ON' : 'OFF'}`;
    });

    // Toggle log order
    reverseBtn.textContent = `Reverse Log Order: ${reverseOrder ? 'ON' : 'OFF'}`;
    reverseBtn.addEventListener('click', () => {
        reverseOrder = !reverseOrder;
        reverseBtn.textContent = `Reverse Log Order: ${reverseOrder ? 'ON' : 'OFF'}`;
        reload(); // Reload logs to apply the new order
    });

    // Reload the logs every 5 seconds
    setInterval(() => {
        if (autoUpdateEnabled) reload();
    }, 5000);
</script>

</body>
</html>