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 1b3789c4..7bebce43 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 @@ -121,14 +121,18 @@ public class K8sDeploymentApiController extends BaseController getPodLogs( @Parameter(description = "Deployment ID", required = true) @PathVariable Long deploymentId, @Parameter(description = "Pod名称", required = true) @PathVariable String podName, @Parameter(description = "容器名称(可选,默认第一个容器)") @RequestParam(required = false) String container, - @Parameter(description = "返回最后N行日志(可选)") @RequestParam(required = false) Integer tail, - @Parameter(description = "返回最近N秒的日志(可选)") @RequestParam(required = false) Integer sinceSeconds + @Parameter(description = "返回最后N行日志(可选,默认500行,最大10000行)") @RequestParam(required = false) Integer tail, + @Parameter(description = "返回最近N秒的日志(可选,默认3600秒即1小时,最大86400秒即24小时)") @RequestParam(required = false) Integer sinceSeconds ) { return Response.success(k8sPodService.getPodLogs(deploymentId, podName, container, tail, sinceSeconds)); } diff --git a/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/K8sServiceIntegrationImpl.java b/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/K8sServiceIntegrationImpl.java index 86f130e2..4494a8e9 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/K8sServiceIntegrationImpl.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/deploy/integration/impl/K8sServiceIntegrationImpl.java @@ -107,7 +107,7 @@ public class K8sServiceIntegrationImpl extends BaseExternalSystemIntegration imp // 创建K8S ApiClient并测试连接(直接使用config作为kubeconfig) ApiClient client = Config.fromConfig(new StringReader(config)); client.setConnectTimeout(15000); // 15秒连接超时 - client.setReadTimeout(30000); // 30秒读取超时 + client.setReadTimeout(120000); // 120秒读取超时(优化日志查询等耗时操作) VersionApi versionApi = new VersionApi(client); VersionInfo version = versionApi.getCode(); @@ -601,13 +601,20 @@ public class K8sServiceIntegrationImpl extends BaseExternalSystemIntegration imp @Override public String getPodLogs(ExternalSystem externalSystem, String namespace, String podName, String container, Integer tail, Integer sinceSeconds, Boolean follow) { - log.info("查询K8S Pod日志,集群: {}, 命名空间: {}, Pod: {}, 容器: {}", - externalSystem.getName(), namespace, podName, container); + // 智能默认参数:优化性能,避免超时 + Integer effectiveTail = tail != null ? tail : 500; // 默认最后500行 + Integer effectiveSinceSeconds = sinceSeconds != null ? sinceSeconds : 3600; // 默认最近1小时 + + log.info("查询K8S Pod日志,集群: {}, 命名空间: {}, Pod: {}, 容器: {}, tail: {}, sinceSeconds: {}", + externalSystem.getName(), namespace, podName, container, effectiveTail, effectiveSinceSeconds); try { K8sApiClientCache cache = getApiClientCache(externalSystem); CoreV1Api api = new CoreV1Api(cache.apiClient); + // 日志大小限制:10MB(防止OOM) + Integer limitBytes = 10 * 1024 * 1024; + // 查询Pod日志 String logs = api.readNamespacedPodLog( podName, // Pod名称 @@ -615,15 +622,16 @@ public class K8sServiceIntegrationImpl extends BaseExternalSystemIntegration imp container, // 容器名称(可选) follow != null && follow, // 是否持续输出 null, // insecureSkipTLSVerifyBackend - null, // limitBytes + limitBytes, // limitBytes(10MB限制) "false", // pretty false, // previous(是否查询上一个容器的日志) - sinceSeconds, // sinceSeconds - tail, // tail + effectiveSinceSeconds, // sinceSeconds(使用智能默认值) + effectiveTail, // tail(使用智能默认值) false // timestamps ); - log.info("查询Pod日志成功,日志长度: {}", logs != null ? logs.length() : 0); + int logLength = logs != null ? logs.length() : 0; + log.info("查询Pod日志成功,日志长度: {} bytes, 行数约: {}", logLength, logLength > 0 ? logs.split("\n").length : 0); return logs != null ? logs : ""; } catch (ApiException e) { @@ -875,7 +883,7 @@ public class K8sServiceIntegrationImpl extends BaseExternalSystemIntegration imp // 直接使用config作为kubeconfig内容 ApiClient client = Config.fromConfig(new StringReader(config)); client.setConnectTimeout(15000); // 15秒连接超时 - client.setReadTimeout(30000); // 30秒读取超时 + client.setReadTimeout(120000); // 120秒读取超时(优化日志查询等耗时操作) return client; } } 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 c63ea45c..a3cef767 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 @@ -135,6 +135,14 @@ public class K8sPodServiceImpl implements IK8sPodService { log.info("查询Pod日志,deploymentId: {}, podName: {}, container: {}, tail: {}, sinceSeconds: {}", deploymentId, podName, container, tail, sinceSeconds); + // 参数校验 + if (tail != null && (tail < 1 || tail > 10000)) { + throw new BusinessException(ResponseCode.INVALID_PARAM, new Object[]{"tail参数范围:1-10000行"}); + } + if (sinceSeconds != null && (sinceSeconds < 1 || sinceSeconds > 86400)) { + throw new BusinessException(ResponseCode.INVALID_PARAM, new Object[]{"sinceSeconds参数范围:1-86400秒(24小时)"}); + } + // 1. 查询K8sDeployment K8sDeployment deployment = k8sDeploymentRepository.findById(deploymentId) .orElseThrow(() -> new BusinessException(ResponseCode.K8S_RESOURCE_NOT_FOUND));