记录所有 console.log 即使控制台被清除也能查看
// ==UserScript== // @name Persistent Console Logger // @namespace http://tampermonkey.net/ // @version 1.0 // @description 记录所有 console.log 即使控制台被清除也能查看 // @author Your Name // @match *://*/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // 创建一个存储日志的数组 const logStorage = []; // 保存原始的 console.log 和 console.clear 方法 const originalLog = console.log; const originalClear = console.clear; // 重写 console.log 方法 console.log = function(...args) { // 将日志存储到 logStorage 数组 logStorage.push({ type: 'log', args: args, timestamp: new Date() }); // 调用原始的 console.log 方法 originalLog.apply(console, args); }; // 重写 console.warn 方法 console.warn = function(...args) { logStorage.push({ type: 'warn', args: args, timestamp: new Date() }); originalLog.apply(console, args); }; // 重写 console.error 方法 console.error = function(...args) { logStorage.push({ type: 'error', args: args, timestamp: new Date() }); originalLog.apply(console, args); }; // 重写 console.clear 方法 console.clear = function() { // 可以选择不清除 logStorage,或根据需要清除 // 这里选择不清除,确保日志仍然被记录 // 调用原始的 console.clear 方法 originalClear.apply(console); }; // 创建一个界面按钮来查看存储的日志 const createLogViewer = () => { // 创建按钮 const button = document.createElement('button'); button.innerText = '查看持久化日志'; button.style.position = 'fixed'; button.style.bottom = '20px'; button.style.right = '20px'; button.style.padding = '10px 20px'; button.style.zIndex = 10000; button.style.backgroundColor = '#4CAF50'; button.style.color = 'white'; button.style.border = 'none'; button.style.borderRadius = '5px'; button.style.cursor = 'pointer'; button.style.boxShadow = '0 4px 6px rgba(0, 0, 0, 0.1)'; button.title = '点击查看持久化的 console.log 日志'; // 创建日志查看窗口 const logWindow = document.createElement('div'); logWindow.style.position = 'fixed'; logWindow.style.top = '50px'; logWindow.style.right = '20px'; logWindow.style.width = '400px'; logWindow.style.height = '300px'; logWindow.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; logWindow.style.color = 'white'; logWindow.style.padding = '10px'; logWindow.style.borderRadius = '5px'; logWindow.style.overflowY = 'scroll'; logWindow.style.display = 'none'; logWindow.style.zIndex = 10000; logWindow.style.fontFamily = 'monospace'; logWindow.style.fontSize = '12px'; // 创建关闭按钮 const closeButton = document.createElement('button'); closeButton.innerText = '关闭'; closeButton.style.position = 'absolute'; closeButton.style.top = '10px'; closeButton.style.right = '10px'; closeButton.style.padding = '5px 10px'; closeButton.style.backgroundColor = '#f44336'; closeButton.style.color = 'white'; closeButton.style.border = 'none'; closeButton.style.borderRadius = '3px'; closeButton.style.cursor = 'pointer'; // 添加事件监听器 button.addEventListener('click', () => { logWindow.style.display = 'block'; renderLogs(); }); closeButton.addEventListener('click', () => { logWindow.style.display = 'none'; }); // 添加内容到 logWindow logWindow.appendChild(closeButton); // 创建日志内容容器 const logContent = document.createElement('div'); logContent.style.marginTop = '40px'; logWindow.appendChild(logContent); // 渲染日志内容 const renderLogs = () => { logContent.innerHTML = ''; // 清空之前的内容 logStorage.forEach(entry => { const logEntry = document.createElement('div'); logEntry.style.marginBottom = '5px'; logEntry.style.padding = '5px'; logEntry.style.borderBottom = '1px solid #555'; const time = entry.timestamp.toLocaleTimeString(); const type = entry.type.toUpperCase(); const args = entry.args.map(arg => { if (typeof arg === 'object') { try { return JSON.stringify(arg); } catch (e) { return '[Object]'; } } return arg.toString(); }).join(' '); logEntry.innerHTML = `<strong>[${time}] ${type}:</strong> ${args}`; logContent.appendChild(logEntry); }); }; // 自动刷新日志内容 setInterval(renderLogs, 1000); // 将按钮和日志窗口添加到页面 document.body.appendChild(button); document.body.appendChild(logWindow); }; // 延迟创建界面,确保页面加载完成 window.addEventListener('load', createLogViewer); // 可选:将日志存储到本地存储,以便刷新页面后仍能保留 const saveLogsToLocalStorage = () => { window.addEventListener('beforeunload', () => { localStorage.setItem('persistentLogs', JSON.stringify(logStorage)); }); // 读取本地存储的日志 const savedLogs = localStorage.getItem('persistentLogs'); if (savedLogs) { try { const parsedLogs = JSON.parse(savedLogs); // 将字符串的 timestamp 转回 Date 对象 parsedLogs.forEach(log => { if (log.timestamp) { log.timestamp = new Date(log.timestamp); } }); logStorage.push(...parsedLogs); localStorage.removeItem('persistentLogs'); } catch (e) { console.error('Failed to parse saved logs:', e); } } }; saveLogsToLocalStorage(); })();