From e54d6834c3d564f6bbe19812ad53304aa43c8d0c Mon Sep 17 00:00:00 2001 From: dengqichen Date: Sun, 14 Dec 2025 01:00:32 +0800 Subject: [PATCH] =?UTF-8?q?1.30=20k8s=20pods=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/K8sPodServiceImpl.java | 89 +++++++++---------- 1 file changed, 40 insertions(+), 49 deletions(-) diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/K8sPodServiceImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/K8sPodServiceImpl.java index 82c19aee..69434d3a 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/K8sPodServiceImpl.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/service/impl/K8sPodServiceImpl.java @@ -152,7 +152,7 @@ public class K8sPodServiceImpl implements IK8sPodService { // 4. 调用K8s API获取原始日志(获取足够多的日志以支持切片) // 使用较大的tail值和缓冲区确保能够覆盖请求的范围 - Integer effectiveTail = Math.max(5000, Math.abs(offsetFrom) + Math.abs(offsetTo) + 1000); + Integer effectiveTail = Math.max(10000, Math.abs(offsetFrom) + Math.abs(offsetTo) + 2000); String rawLogs = k8sServiceIntegration.getPodLogs( externalSystem, namespace.getNamespaceName(), @@ -178,60 +178,51 @@ public class K8sPodServiceImpl implements IK8sPodService { com.qqchen.deploy.backend.deploy.utils.K8sLogParser.LogSliceResult result = com.qqchen.deploy.backend.deploy.utils.K8sLogParser.selectLogs(logLines, selection); - // 8. 验证引用点是否有效(仅对非newest/oldest模式) - if (!result.getLogs().isEmpty() && - !referenceTimestamp.equals("newest") && - !referenceTimestamp.equals("oldest")) { + // 8. 如果返回空日志,直接返回空响应(引用点可能已丢失) + if (result.getLogs().isEmpty()) { + log.warn("引用点定位失败,返回空日志。referenceTimestamp: {}", referenceTimestamp); - // 获取返回日志的第一行和最后一行时间戳 - String firstTimestamp = result.getLogs().get(0).getTimestamp(); - String lastTimestamp = result.getLogs().get(result.getLogs().size() - 1).getTimestamp(); - - log.debug("引用点: {}, 返回日志范围: {} 到 {}", referenceTimestamp, firstTimestamp, lastTimestamp); - - // 验证:如果是向后查询(offsetFrom > 0),返回的日志应该在引用点之后 - if (offsetFrom > 0) { - // 检查第一行时间戳是否在引用点之后 - if (firstTimestamp.compareTo(referenceTimestamp) <= 0) { - log.warn("引用点验证失败:返回的日志在引用点之前或等于引用点。referenceTimestamp: {}, firstTimestamp: {}, 回退到newest模式", - referenceTimestamp, firstTimestamp); - - // 回退到newest模式 - selection = new com.qqchen.deploy.backend.deploy.dto.K8sLogSelection("newest", -100, 0); - result = com.qqchen.deploy.backend.deploy.utils.K8sLogParser.selectLogs(logLines, selection); - } - } - // 验证:如果是向前查询(offsetTo <= 0),返回的日志应该在引用点之前 - else if (offsetTo <= 0) { - // 检查最后一行时间戳是否在引用点之前 - if (lastTimestamp.compareTo(referenceTimestamp) >= 0) { - log.warn("引用点验证失败:返回的日志在引用点之后或等于引用点。referenceTimestamp: {}, lastTimestamp: {}, 回退到newest模式", - referenceTimestamp, lastTimestamp); - - // 回退到newest模式 - selection = new com.qqchen.deploy.backend.deploy.dto.K8sLogSelection("newest", -100, 0); - result = com.qqchen.deploy.backend.deploy.utils.K8sLogParser.selectLogs(logLines, selection); - } - } - } - - // 9. 如果返回空日志且不是newest/oldest模式,回退到newest模式 - if (result.getLogs().isEmpty() && - !referenceTimestamp.equals("newest") && - !referenceTimestamp.equals("oldest")) { - log.warn("引用点定位失败,返回空日志。referenceTimestamp: {}, 回退到newest模式", referenceTimestamp); - - // 回退到newest模式 - selection = new com.qqchen.deploy.backend.deploy.dto.K8sLogSelection("newest", -100, 0); - result = com.qqchen.deploy.backend.deploy.utils.K8sLogParser.selectLogs(logLines, selection); + return new com.qqchen.deploy.backend.deploy.dto.K8sPodLogsResponse( + podName, + container != null ? container : "default", + null, + null, + result.getLogs(), + result.isTruncated() + ); } - // 10. 构建响应 + // 9. 使用中点策略计算新的引用点(Kubernetes Dashboard策略) + // 中点引用点不容易因为日志增删而丢失 + int midIndex = result.getLogs().size() / 2; + String midTimestamp = result.getLogs().get(midIndex).getTimestamp(); + + log.debug("返回 {} 行日志,中点索引: {}, 中点时间戳: {}", + result.getLogs().size(), midIndex, midTimestamp); + + // 10. 构建referenceForPrevious(向前翻页) + com.qqchen.deploy.backend.deploy.dto.K8sLogSelection referenceForPrevious = + new com.qqchen.deploy.backend.deploy.dto.K8sLogSelection( + midTimestamp, + -midIndex - 100, // 从中点向前100行 + -midIndex + ); + + // 11. 构建referenceForNext(向后翻页) + int remainingAfterMid = result.getLogs().size() - midIndex; + com.qqchen.deploy.backend.deploy.dto.K8sLogSelection referenceForNext = + new com.qqchen.deploy.backend.deploy.dto.K8sLogSelection( + midTimestamp, + remainingAfterMid, // 从中点向后 + remainingAfterMid + 100 // 向后100行 + ); + + // 12. 构建响应 return new com.qqchen.deploy.backend.deploy.dto.K8sPodLogsResponse( podName, container != null ? container : "default", - result.getReferenceForPrevious(), - result.getReferenceForNext(), + referenceForPrevious, + referenceForNext, result.getLogs(), result.isTruncated() );