From dfbf8e4f0a2d44a773bd61d3cec7875db43462ad Mon Sep 17 00:00:00 2001 From: dengqichen Date: Sun, 14 Dec 2025 13:38:50 +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 --- .../api/K8sDeploymentApiController.java | 28 ++------ .../deploy/service/IK8sPodService.java | 8 +-- .../service/impl/K8sPodServiceImpl.java | 69 ++++++++++--------- 3 files changed, 48 insertions(+), 57 deletions(-) diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/K8sDeploymentApiController.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/K8sDeploymentApiController.java index a47f699d..3e6a5721 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/K8sDeploymentApiController.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/api/K8sDeploymentApiController.java @@ -123,24 +123,10 @@ public class K8sDeploymentApiController extends BaseController getPodLogs( @@ -148,10 +134,10 @@ public class K8sDeploymentApiController extends BaseController new BusinessException(ResponseCode.EXTERNAL_SYSTEM_NOT_FOUND)); - // 4. 调用K8s API获取原始日志(获取足够多的日志以支持切片) - // 使用较大的tail值和缓冲区确保能够覆盖请求的范围 - Integer effectiveTail = Math.max(10000, Math.abs(offsetFrom) + Math.abs(offsetTo) + 2000); + // 4. 计算有效的日志行数(默认100行) + int effectiveLogCount = (logCount != null && logCount > 0) ? logCount : 100; + + // 5. 根据direction计算offsetFrom和offsetTo + int offsetFrom; + int offsetTo; + if ("prev".equalsIgnoreCase(direction)) { + // 向上加载历史日志 + offsetFrom = -effectiveLogCount; + offsetTo = 0; + } else { + // 向下加载新日志(next或默认) + offsetFrom = 0; + offsetTo = effectiveLogCount; + } + + // 6. 调用K8s API获取原始日志 + Integer effectiveTail = Math.max(10000, effectiveLogCount + 2000); String rawLogs = k8sServiceIntegration.getPodLogs( externalSystem, namespace.getNamespaceName(), podName, container, effectiveTail, - null, // 不使用sinceSeconds,获取更多历史日志 + null, false ); - // 5. 解析日志 + // 7. 解析日志 List logLines = com.qqchen.deploy.backend.deploy.utils.K8sLogParser.parseLogLines(rawLogs); log.debug("解析到 {} 行日志", logLines.size()); - // 6. 创建选择器 + // 8. 创建选择器 com.qqchen.deploy.backend.deploy.dto.K8sLogSelection selection = new com.qqchen.deploy.backend.deploy.dto.K8sLogSelection( referenceTimestamp, offsetFrom, offsetTo); - // 7. 切片日志 + // 9. 切片日志 com.qqchen.deploy.backend.deploy.utils.K8sLogParser.LogSliceResult result = com.qqchen.deploy.backend.deploy.utils.K8sLogParser.selectLogs(logLines, selection); - // 8. 如果返回空日志,直接返回空响应(引用点可能已丢失) + // 10. 如果返回空日志,直接返回空响应 if (result.getLogs().isEmpty()) { - log.warn("引用点定位失败,返回空日志。referenceTimestamp: {}", referenceTimestamp); + log.warn("引用点定位失败或无更多日志,referenceTimestamp: {}, direction: {}", referenceTimestamp, direction); return new com.qqchen.deploy.backend.deploy.dto.K8sPodLogsResponse( podName, @@ -192,32 +207,22 @@ public class K8sPodServiceImpl implements IK8sPodService { ); } - // 9. 使用中点策略计算新的引用点(Kubernetes Dashboard策略) - // 中点引用点不容易因为日志增删而丢失 - int midIndex = result.getLogs().size() / 2; - String midTimestamp = result.getLogs().get(midIndex).getTimestamp(); + // 11. 计算新的引用点(使用返回结果的第一行和最后一行) + String firstTimestamp = result.getLogs().get(0).getTimestamp(); + String lastTimestamp = result.getLogs().get(result.getLogs().size() - 1).getTimestamp(); - log.debug("返回 {} 行日志,中点索引: {}, 中点时间戳: {}", - result.getLogs().size(), midIndex, midTimestamp); + log.debug("返回 {} 行日志,第一行时间戳: {}, 最后一行时间戳: {}", + result.getLogs().size(), firstTimestamp, lastTimestamp); - // 10. 构建referenceForPrevious(向前翻页) + // 12. 构建referenceForPrevious(用于向上加载,使用第一行时间戳) com.qqchen.deploy.backend.deploy.dto.K8sLogSelection referenceForPrevious = - new com.qqchen.deploy.backend.deploy.dto.K8sLogSelection( - midTimestamp, - -midIndex - 100, // 从中点向前100行 - -midIndex - ); + new com.qqchen.deploy.backend.deploy.dto.K8sLogSelection(firstTimestamp, -effectiveLogCount, 0); - // 11. 构建referenceForNext(向后翻页) - int remainingAfterMid = result.getLogs().size() - midIndex; + // 13. 构建referenceForNext(用于向下加载,使用最后一行时间戳) com.qqchen.deploy.backend.deploy.dto.K8sLogSelection referenceForNext = - new com.qqchen.deploy.backend.deploy.dto.K8sLogSelection( - midTimestamp, - remainingAfterMid, // 从中点向后 - remainingAfterMid + 100 // 向后100行 - ); + new com.qqchen.deploy.backend.deploy.dto.K8sLogSelection(lastTimestamp, 1, effectiveLogCount + 1); - // 12. 构建响应 + // 14. 构建响应 return new com.qqchen.deploy.backend.deploy.dto.K8sPodLogsResponse( podName, container != null ? container : "default",