You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dolphinscheduler.apache.org by ca...@apache.org on 2022/07/27 02:41:25 UTC
[dolphinscheduler] 07/09: [Bug] [API] If the single log length is long, it will causes the View Log page to hang (#10612)
This is an automated email from the ASF dual-hosted git repository.
caishunfeng pushed a commit to branch 3.0.0-prepare
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
commit 1b0f8c04d3e419320e30254393a8592ed52065a4
Author: zhuxt2015 <59...@qq.com>
AuthorDate: Tue Jul 26 10:14:45 2022 +0800
[Bug] [API] If the single log length is long, it will causes the View Log page to hang (#10612)
---
.../api/controller/LoggerController.java | 9 ++++---
.../api/service/LoggerService.java | 3 ++-
.../api/service/impl/LoggerServiceImpl.java | 10 ++++---
.../service/impl/ProcessInstanceServiceImpl.java | 5 ++--
.../dao/entity/ResponseTaskLog.java | 31 ++++++++++++++++++++++
.../server/log/LoggerRequestProcessor.java | 19 ++++++++++++-
.../src/views/projects/task/instance/index.tsx | 8 +++---
7 files changed, 69 insertions(+), 16 deletions(-)
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoggerController.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoggerController.java
index 88c715fab6..f24ee0273b 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoggerController.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/controller/LoggerController.java
@@ -25,6 +25,7 @@ import org.apache.dolphinscheduler.api.exceptions.ApiException;
import org.apache.dolphinscheduler.api.service.LoggerService;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants;
+import org.apache.dolphinscheduler.dao.entity.ResponseTaskLog;
import org.apache.dolphinscheduler.dao.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
@@ -77,10 +78,10 @@ public class LoggerController extends BaseController {
@ResponseStatus(HttpStatus.OK)
@ApiException(QUERY_TASK_INSTANCE_LOG_ERROR)
@AccessLogAnnotation(ignoreRequestArgs = "loginUser")
- public Result<String> queryLog(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
- @RequestParam(value = "taskInstanceId") int taskInstanceId,
- @RequestParam(value = "skipLineNum") int skipNum,
- @RequestParam(value = "limit") int limit) {
+ public Result<ResponseTaskLog> queryLog(@ApiIgnore @RequestAttribute(value = Constants.SESSION_USER) User loginUser,
+ @RequestParam(value = "taskInstanceId") int taskInstanceId,
+ @RequestParam(value = "skipLineNum") int skipNum,
+ @RequestParam(value = "limit") int limit) {
return loggerService.queryLog(taskInstanceId, skipNum, limit);
}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/LoggerService.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/LoggerService.java
index b252522c7c..f7ba946e4c 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/LoggerService.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/LoggerService.java
@@ -18,6 +18,7 @@
package org.apache.dolphinscheduler.api.service;
import org.apache.dolphinscheduler.api.utils.Result;
+import org.apache.dolphinscheduler.dao.entity.ResponseTaskLog;
import org.apache.dolphinscheduler.dao.entity.User;
import java.util.Map;
@@ -35,7 +36,7 @@ public interface LoggerService {
* @param limit limit
* @return log string data
*/
- Result<String> queryLog(int taskInstId, int skipLineNum, int limit);
+ Result<ResponseTaskLog> queryLog(int taskInstId, int skipLineNum, int limit);
/**
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/LoggerServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/LoggerServiceImpl.java
index cd5d18c463..48c044398d 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/LoggerServiceImpl.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/LoggerServiceImpl.java
@@ -24,6 +24,7 @@ import org.apache.dolphinscheduler.api.service.ProjectService;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.Constants;
import org.apache.dolphinscheduler.dao.entity.Project;
+import org.apache.dolphinscheduler.dao.entity.ResponseTaskLog;
import org.apache.dolphinscheduler.dao.entity.TaskDefinition;
import org.apache.dolphinscheduler.dao.entity.TaskInstance;
import org.apache.dolphinscheduler.dao.entity.User;
@@ -97,7 +98,7 @@ public class LoggerServiceImpl extends BaseServiceImpl implements LoggerService
*/
@Override
@SuppressWarnings("unchecked")
- public Result<String> queryLog(int taskInstId, int skipLineNum, int limit) {
+ public Result<ResponseTaskLog> queryLog(int taskInstId, int skipLineNum, int limit) {
TaskInstance taskInstance = processService.findTaskInstanceById(taskInstId);
@@ -107,9 +108,10 @@ public class LoggerServiceImpl extends BaseServiceImpl implements LoggerService
if (StringUtils.isBlank(taskInstance.getHost())) {
return Result.error(Status.TASK_INSTANCE_HOST_IS_NULL);
}
- Result<String> result = new Result<>(Status.SUCCESS.getCode(), Status.SUCCESS.getMsg());
- String log = queryLog(taskInstance,skipLineNum,limit);
- result.setData(log);
+ Result<ResponseTaskLog> result = new Result<>(Status.SUCCESS.getCode(), Status.SUCCESS.getMsg());
+ String log = queryLog(taskInstance, skipLineNum, limit);
+ int lineNum = log.split("\\r\\n").length;
+ result.setData(new ResponseTaskLog(lineNum, log));
return result;
}
diff --git a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java
index dd17255fdb..4c84ec2666 100644
--- a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java
+++ b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/service/impl/ProcessInstanceServiceImpl.java
@@ -50,6 +50,7 @@ import org.apache.dolphinscheduler.dao.entity.ProcessDefinition;
import org.apache.dolphinscheduler.dao.entity.ProcessInstance;
import org.apache.dolphinscheduler.dao.entity.ProcessTaskRelationLog;
import org.apache.dolphinscheduler.dao.entity.Project;
+import org.apache.dolphinscheduler.dao.entity.ResponseTaskLog;
import org.apache.dolphinscheduler.dao.entity.TaskDefinition;
import org.apache.dolphinscheduler.dao.entity.TaskDefinitionLog;
import org.apache.dolphinscheduler.dao.entity.TaskInstance;
@@ -344,10 +345,10 @@ public class ProcessInstanceServiceImpl extends BaseServiceImpl implements Proce
private void addDependResultForTaskList(List<TaskInstance> taskInstanceList) throws IOException {
for (TaskInstance taskInstance : taskInstanceList) {
if (TASK_TYPE_DEPENDENT.equalsIgnoreCase(taskInstance.getTaskType())) {
- Result<String> logResult = loggerService.queryLog(
+ Result<ResponseTaskLog> logResult = loggerService.queryLog(
taskInstance.getId(), Constants.LOG_QUERY_SKIP_LINE_NUMBER, Constants.LOG_QUERY_LIMIT);
if (logResult.getCode() == Status.SUCCESS.ordinal()) {
- String log = logResult.getData();
+ String log = logResult.getData().getMessage();
Map<String, DependResult> resultMap = parseLogForDependentResult(log);
taskInstance.setDependentResult(JSONUtils.toJsonString(resultMap));
}
diff --git a/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/ResponseTaskLog.java b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/ResponseTaskLog.java
new file mode 100644
index 0000000000..6876c060f8
--- /dev/null
+++ b/dolphinscheduler-dao/src/main/java/org/apache/dolphinscheduler/dao/entity/ResponseTaskLog.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.dolphinscheduler.dao.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * log of the logger service response
+ */
+@Data
+@AllArgsConstructor
+public class ResponseTaskLog {
+ private int lineNum;
+ private String message;
+}
diff --git a/dolphinscheduler-log-server/src/main/java/org/apache/dolphinscheduler/server/log/LoggerRequestProcessor.java b/dolphinscheduler-log-server/src/main/java/org/apache/dolphinscheduler/server/log/LoggerRequestProcessor.java
index 1ab4aa13fe..b5cae3562d 100644
--- a/dolphinscheduler-log-server/src/main/java/org/apache/dolphinscheduler/server/log/LoggerRequestProcessor.java
+++ b/dolphinscheduler-log-server/src/main/java/org/apache/dolphinscheduler/server/log/LoggerRequestProcessor.java
@@ -40,6 +40,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Collections;
@@ -113,8 +114,24 @@ public class LoggerRequestProcessor implements NettyRequestProcessor {
List<String> lines = readPartFileContent(rollViewLogPath,
rollViewLogRequest.getSkipLineNum(), rollViewLogRequest.getLimit());
StringBuilder builder = new StringBuilder();
+ final int MaxResponseLogSize = 65535;
+ int totalLogByteSize = 0;
for (String line : lines) {
- builder.append(line).append("\r\n");
+ //If a single line of log is exceed max response size, cut off the line
+ final int lineByteSize = line.getBytes(StandardCharsets.UTF_8).length;
+ if (lineByteSize >= MaxResponseLogSize) {
+ builder.append(line, 0, MaxResponseLogSize)
+ .append(" [this line's size ").append(lineByteSize).append(" bytes is exceed ")
+ .append(MaxResponseLogSize).append(" bytes, so only ")
+ .append(MaxResponseLogSize).append(" characters are reserved for performance reasons.]")
+ .append("\r\n");
+ } else {
+ builder.append(line).append("\r\n");
+ }
+ totalLogByteSize += lineByteSize;
+ if (totalLogByteSize >= MaxResponseLogSize) {
+ break;
+ }
}
RollViewLogResponseCommand rollViewLogRequestResponse = new RollViewLogResponseCommand(builder.toString());
channel.writeAndFlush(rollViewLogRequestResponse.convert2Command(command.getOpaque()));
diff --git a/dolphinscheduler-ui/src/views/projects/task/instance/index.tsx b/dolphinscheduler-ui/src/views/projects/task/instance/index.tsx
index 9faa15f3f9..16487a9295 100644
--- a/dolphinscheduler-ui/src/views/projects/task/instance/index.tsx
+++ b/dolphinscheduler-ui/src/views/projects/task/instance/index.tsx
@@ -76,11 +76,11 @@ const TaskInstance = defineComponent({
taskInstanceId: Number(row.id),
limit: variables.limit,
skipLineNum: variables.skipLineNum
- }).then((res: string) => {
- variables.logRef += res
- if (res) {
+ }).then((res: any) => {
+ if (res?.message) {
+ variables.logRef += res.message
variables.limit += 1000
- variables.skipLineNum += 1000
+ variables.skipLineNum += res.lineNum
getLogs(row)
} else {
variables.logLoadingRef = false