Files
vf_react/src/devtools/index.js

248 lines
8.5 KiB
JavaScript
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.

// src/debug/index.js
/**
* 调试工具统一入口
*
* 使用方法:
* 1. 开启调试: 在 .env.production 中设置 REACT_APP_ENABLE_DEBUG=true
* 2. 使用控制台命令: window.__DEBUG__.api.getLogs()
* 3. 后期移除: 删除整个 src/debug/ 目录 + 从 src/index.js 移除导入
*
* 全局 API:
* - window.__DEBUG__ - 调试 API 主对象
* - window.__DEBUG__.api - API 调试工具
* - window.__DEBUG__.socket - Socket 调试工具
* - window.__DEBUG__.help() - 显示帮助信息
* - window.__DEBUG__.exportAll() - 导出所有日志
*/
import { apiDebugger } from './apiDebugger';
import { socketDebugger } from './socketDebugger';
class DebugToolkit {
constructor() {
this.api = apiDebugger;
this.socket = socketDebugger;
}
/**
* 初始化所有调试工具
*/
init() {
console.log(
'%c╔════════════════════════════════════════════════════════════════╗',
'color: #FF9800; font-weight: bold;'
);
console.log(
'%c║ 🔧 调试模式已启用 (Debug Mode Enabled) ║',
'color: #FF9800; font-weight: bold;'
);
console.log(
'%c╚════════════════════════════════════════════════════════════════╝',
'color: #FF9800; font-weight: bold;'
);
console.log('');
// 初始化各个调试工具
this.api.init();
this.socket.init();
// 暴露到全局
window.__DEBUG__ = this;
// 打印帮助信息
this._printWelcome();
}
/**
* 打印欢迎信息
*/
_printWelcome() {
console.log('%c📚 调试工具使用指南:', 'color: #2196F3; font-weight: bold; font-size: 14px;');
console.log('');
console.log('%c1⃣ API 调试:', 'color: #2196F3; font-weight: bold;');
console.log(' __DEBUG__.api.getLogs() - 获取所有 API 日志');
console.log(' __DEBUG__.api.getRecentErrors() - 获取最近的错误');
console.log(' __DEBUG__.api.exportLogs() - 导出 API 日志');
console.log(' __DEBUG__.api.testRequest(method, endpoint, data) - 测试 API 请求');
console.log('');
console.log('%c2⃣ Socket 调试:', 'color: #00BCD4; font-weight: bold;');
console.log(' __DEBUG__.socket.getLogs() - 获取所有 Socket 日志');
console.log(' __DEBUG__.socket.getStatus() - 获取连接状态');
console.log(' __DEBUG__.socket.reconnect() - 手动重连');
console.log(' __DEBUG__.socket.exportLogs() - 导出 Socket 日志');
console.log('');
console.log('%c3⃣ 通用命令:', 'color: #4CAF50; font-weight: bold;');
console.log(' __DEBUG__.help() - 显示帮助信息');
console.log(' __DEBUG__.exportAll() - 导出所有日志');
console.log(' __DEBUG__.printStats() - 打印所有统计信息');
console.log(' __DEBUG__.clearAll() - 清空所有日志');
console.log('');
console.log(
'%c⚠ 警告: 调试模式会记录所有 API 请求和响应,请勿在生产环境长期开启!',
'color: #F44336; font-weight: bold;'
);
console.log('');
}
/**
* 显示帮助信息
*/
help() {
this._printWelcome();
}
/**
* 导出所有日志
*/
exportAll() {
console.log('[Debug Toolkit] Exporting all logs...');
const allLogs = {
timestamp: new Date().toISOString(),
api: this.api.getLogs(),
socket: this.socket.getLogs(),
};
const blob = new Blob([JSON.stringify(allLogs, null, 2)], {
type: 'application/json',
});
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = `debug-all-logs-${Date.now()}.json`;
a.click();
URL.revokeObjectURL(url);
console.log('[Debug Toolkit] ✅ All logs exported');
}
/**
* 打印所有统计信息
*/
printStats() {
console.log('\n%c=== 📊 调试统计信息 ===', 'color: #FF9800; font-weight: bold; font-size: 16px;');
console.log('\n%c[API 统计]', 'color: #2196F3; font-weight: bold;');
const apiStats = this.api.printStats();
console.log('\n%c[Socket 统计]', 'color: #00BCD4; font-weight: bold;');
const socketStats = this.socket.printStats();
return {
api: apiStats,
socket: socketStats,
};
}
/**
* 清空所有日志
*/
clearAll() {
console.log('[Debug Toolkit] Clearing all logs...');
this.api.clearLogs();
this.socket.clearLogs();
console.log('[Debug Toolkit] ✅ All logs cleared');
}
/**
* 快速诊断(检查所有系统状态)
*/
diagnose() {
console.log('\n%c=== 🔍 系统诊断 ===', 'color: #FF9800; font-weight: bold; font-size: 16px;');
// 1. Socket 状态
console.log('\n%c[1/2] Socket 状态', 'color: #00BCD4; font-weight: bold;');
const socketStatus = this.socket.getStatus();
// 2. API 错误
console.log('\n%c[2/2] 最近的 API 错误', 'color: #F44336; font-weight: bold;');
const recentErrors = this.api.getRecentErrors(5);
if (recentErrors.length > 0) {
console.table(
recentErrors.map((err) => ({
时间: err.timestamp,
方法: err.method,
URL: err.url,
状态码: err.status,
错误信息: err.message,
}))
);
} else {
console.log('✅ 没有 API 错误');
}
// 3. 汇总报告
const report = {
timestamp: new Date().toISOString(),
socket: socketStatus,
apiErrors: recentErrors.length,
};
console.log('\n%c=== 诊断报告 ===', 'color: #4CAF50; font-weight: bold;');
console.table(report);
return report;
}
/**
* 性能监控
*/
performance() {
console.log('\n%c=== ⚡ 性能监控 ===', 'color: #FF9800; font-weight: bold; font-size: 16px;');
// 计算 API 平均响应时间
const apiLogs = this.api.getLogs();
const responseTimes = [];
for (let i = 0; i < apiLogs.length - 1; i++) {
const log = apiLogs[i];
const prevLog = apiLogs[i + 1];
if (
log.type === 'response' &&
prevLog.type === 'request' &&
log.url === prevLog.url
) {
const responseTime =
new Date(log.timestamp).getTime() - new Date(prevLog.timestamp).getTime();
responseTimes.push({
url: log.url,
method: log.method,
time: responseTime,
});
}
}
if (responseTimes.length > 0) {
const avgTime =
responseTimes.reduce((sum, item) => sum + item.time, 0) / responseTimes.length;
const maxTime = Math.max(...responseTimes.map((item) => item.time));
const minTime = Math.min(...responseTimes.map((item) => item.time));
console.log('API 响应时间统计:');
console.table({
平均响应时间: `${avgTime.toFixed(2)}ms`,
最快响应: `${minTime}ms`,
最慢响应: `${maxTime}ms`,
请求总数: responseTimes.length,
});
// 显示最慢的 5 个请求
console.log('\n最慢的 5 个请求:');
const slowest = responseTimes.sort((a, b) => b.time - a.time).slice(0, 5);
console.table(
slowest.map((item) => ({
方法: item.method,
URL: item.url,
响应时间: `${item.time}ms`,
}))
);
} else {
console.log('暂无性能数据');
}
}
}
// 导出单例
export const debugToolkit = new DebugToolkit();
export default debugToolkit;