完善查询历史记录
This commit is contained in:
156
static/js/app.js
156
static/js/app.js
@@ -2758,6 +2758,21 @@ async function loadHistoryResults(historyId) {
|
||||
// 显示结果
|
||||
displayResults(result.data);
|
||||
|
||||
// 加载相关的查询日志
|
||||
try {
|
||||
await loadQueryLogsByHistory(historyId);
|
||||
// 自动切换到查询日志选项卡以显示关联信息
|
||||
const logsTab = document.getElementById('logs-tab');
|
||||
if (logsTab) {
|
||||
// 添加一个小延迟确保结果已经显示
|
||||
setTimeout(() => {
|
||||
logsTab.click();
|
||||
}, 500);
|
||||
}
|
||||
} catch (logError) {
|
||||
console.warn('加载历史记录相关查询日志失败:', logError);
|
||||
}
|
||||
|
||||
// 关闭历史记录modal
|
||||
const modal = bootstrap.Modal.getInstance(document.getElementById('queryHistoryModal'));
|
||||
if (modal) {
|
||||
@@ -2766,7 +2781,7 @@ async function loadHistoryResults(historyId) {
|
||||
|
||||
const queryTypeDesc = (result.data.history_info && result.data.history_info.query_type === 'sharding') ? '分表查询' : '单表查询';
|
||||
const historyName = (result.data.history_info && result.data.history_info.name) || '未知';
|
||||
showAlert('success', `${queryTypeDesc}历史记录结果 "${historyName}" 加载成功`);
|
||||
showAlert('success', `${queryTypeDesc}历史记录结果 "${historyName}" 加载成功,查询日志已关联显示`);
|
||||
} else {
|
||||
showAlert('danger', result.error || '加载历史记录结果失败');
|
||||
}
|
||||
@@ -3441,6 +3456,145 @@ async function cleanupOldLogs() {
|
||||
}
|
||||
}
|
||||
|
||||
// 根据历史记录ID获取相关查询日志
|
||||
async function loadQueryLogsByHistory(historyId) {
|
||||
try {
|
||||
const response = await fetch(`/api/query-logs/history/${historyId}`);
|
||||
const result = await response.json();
|
||||
|
||||
if (result.success && result.data) {
|
||||
// 显示关联的查询日志
|
||||
displayHistoryRelatedLogs(result.data, historyId);
|
||||
return result.data;
|
||||
} else {
|
||||
console.warn('获取历史记录相关日志失败:', result.error);
|
||||
return [];
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取历史记录相关查询日志失败:', error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// 显示历史记录相关的查询日志
|
||||
function displayHistoryRelatedLogs(groupedLogs, historyId) {
|
||||
const container = document.getElementById('query-logs');
|
||||
|
||||
if (!groupedLogs || groupedLogs.length === 0) {
|
||||
container.innerHTML = `
|
||||
<div class="alert alert-info">
|
||||
<i class="fas fa-info-circle"></i>
|
||||
历史记录 ID ${historyId} 没有关联的查询日志
|
||||
</div>
|
||||
`;
|
||||
return;
|
||||
}
|
||||
|
||||
let html = `
|
||||
<div class="alert alert-primary">
|
||||
<i class="fas fa-link"></i>
|
||||
显示历史记录 ID ${historyId} 的相关查询日志 (共 ${groupedLogs.length} 个批次)
|
||||
</div>
|
||||
`;
|
||||
|
||||
// 使用与refreshQueryLogs相同的显示逻辑
|
||||
groupedLogs.forEach((batchData, index) => {
|
||||
const [batchId, logs] = batchData;
|
||||
const isExpanded = true; // 历史记录日志默认展开所有批次
|
||||
const collapseId = `history-batch-${batchId}`;
|
||||
|
||||
// 统计批次信息
|
||||
const logCounts = {
|
||||
INFO: logs.filter(log => log.level === 'INFO').length,
|
||||
WARNING: logs.filter(log => log.level === 'WARNING').length,
|
||||
ERROR: logs.filter(log => log.level === 'ERROR').length
|
||||
};
|
||||
|
||||
const totalLogs = logs.length;
|
||||
const firstLog = logs[0];
|
||||
const lastLog = logs[logs.length - 1];
|
||||
const duration = firstLog && lastLog ? calculateDuration(firstLog.timestamp, lastLog.timestamp) : '0秒';
|
||||
|
||||
// 确定批次类型和状态
|
||||
const hasErrors = logCounts.ERROR > 0;
|
||||
const hasWarnings = logCounts.WARNING > 0;
|
||||
const batchStatus = hasErrors ? 'danger' : hasWarnings ? 'warning' : 'success';
|
||||
const batchIcon = hasErrors ? 'fas fa-times-circle' : hasWarnings ? 'fas fa-exclamation-triangle' : 'fas fa-check-circle';
|
||||
|
||||
// 提取查询类型
|
||||
const batchTypeMatch = firstLog?.message.match(/开始(\w+)查询批次/);
|
||||
const batchType = batchTypeMatch ? batchTypeMatch[1] : '未知';
|
||||
|
||||
html += `
|
||||
<div class="card mb-3 border-${batchStatus}">
|
||||
<div class="card-header bg-${batchStatus} bg-opacity-10" data-bs-toggle="collapse" data-bs-target="#${collapseId}" style="cursor: pointer;">
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<div class="d-flex align-items-center">
|
||||
<i class="${batchIcon} text-${batchStatus} me-2"></i>
|
||||
<strong>${batchType}查询批次 ${batchId}</strong>
|
||||
<span class="badge bg-primary ms-2">${totalLogs}条日志</span>
|
||||
<span class="badge bg-secondary ms-1">历史记录</span>
|
||||
</div>
|
||||
<div class="d-flex align-items-center">
|
||||
<small class="text-muted me-3">
|
||||
<i class="fas fa-clock"></i> ${duration}
|
||||
</small>
|
||||
<div>
|
||||
${logCounts.INFO > 0 ? `<span class="badge bg-info me-1">${logCounts.INFO} INFO</span>` : ''}
|
||||
${logCounts.WARNING > 0 ? `<span class="badge bg-warning me-1">${logCounts.WARNING} WARN</span>` : ''}
|
||||
${logCounts.ERROR > 0 ? `<span class="badge bg-danger me-1">${logCounts.ERROR} ERROR</span>` : ''}
|
||||
</div>
|
||||
<i class="fas fa-chevron-down ms-2"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="collapse ${isExpanded ? 'show' : ''}" id="${collapseId}">
|
||||
<div class="card-body p-0">
|
||||
<div class="log-entries" style="max-height: 400px; overflow-y: auto;">
|
||||
`;
|
||||
|
||||
// 显示该批次的日志条目
|
||||
logs.forEach(log => {
|
||||
const shouldShow = true; // 历史记录日志显示所有级别
|
||||
|
||||
if (shouldShow) {
|
||||
const levelClass = log.level === 'ERROR' ? 'danger' :
|
||||
log.level === 'WARNING' ? 'warning' : 'info';
|
||||
const levelIcon = log.level === 'ERROR' ? 'fas fa-times-circle' :
|
||||
log.level === 'WARNING' ? 'fas fa-exclamation-triangle' : 'fas fa-info-circle';
|
||||
|
||||
// 简化时间戳显示
|
||||
const timeOnly = log.timestamp.split(' ')[1] || log.timestamp;
|
||||
|
||||
html += `
|
||||
<div class="log-entry p-2 border-bottom">
|
||||
<div class="d-flex align-items-start">
|
||||
<span class="badge bg-${levelClass} me-2">
|
||||
<i class="${levelIcon}"></i> ${log.level}
|
||||
</span>
|
||||
<small class="text-muted me-2 flex-shrink-0" style="min-width: 80px;">
|
||||
${timeOnly}
|
||||
</small>
|
||||
<div class="log-message flex-grow-1">
|
||||
${formatLogMessage(log.message)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
});
|
||||
|
||||
html += `
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
|
||||
container.innerHTML = html;
|
||||
}
|
||||
|
||||
// 在查询执行后自动刷新日志
|
||||
function autoRefreshLogsAfterQuery() {
|
||||
// 延迟一下确保后端日志已经记录
|
||||
|
Reference in New Issue
Block a user