This is an automated email from the ASF dual-hosted git repository.
zihaoxiang pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/dolphinscheduler.git
The following commit(s) were added to refs/heads/dev by this push:
new 7a8d910e70 [DSIP-40][APIService] Add LogClient to fetch log (#17165)
7a8d910e70 is described below
commit 7a8d910e705d09c225536b56787f549f5131c88d
Author: [email protected] <[email protected]>
AuthorDate: Tue Jun 10 11:24:40 2025 +0800
[DSIP-40][APIService] Add LogClient to fetch log (#17165)
---
.../api/executor/logging/LocalLogClient.java | 88 ++++++++++++
.../api/executor/logging/LogClientDelegate.java | 112 +++++++++++++++
.../api/executor/logging/RemoteLogClient.java | 54 ++++++++
.../api/service/impl/LoggerServiceImpl.java | 31 +----
.../api/executor/logging/LocalLogClientTest.java | 137 +++++++++++++++++++
.../executor/logging/LogClientDelegateTest.java | 152 +++++++++++++++++++++
.../api/service/LoggerServiceTest.java | 82 +++--------
.../common/service/impl/LogServiceImpl.java | 85 ++++++++++++
...ownloadResponse.java => LogResponseStatus.java} | 22 +--
.../TaskInstanceLogFileDownloadResponse.java | 4 +
.../TaskInstanceLogPageQueryResponse.java | 4 +
.../server/master/rpc/MasterLogServiceImpl.java | 35 +----
.../server/worker/rpc/WorkerLogServiceImpl.java | 34 +----
13 files changed, 675 insertions(+), 165 deletions(-)
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/executor/logging/LocalLogClient.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/executor/logging/LocalLogClient.java
new file mode 100644
index 0000000000..ebe8b2e9fe
--- /dev/null
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/executor/logging/LocalLogClient.java
@@ -0,0 +1,88 @@
+/*
+ * 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.api.executor.logging;
+
+import org.apache.dolphinscheduler.dao.entity.TaskInstance;
+import org.apache.dolphinscheduler.extract.base.client.Clients;
+import org.apache.dolphinscheduler.extract.common.ILogService;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadRequest;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadResponse;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryRequest;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryResponse;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.stereotype.Component;
+
+@Component
+@Slf4j
+public class LocalLogClient {
+
+ /**
+ * Download the complete log of a task instance.
+ * This method is used to retrieve all log information from the start to
the end of a task instance,
+ * suitable for scenarios where a complete log record is required.
+ *
+ * @param taskInstance The task instance object, containing information
needed to retrieve the log.
+ * @return The complete log file download response of the task instance,
including log content and metadata.
+ */
+ public TaskInstanceLogFileDownloadResponse getWholeLog(TaskInstance
taskInstance) {
+ return getLocalWholeLog(taskInstance);
+ }
+
+ /**
+ * Query a portion of the log of a task instance.
+ * This method is used to query log information of a task instance in a
paginated manner,
+ * suitable for scenarios where the log content is large and needs to be
retrieved in batches.
+ *
+ * @param taskInstance The task instance object, containing information
needed to retrieve the log.
+ * @param skipLineNum The number of lines to skip, indicating from which
line to start reading the log.
+ * @param limit The maximum number of lines to read, indicating the
maximum number of lines to retrieve in this query.
+ * @return The partial log query response, including log content within
the specified range and metadata.
+ */
+ public TaskInstanceLogPageQueryResponse getPartLog(TaskInstance
taskInstance, int skipLineNum, int limit) {
+ return getLocalPartLog(taskInstance, skipLineNum, limit);
+ }
+
+ private TaskInstanceLogFileDownloadResponse getLocalWholeLog(TaskInstance
taskInstance) {
+ TaskInstanceLogFileDownloadRequest request = new
TaskInstanceLogFileDownloadRequest(
+ taskInstance.getId(),
+ taskInstance.getLogPath());
+ return
getProxyLogService(taskInstance).getTaskInstanceWholeLogFileBytes(request);
+ }
+
+ private TaskInstanceLogPageQueryResponse getLocalPartLog(TaskInstance
taskInstance, int skipLineNum,
+ int limit) {
+ TaskInstanceLogPageQueryRequest request =
TaskInstanceLogPageQueryRequest
+ .builder()
+ .taskInstanceId(taskInstance.getId())
+ .taskInstanceLogAbsolutePath(taskInstance.getLogPath())
+ .skipLineNum(skipLineNum)
+ .limit(limit)
+ .build();
+ return
getProxyLogService(taskInstance).pageQueryTaskInstanceLog(request);
+ }
+
+ private ILogService getProxyLogService(TaskInstance taskInstance) {
+ ILogService logService = Clients
+ .withService(ILogService.class)
+ .withHost(taskInstance.getHost());
+ log.debug("Created log service for host: {}", taskInstance.getHost());
+ return logService;
+ }
+}
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/executor/logging/LogClientDelegate.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/executor/logging/LogClientDelegate.java
new file mode 100644
index 0000000000..ac5b6ecb2b
--- /dev/null
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/executor/logging/LogClientDelegate.java
@@ -0,0 +1,112 @@
+/*
+ * 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.api.executor.logging;
+
+import org.apache.dolphinscheduler.dao.entity.TaskInstance;
+import
org.apache.dolphinscheduler.extract.common.transportor.LogResponseStatus;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadResponse;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryResponse;
+import org.apache.dolphinscheduler.plugin.task.api.utils.TaskTypeUtils;
+import org.apache.dolphinscheduler.registry.api.RegistryClient;
+import org.apache.dolphinscheduler.registry.api.enums.RegistryNodeType;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+@Slf4j
+@Component
+public class LogClientDelegate {
+
+ @Autowired
+ private LocalLogClient localLogClient;
+ @Autowired
+ private RemoteLogClient remoteLogClient;
+ @Autowired
+ private RegistryClient registryClient;
+
+ /**
+ * Retrieves a portion of the log string for a given task instance.
+ * This method first attempts to fetch the log from local storage; if
unsuccessful, it tries to obtain the log from remote storage.
+ *
+ * @param taskInstance The task instance object, containing information
needed for log retrieval.
+ * @param skipLineNum The number of log lines to skip from the beginning.
+ * @param limit The maximum number of log lines to retrieve.
+ * @return A string containing the specified portion of the log.
+ */
+ public String getPartLogString(TaskInstance taskInstance, int skipLineNum,
int limit) {
+ checkArgs(taskInstance);
+ if (checkNodeExists(taskInstance)) {
+ TaskInstanceLogPageQueryResponse response =
localLogClient.getPartLog(taskInstance, skipLineNum, limit);
+ if (response.getCode() == LogResponseStatus.SUCCESS) {
+ return response.getLogContent();
+ } else {
+ log.warn("get part log string is not success for task instance
{}; reason :{}",
+ taskInstance.getId(), response.getMessage());
+ return remoteLogClient.getPartLog(taskInstance, skipLineNum,
limit);
+ }
+ } else {
+ return remoteLogClient.getPartLog(taskInstance, skipLineNum,
limit);
+ }
+ }
+
+ /**
+ * Retrieves the complete log content for a given task instance as a byte
array.
+ * This method first attempts to fetch the log from local storage; if
unsuccessful, it tries to obtain the log from remote storage.
+ *
+ * @param taskInstance The task instance object, containing information
needed for log retrieval.
+ * @return A byte array containing the complete log content.
+ */
+ public byte[] getWholeLogBytes(TaskInstance taskInstance) {
+ checkArgs(taskInstance);
+ if (checkNodeExists(taskInstance)) {
+ TaskInstanceLogFileDownloadResponse response =
localLogClient.getWholeLog(taskInstance);
+ if (response.getCode() == LogResponseStatus.SUCCESS) {
+ return response.getLogBytes();
+ } else {
+ log.warn("get whole log bytes is not success for task instance
{}; reason :{}", taskInstance.getId(),
+ response.getMessage());
+ return remoteLogClient.getWholeLog(taskInstance);
+ }
+ } else {
+ return remoteLogClient.getWholeLog(taskInstance);
+ }
+ }
+
+ private static void checkArgs(TaskInstance taskInstance) {
+ if (taskInstance == null) {
+ throw new IllegalArgumentException("canFetchLog task instance is
null");
+ }
+ }
+
+ private boolean checkNodeExists(TaskInstance taskInstance) {
+ RegistryNodeType nodeType;
+ if (TaskTypeUtils.isLogicTask(taskInstance.getTaskType())) {
+ nodeType = RegistryNodeType.MASTER;
+ } else {
+ nodeType = RegistryNodeType.WORKER;
+ }
+ boolean exists =
registryClient.checkNodeExists(taskInstance.getHost(), nodeType);
+ if (!exists) {
+ log.warn("Node {} does not exist for task instance {}",
taskInstance.getHost(), taskInstance.getId());
+ }
+ return exists;
+ }
+
+}
diff --git
a/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/executor/logging/RemoteLogClient.java
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/executor/logging/RemoteLogClient.java
new file mode 100644
index 0000000000..1b3542e962
--- /dev/null
+++
b/dolphinscheduler-api/src/main/java/org/apache/dolphinscheduler/api/executor/logging/RemoteLogClient.java
@@ -0,0 +1,54 @@
+/*
+ * 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.api.executor.logging;
+
+import org.apache.dolphinscheduler.common.utils.LogUtils;
+import org.apache.dolphinscheduler.dao.entity.TaskInstance;
+
+import org.springframework.stereotype.Component;
+
+@Component
+public class RemoteLogClient {
+
+ /**
+ * Retrieves the entire log content for a given task instance.
+ * This method is used when it is necessary to obtain all the log
information for a task instance.
+ *
+ * @param taskInstance The task instance object, containing information
such as the task ID and log path.
+ * @return Returns the log content in byte array format.
+ */
+ public byte[] getWholeLog(TaskInstance taskInstance) {
+ return
LogUtils.getFileContentBytesFromRemote(taskInstance.getLogPath());
+ }
+
+ /**
+ * Retrieves part of the log content for a given task instance, based on
the specified line number and the number of lines to read.
+ * This method is used when it is necessary to browse a portion of the log
content, allowing for skipping a certain number of lines and limiting the
number of lines read.
+ *
+ * @param taskInstance The task instance object, containing information
such as the task ID and log path.
+ * @param skipLineNum The number of lines to skip, starting from the
beginning of the log.
+ * @param limit The maximum number of lines to read.
+ * @return Returns the specified part of the log content in string format.
+ */
+ public String getPartLog(TaskInstance taskInstance, int skipLineNum, int
limit) {
+ // todo We can optimize requests by the actual range, reducing disk
usage and network traffic.
+ return LogUtils.rollViewLogLines(
+
LogUtils.readPartFileContentFromRemote(taskInstance.getLogPath(), skipLineNum,
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 1b8cc02b39..a0b3b35fc1 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
@@ -22,6 +22,7 @@ import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationCon
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.exceptions.ServiceException;
+import org.apache.dolphinscheduler.api.executor.logging.LogClientDelegate;
import org.apache.dolphinscheduler.api.service.LoggerService;
import org.apache.dolphinscheduler.api.service.ProjectService;
import org.apache.dolphinscheduler.api.utils.Result;
@@ -34,12 +35,6 @@ import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
import org.apache.dolphinscheduler.dao.mapper.TaskDefinitionMapper;
import org.apache.dolphinscheduler.dao.repository.TaskInstanceDao;
-import org.apache.dolphinscheduler.extract.base.client.Clients;
-import org.apache.dolphinscheduler.extract.common.ILogService;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadRequest;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadResponse;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryRequest;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryResponse;
import org.apache.commons.lang3.StringUtils;
@@ -73,6 +68,9 @@ public class LoggerServiceImpl extends BaseServiceImpl
implements LoggerService
@Autowired
private TaskDefinitionMapper taskDefinitionMapper;
+ @Autowired
+ private LogClientDelegate logClientDelegate;
+
/**
* view log
*
@@ -203,17 +201,7 @@ public class LoggerServiceImpl extends BaseServiceImpl
implements LoggerService
}
try {
- TaskInstanceLogPageQueryRequest request =
TaskInstanceLogPageQueryRequest.builder()
- .taskInstanceId(taskInstance.getId())
- .taskInstanceLogAbsolutePath(logPath)
- .skipLineNum(skipLineNum)
- .limit(limit)
- .build();
- final TaskInstanceLogPageQueryResponse response = Clients
- .withService(ILogService.class)
- .withHost(taskInstance.getHost())
- .pageQueryTaskInstanceLog(request);
- String logContent = response.getLogContent();
+ String logContent =
logClientDelegate.getPartLogString(taskInstance, skipLineNum, limit);
if (logContent != null) {
sb.append(logContent);
}
@@ -241,14 +229,7 @@ public class LoggerServiceImpl extends BaseServiceImpl
implements LoggerService
byte[] logBytes;
try {
- final TaskInstanceLogFileDownloadRequest request = new
TaskInstanceLogFileDownloadRequest(
- taskInstance.getId(),
- logPath);
- final TaskInstanceLogFileDownloadResponse response = Clients
- .withService(ILogService.class)
- .withHost(taskInstance.getHost())
- .getTaskInstanceWholeLogFileBytes(request);
- logBytes = response.getLogBytes();
+ logBytes = logClientDelegate.getWholeLogBytes(taskInstance);
return Bytes.concat(head, logBytes);
} catch (Exception ex) {
log.error("Download TaskInstance: {} Log Error",
taskInstance.getName(), ex);
diff --git
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/executor/logging/LocalLogClientTest.java
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/executor/logging/LocalLogClientTest.java
new file mode 100644
index 0000000000..38ed869007
--- /dev/null
+++
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/executor/logging/LocalLogClientTest.java
@@ -0,0 +1,137 @@
+/*
+ * 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.api.executor.logging;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.apache.dolphinscheduler.api.exceptions.ServiceException;
+import org.apache.dolphinscheduler.dao.entity.TaskInstance;
+import org.apache.dolphinscheduler.extract.base.config.NettyServerConfig;
+import
org.apache.dolphinscheduler.extract.base.server.SpringServerMethodInvokerDiscovery;
+import org.apache.dolphinscheduler.extract.common.ILogService;
+import
org.apache.dolphinscheduler.extract.common.transportor.LogResponseStatus;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadRequest;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadResponse;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryRequest;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryResponse;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.junit.jupiter.MockitoSettings;
+import org.mockito.quality.Strictness;
+
+@ExtendWith(MockitoExtension.class)
+@MockitoSettings(strictness = Strictness.LENIENT)
+public class LocalLogClientTest {
+
+ @InjectMocks
+ private LocalLogClient localLogClient;
+
+ private SpringServerMethodInvokerDiscovery
springServerMethodInvokerDiscovery;
+
+ private int nettyServerPort = 18080;
+
+ @BeforeEach
+ public void setUp() {
+ try (ServerSocket s = new ServerSocket(0)) {
+ nettyServerPort = s.getLocalPort();
+ } catch (IOException e) {
+ return;
+ }
+
+ springServerMethodInvokerDiscovery = new
SpringServerMethodInvokerDiscovery(
+
NettyServerConfig.builder().serverName("TestLogServer").listenPort(nettyServerPort).build());
+ springServerMethodInvokerDiscovery.start();
+
springServerMethodInvokerDiscovery.registerServerMethodInvokerProvider(new
ILogService() {
+
+ @Override
+ public TaskInstanceLogFileDownloadResponse
getTaskInstanceWholeLogFileBytes(TaskInstanceLogFileDownloadRequest
taskInstanceLogFileDownloadRequest) {
+ if (taskInstanceLogFileDownloadRequest.getTaskInstanceId() ==
1) {
+ return new TaskInstanceLogFileDownloadResponse(new
byte[0], LogResponseStatus.SUCCESS, "");
+ } else if
(taskInstanceLogFileDownloadRequest.getTaskInstanceId() == 10) {
+ return new TaskInstanceLogFileDownloadResponse("log
content".getBytes(), LogResponseStatus.SUCCESS,
+ "");
+ }
+
+ throw new ServiceException("download error");
+ }
+
+ @Override
+ public TaskInstanceLogPageQueryResponse
pageQueryTaskInstanceLog(TaskInstanceLogPageQueryRequest
taskInstanceLogPageQueryRequest) {
+ if (taskInstanceLogPageQueryRequest.getTaskInstanceId() !=
null) {
+ if (taskInstanceLogPageQueryRequest.getTaskInstanceId() ==
100) {
+ throw new ServiceException("query log error");
+ } else if
(taskInstanceLogPageQueryRequest.getTaskInstanceId() == 10) {
+ return new TaskInstanceLogPageQueryResponse("Partial
log content", LogResponseStatus.SUCCESS,
+ "");
+ }
+ }
+
+ return new TaskInstanceLogPageQueryResponse();
+ }
+
+ @Override
+ public void removeTaskInstanceLog(String
taskInstanceLogAbsolutePath) {
+
+ }
+ });
+ springServerMethodInvokerDiscovery.start();
+ }
+
+ @AfterEach
+ public void tearDown() {
+ if (springServerMethodInvokerDiscovery != null) {
+ springServerMethodInvokerDiscovery.close();
+ }
+ }
+
+ @Test
+ public void testGetWholeLogSuccess() {
+ TaskInstance taskInstance = new TaskInstance();
+ taskInstance.setHost("127.0.0.1:" + nettyServerPort);
+ taskInstance.setId(1);
+ taskInstance.setLogPath("/path/to/log");
+
+ TaskInstanceLogFileDownloadResponse actualResponse =
localLogClient.getWholeLog(taskInstance);
+
+ assertNotNull(actualResponse);
+ assertArrayEquals("".getBytes(), actualResponse.getLogBytes());
+ }
+
+ @Test
+ public void testGetPartLogSuccess() {
+ TaskInstance taskInstance = new TaskInstance();
+ taskInstance.setId(10);
+ taskInstance.setHost("127.0.0.1:" + nettyServerPort);
+ taskInstance.setLogPath("/path/to/log");
+
+ TaskInstanceLogPageQueryResponse actualResponse =
localLogClient.getPartLog(taskInstance, 0, 10);
+
+ assertNotNull(actualResponse);
+ assertEquals("Partial log content", actualResponse.getLogContent());
+ }
+}
diff --git
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/executor/logging/LogClientDelegateTest.java
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/executor/logging/LogClientDelegateTest.java
new file mode 100644
index 0000000000..edf85268a7
--- /dev/null
+++
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/executor/logging/LogClientDelegateTest.java
@@ -0,0 +1,152 @@
+/*
+ * 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.api.executor.logging;
+
+import static org.junit.jupiter.api.Assertions.assertArrayEquals;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.when;
+
+import org.apache.dolphinscheduler.dao.entity.TaskInstance;
+import
org.apache.dolphinscheduler.extract.common.transportor.LogResponseStatus;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadResponse;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryResponse;
+import org.apache.dolphinscheduler.registry.api.RegistryClient;
+import org.apache.dolphinscheduler.registry.api.enums.RegistryNodeType;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
+import org.mockito.junit.jupiter.MockitoExtension;
+
+@ExtendWith(MockitoExtension.class)
+public class LogClientDelegateTest {
+
+ @Mock
+ private LocalLogClient localLogClient;
+
+ @Mock
+ private RemoteLogClient remoteLogClient;
+
+ @Mock
+ private RegistryClient registryClient;
+
+ @InjectMocks
+ private LogClientDelegate logClientDelegate;
+
+ @Test
+ public void testGetPartLogStringTaskInstanceNullThrowsException() {
+ assertThrows(IllegalArgumentException.class, () ->
logClientDelegate.getPartLogString(null, 0, 10));
+ }
+
+ @Test
+ public void testGetPartLogStringNodeExistsLocalSuccess() {
+ TaskInstance taskInstance = new TaskInstance();
+ taskInstance.setId(1);
+ taskInstance.setHost("localhost");
+ taskInstance.setTaskType("SHELL");
+ when(registryClient.checkNodeExists(eq(taskInstance.getHost()),
any())).thenReturn(true);
+ when(localLogClient.getPartLog(taskInstance, 0, 10))
+ .thenReturn(new TaskInstanceLogPageQueryResponse("logContent",
LogResponseStatus.SUCCESS, ""));
+ String result = logClientDelegate.getPartLogString(taskInstance, 0,
10);
+ assertEquals("logContent", result);
+ }
+
+ @Test
+ public void testGetPartLogStringNodeExistsLocalFailure() {
+ TaskInstance taskInstance = new TaskInstance();
+ taskInstance.setId(1);
+ taskInstance.setHost("localhost");
+ taskInstance.setTaskType("SHELL");
+
+ when(registryClient.checkNodeExists("localhost",
RegistryNodeType.WORKER)).thenReturn(true);
+ when(localLogClient.getPartLog(taskInstance, 0, 10)).thenReturn(
+ new TaskInstanceLogPageQueryResponse(null,
LogResponseStatus.ERROR, "error"));
+ when(remoteLogClient.getPartLog(taskInstance, 0,
10)).thenReturn("remoteLogContent");
+
+ String result = logClientDelegate.getPartLogString(taskInstance, 0,
10);
+ assertEquals("remoteLogContent", result);
+ }
+
+ @Test
+ public void testGetPartLogStringNodeNotExists() {
+ TaskInstance taskInstance = new TaskInstance();
+ taskInstance.setId(1);
+ taskInstance.setHost("localhost");
+ taskInstance.setTaskType("SHELL");
+
+ when(registryClient.checkNodeExists("localhost",
RegistryNodeType.WORKER)).thenReturn(false);
+ when(remoteLogClient.getPartLog(taskInstance, 0,
10)).thenReturn("remoteLogContent");
+
+ String result = logClientDelegate.getPartLogString(taskInstance, 0,
10);
+ assertEquals("remoteLogContent", result);
+ }
+
+ @Test
+ public void testGetWholeLogBytesTaskInstanceNullThrowsException() {
+ assertThrows(IllegalArgumentException.class, () ->
logClientDelegate.getWholeLogBytes(null));
+ }
+
+ @Test
+ public void testGetWholeLogBytesNodeExistsLocalSuccess() {
+ TaskInstance taskInstance = new TaskInstance();
+ taskInstance.setId(1);
+ taskInstance.setHost("localhost");
+ taskInstance.setTaskType("SWITCH");
+
+ when(registryClient.checkNodeExists("localhost",
RegistryNodeType.MASTER)).thenReturn(true);
+ when(localLogClient.getWholeLog(taskInstance)).thenReturn(
+ new TaskInstanceLogFileDownloadResponse("logBytes".getBytes(),
LogResponseStatus.SUCCESS, null));
+
+ byte[] result = logClientDelegate.getWholeLogBytes(taskInstance);
+ assertArrayEquals("logBytes".getBytes(), result);
+ }
+
+ @Test
+ public void testGetWholeLogBytesNodeExistsLocalFailure() {
+ TaskInstance taskInstance = new TaskInstance();
+ taskInstance.setId(1);
+ taskInstance.setHost("localhost");
+ taskInstance.setTaskType("SWITCH");
+
+ when(registryClient.checkNodeExists("localhost",
RegistryNodeType.MASTER)).thenReturn(true);
+ when(localLogClient.getWholeLog(taskInstance)).thenReturn(
+ new TaskInstanceLogFileDownloadResponse(null,
LogResponseStatus.ERROR, "error"));
+
when(remoteLogClient.getWholeLog(taskInstance)).thenReturn("remoteLogBytes".getBytes());
+
+ byte[] result = logClientDelegate.getWholeLogBytes(taskInstance);
+ assertArrayEquals("remoteLogBytes".getBytes(), result);
+ }
+
+ @Test
+ public void testGetWholeLogBytesNodeNotExists() {
+ TaskInstance taskInstance = new TaskInstance();
+ taskInstance.setId(1);
+ taskInstance.setHost("localhost");
+ taskInstance.setTaskType("SWITCH");
+
+ when(registryClient.checkNodeExists("localhost",
RegistryNodeType.MASTER)).thenReturn(false);
+
when(remoteLogClient.getWholeLog(taskInstance)).thenReturn("remoteLogBytes".getBytes());
+
+ byte[] result = logClientDelegate.getWholeLogBytes(taskInstance);
+ assertArrayEquals("remoteLogBytes".getBytes(), result);
+ }
+}
diff --git
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/LoggerServiceTest.java
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/LoggerServiceTest.java
index 306cf91de2..8788696cbf 100644
---
a/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/LoggerServiceTest.java
+++
b/dolphinscheduler-api/src/test/java/org/apache/dolphinscheduler/api/service/LoggerServiceTest.java
@@ -22,6 +22,8 @@ import static
org.apache.dolphinscheduler.api.AssertionsHelper.assertThrowsServi
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.DOWNLOAD_LOG;
import static
org.apache.dolphinscheduler.api.constants.ApiFuncIdentificationConstant.VIEW_LOG;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.when;
@@ -29,6 +31,7 @@ import static org.mockito.Mockito.when;
import org.apache.dolphinscheduler.api.AssertionsHelper;
import org.apache.dolphinscheduler.api.enums.Status;
import org.apache.dolphinscheduler.api.exceptions.ServiceException;
+import org.apache.dolphinscheduler.api.executor.logging.LogClientDelegate;
import org.apache.dolphinscheduler.api.service.impl.LoggerServiceImpl;
import org.apache.dolphinscheduler.api.utils.Result;
import org.apache.dolphinscheduler.common.constants.Constants;
@@ -40,23 +43,12 @@ import org.apache.dolphinscheduler.dao.entity.User;
import org.apache.dolphinscheduler.dao.mapper.ProjectMapper;
import org.apache.dolphinscheduler.dao.mapper.TaskDefinitionMapper;
import org.apache.dolphinscheduler.dao.repository.TaskInstanceDao;
-import org.apache.dolphinscheduler.extract.base.config.NettyServerConfig;
-import
org.apache.dolphinscheduler.extract.base.server.SpringServerMethodInvokerDiscovery;
-import org.apache.dolphinscheduler.extract.common.ILogService;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadRequest;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadResponse;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryRequest;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryResponse;
-
-import java.io.IOException;
-import java.net.ServerSocket;
+
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;
-import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
@@ -88,61 +80,10 @@ public class LoggerServiceTest {
@Mock
private TaskDefinitionMapper taskDefinitionMapper;
- private SpringServerMethodInvokerDiscovery
springServerMethodInvokerDiscovery;
-
- private int nettyServerPort = 18080;
-
- @BeforeEach
- public void setUp() {
- try (ServerSocket s = new ServerSocket(0)) {
- nettyServerPort = s.getLocalPort();
- } catch (IOException e) {
- return;
- }
-
- springServerMethodInvokerDiscovery = new
SpringServerMethodInvokerDiscovery(
-
NettyServerConfig.builder().serverName("TestLogServer").listenPort(nettyServerPort).build());
- springServerMethodInvokerDiscovery.start();
-
springServerMethodInvokerDiscovery.registerServerMethodInvokerProvider(new
ILogService() {
-
- @Override
- public TaskInstanceLogFileDownloadResponse
getTaskInstanceWholeLogFileBytes(TaskInstanceLogFileDownloadRequest
taskInstanceLogFileDownloadRequest) {
- if (taskInstanceLogFileDownloadRequest.getTaskInstanceId() ==
1) {
- return new TaskInstanceLogFileDownloadResponse(new
byte[0]);
- } else if
(taskInstanceLogFileDownloadRequest.getTaskInstanceId() == 10) {
- return new TaskInstanceLogFileDownloadResponse("log
content".getBytes());
- }
-
- throw new ServiceException("download error");
- }
-
- @Override
- public TaskInstanceLogPageQueryResponse
pageQueryTaskInstanceLog(TaskInstanceLogPageQueryRequest
taskInstanceLogPageQueryRequest) {
- if (taskInstanceLogPageQueryRequest.getTaskInstanceId() !=
null) {
- if (taskInstanceLogPageQueryRequest.getTaskInstanceId() ==
100) {
- throw new ServiceException("query log error");
- } else if
(taskInstanceLogPageQueryRequest.getTaskInstanceId() == 10) {
- return new TaskInstanceLogPageQueryResponse("log
content");
- }
- }
-
- return new TaskInstanceLogPageQueryResponse();
- }
-
- @Override
- public void removeTaskInstanceLog(String
taskInstanceLogAbsolutePath) {
-
- }
- });
- springServerMethodInvokerDiscovery.start();
- }
+ @Mock
+ private LogClientDelegate logClientDelegate;
- @AfterEach
- public void tearDown() {
- if (springServerMethodInvokerDiscovery != null) {
- springServerMethodInvokerDiscovery.close();
- }
- }
+ private final int nettyServerPort = 18080;
@Test
public void testQueryLog() {
@@ -237,8 +178,10 @@ public class LoggerServiceTest {
() -> loggerService.queryLog(loginUser, 1, 1, 1));
// SUCCESS
+ when(logClientDelegate.getWholeLogBytes(any())).thenReturn(new
byte[0]);
doNothing().when(projectService).checkProjectAndAuthThrowException(loginUser,
taskInstance.getProjectCode(),
DOWNLOAD_LOG);
+ when(logClientDelegate.getWholeLogBytes(any())).thenReturn(new
byte[0]);
byte[] logBytes = loggerService.getLogBytes(loginUser, 1);
Assertions.assertEquals(42, logBytes.length -
String.valueOf(nettyServerPort).length());
}
@@ -278,11 +221,16 @@ public class LoggerServiceTest {
taskDefinition.setProjectCode(1);
taskInstance.setId(10);
when(taskInstanceDao.queryById(10)).thenReturn(taskInstance);
+
+ when(logClientDelegate.getPartLogString(any(), anyInt(),
anyInt())).thenReturn("log content");
+
String result = loggerService.queryLog(loginUser, projectCode, 10, 1,
1);
assertEquals("log content", result);
taskInstance.setId(100);
when(taskInstanceDao.queryById(100)).thenReturn(taskInstance);
+ doThrow(new ServiceException("query log
error")).when(logClientDelegate).getPartLogString(any(), anyInt(),
+ anyInt());
assertThrowsServiceException(Status.QUERY_TASK_INSTANCE_LOG_ERROR,
() -> loggerService.queryLog(loginUser, projectCode, 10, 1,
1));
}
@@ -314,6 +262,7 @@ public class LoggerServiceTest {
when(taskInstanceDao.queryById(1)).thenReturn(taskInstance);
when(taskDefinitionMapper.queryByCode(taskInstance.getTaskCode())).thenReturn(taskDefinition);
+ when(logClientDelegate.getWholeLogBytes(any())).thenReturn(new
byte[0]);
assertDoesNotThrow(() -> loggerService.getLogBytes(loginUser,
projectCode, 1));
taskDefinition.setProjectCode(2L);
@@ -323,6 +272,7 @@ public class LoggerServiceTest {
taskDefinition.setProjectCode(1L);
taskInstance.setId(100);
when(taskInstanceDao.queryById(100)).thenReturn(taskInstance);
+ doThrow(new ServiceException("download
error")).when(logClientDelegate).getWholeLogBytes(any());
assertThrowsServiceException(Status.DOWNLOAD_TASK_INSTANCE_LOG_FILE_ERROR,
() -> loggerService.getLogBytes(loginUser, projectCode, 100));
}
diff --git
a/dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/service/impl/LogServiceImpl.java
b/dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/service/impl/LogServiceImpl.java
new file mode 100644
index 0000000000..bbe2c09d92
--- /dev/null
+++
b/dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/service/impl/LogServiceImpl.java
@@ -0,0 +1,85 @@
+/*
+ * 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.extract.common.service.impl;
+
+import org.apache.dolphinscheduler.common.utils.FileUtils;
+import org.apache.dolphinscheduler.common.utils.LogUtils;
+import org.apache.dolphinscheduler.extract.common.ILogService;
+import
org.apache.dolphinscheduler.extract.common.transportor.LogResponseStatus;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadRequest;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadResponse;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryRequest;
+import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryResponse;
+
+import org.apache.commons.lang3.exception.ExceptionUtils;
+
+import java.util.List;
+
+public class LogServiceImpl implements ILogService {
+
+ /**
+ * Downloads the entire log file for a task instance.
+ *
+ * @param taskInstanceLogFileDownloadRequest Request object containing the
path to the task instance log file.
+ * @return Response object containing the log file content in byte array
form.
+ */
+ @Override
+ public TaskInstanceLogFileDownloadResponse
getTaskInstanceWholeLogFileBytes(TaskInstanceLogFileDownloadRequest
taskInstanceLogFileDownloadRequest) {
+ final TaskInstanceLogFileDownloadResponse
taskInstanceLogFileDownloadResponse =
+ new TaskInstanceLogFileDownloadResponse();
+ try {
+ byte[] bytes = LogUtils
+
.getFileContentBytesFromLocal(taskInstanceLogFileDownloadRequest.getTaskInstanceLogAbsolutePath());
+ taskInstanceLogFileDownloadResponse.setLogBytes(bytes);
+ } catch (Exception e) {
+
taskInstanceLogFileDownloadResponse.setCode(LogResponseStatus.ERROR);
+
taskInstanceLogFileDownloadResponse.setMessage(ExceptionUtils.getRootCauseMessage(e));
+ }
+ return taskInstanceLogFileDownloadResponse;
+ }
+
+ /**
+ * Performs paginated queries on task instance logs.
+ *
+ * @param taskInstanceLogPageQueryRequest Request object containing the
path to the task instance log file, the number of lines to skip, and the
maximum number of lines to read.
+ * @return Response object containing the log content.
+ */
+ @Override
+ public TaskInstanceLogPageQueryResponse
pageQueryTaskInstanceLog(TaskInstanceLogPageQueryRequest
taskInstanceLogPageQueryRequest) {
+ final TaskInstanceLogPageQueryResponse
taskInstanceLogPageQueryResponse =
+ new TaskInstanceLogPageQueryResponse();
+ List<String> lines;
+ try {
+ lines = LogUtils.readPartFileContentFromLocal(
+
taskInstanceLogPageQueryRequest.getTaskInstanceLogAbsolutePath(),
+ taskInstanceLogPageQueryRequest.getSkipLineNum(),
+ taskInstanceLogPageQueryRequest.getLimit());
+
taskInstanceLogPageQueryResponse.setLogContent(LogUtils.rollViewLogLines(lines));
+ } catch (Exception e) {
+ taskInstanceLogPageQueryResponse.setCode(LogResponseStatus.ERROR);
+
taskInstanceLogPageQueryResponse.setMessage(ExceptionUtils.getMessage(e));
+ }
+ return taskInstanceLogPageQueryResponse;
+ }
+
+ @Override
+ public void removeTaskInstanceLog(String taskInstanceLogAbsolutePath) {
+ FileUtils.deleteFile(taskInstanceLogAbsolutePath);
+ }
+
+}
diff --git
a/dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/transportor/TaskInstanceLogFileDownloadResponse.java
b/dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/transportor/LogResponseStatus.java
similarity index 79%
copy from
dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/transportor/TaskInstanceLogFileDownloadResponse.java
copy to
dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/transportor/LogResponseStatus.java
index ac1e5b0cfd..c82b6c342c 100644
---
a/dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/transportor/TaskInstanceLogFileDownloadResponse.java
+++
b/dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/transportor/LogResponseStatus.java
@@ -17,15 +17,19 @@
package org.apache.dolphinscheduler.extract.common.transportor;
-import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+public enum LogResponseStatus {
+ /**
+ * Success status code.
+ */
+ SUCCESS,
-@Data
-@NoArgsConstructor
-@AllArgsConstructor
-public class TaskInstanceLogFileDownloadResponse {
-
- private byte[] logBytes;
+ /**
+ * General error status code.
+ */
+ ERROR,
+ /**
+ * Log file not found status code.
+ */
+ LOG_FILE_NOT_FOUND,
}
diff --git
a/dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/transportor/TaskInstanceLogFileDownloadResponse.java
b/dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/transportor/TaskInstanceLogFileDownloadResponse.java
index ac1e5b0cfd..6cf6dff623 100644
---
a/dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/transportor/TaskInstanceLogFileDownloadResponse.java
+++
b/dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/transportor/TaskInstanceLogFileDownloadResponse.java
@@ -28,4 +28,8 @@ public class TaskInstanceLogFileDownloadResponse {
private byte[] logBytes;
+ private LogResponseStatus code = LogResponseStatus.SUCCESS;
+
+ private String message;
+
}
diff --git
a/dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/transportor/TaskInstanceLogPageQueryResponse.java
b/dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/transportor/TaskInstanceLogPageQueryResponse.java
index ac769d7677..994ceb96b5 100644
---
a/dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/transportor/TaskInstanceLogPageQueryResponse.java
+++
b/dolphinscheduler-extract/dolphinscheduler-extract-common/src/main/java/org/apache/dolphinscheduler/extract/common/transportor/TaskInstanceLogPageQueryResponse.java
@@ -28,4 +28,8 @@ public class TaskInstanceLogPageQueryResponse {
private String logContent;
+ private LogResponseStatus code = LogResponseStatus.SUCCESS;
+
+ private String message;
+
}
diff --git
a/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/rpc/MasterLogServiceImpl.java
b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/rpc/MasterLogServiceImpl.java
index 98e7461f50..5fae40600f 100644
---
a/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/rpc/MasterLogServiceImpl.java
+++
b/dolphinscheduler-master/src/main/java/org/apache/dolphinscheduler/server/master/rpc/MasterLogServiceImpl.java
@@ -17,15 +17,8 @@
package org.apache.dolphinscheduler.server.master.rpc;
-import org.apache.dolphinscheduler.common.utils.FileUtils;
-import org.apache.dolphinscheduler.common.utils.LogUtils;
import org.apache.dolphinscheduler.extract.common.ILogService;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadRequest;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadResponse;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryRequest;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryResponse;
-
-import java.util.List;
+import org.apache.dolphinscheduler.extract.common.service.impl.LogServiceImpl;
import lombok.extern.slf4j.Slf4j;
@@ -33,30 +26,6 @@ import org.springframework.stereotype.Service;
@Slf4j
@Service
-public class MasterLogServiceImpl implements ILogService {
-
- @Override
- public TaskInstanceLogFileDownloadResponse
getTaskInstanceWholeLogFileBytes(TaskInstanceLogFileDownloadRequest
logicTaskInstanceLogFileDownloadRequest) {
- byte[] bytes =
-
LogUtils.getFileContentBytes(logicTaskInstanceLogFileDownloadRequest.getTaskInstanceLogAbsolutePath());
- // todo: if file not exists, return error result
- return new TaskInstanceLogFileDownloadResponse(bytes);
- }
-
- @Override
- public TaskInstanceLogPageQueryResponse
pageQueryTaskInstanceLog(TaskInstanceLogPageQueryRequest
taskInstanceLogPageQueryRequest) {
-
- List<String> lines = LogUtils.readPartFileContent(
-
taskInstanceLogPageQueryRequest.getTaskInstanceLogAbsolutePath(),
- taskInstanceLogPageQueryRequest.getSkipLineNum(),
- taskInstanceLogPageQueryRequest.getLimit());
-
- String logContent = LogUtils.rollViewLogLines(lines);
- return new TaskInstanceLogPageQueryResponse(logContent);
- }
+public class MasterLogServiceImpl extends LogServiceImpl implements
ILogService {
- @Override
- public void removeTaskInstanceLog(String taskInstanceLogAbsolutePath) {
- FileUtils.deleteFile(taskInstanceLogAbsolutePath);
- }
}
diff --git
a/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/rpc/WorkerLogServiceImpl.java
b/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/rpc/WorkerLogServiceImpl.java
index b1bca6dfe6..68a36c0c6c 100644
---
a/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/rpc/WorkerLogServiceImpl.java
+++
b/dolphinscheduler-worker/src/main/java/org/apache/dolphinscheduler/server/worker/rpc/WorkerLogServiceImpl.java
@@ -17,15 +17,8 @@
package org.apache.dolphinscheduler.server.worker.rpc;
-import org.apache.dolphinscheduler.common.utils.FileUtils;
-import org.apache.dolphinscheduler.common.utils.LogUtils;
import org.apache.dolphinscheduler.extract.common.ILogService;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadRequest;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogFileDownloadResponse;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryRequest;
-import
org.apache.dolphinscheduler.extract.common.transportor.TaskInstanceLogPageQueryResponse;
-
-import java.util.List;
+import org.apache.dolphinscheduler.extract.common.service.impl.LogServiceImpl;
import lombok.extern.slf4j.Slf4j;
@@ -33,29 +26,6 @@ import org.springframework.stereotype.Service;
@Slf4j
@Service
-public class WorkerLogServiceImpl implements ILogService {
-
- @Override
- public TaskInstanceLogFileDownloadResponse
getTaskInstanceWholeLogFileBytes(TaskInstanceLogFileDownloadRequest
taskInstanceLogFileDownloadRequest) {
- byte[] bytes = LogUtils
-
.getFileContentBytes(taskInstanceLogFileDownloadRequest.getTaskInstanceLogAbsolutePath());
- // todo: if file not exists, return error result
- return new TaskInstanceLogFileDownloadResponse(bytes);
- }
-
- @Override
- public TaskInstanceLogPageQueryResponse
pageQueryTaskInstanceLog(TaskInstanceLogPageQueryRequest
taskInstanceLogPageQueryRequest) {
- List<String> lines = LogUtils.readPartFileContent(
-
taskInstanceLogPageQueryRequest.getTaskInstanceLogAbsolutePath(),
- taskInstanceLogPageQueryRequest.getSkipLineNum(),
- taskInstanceLogPageQueryRequest.getLimit());
-
- String logContent = LogUtils.rollViewLogLines(lines);
- return new TaskInstanceLogPageQueryResponse(logContent);
- }
+public class WorkerLogServiceImpl extends LogServiceImpl implements
ILogService {
- @Override
- public void removeTaskInstanceLog(String taskInstanceLogAbsolutePath) {
- FileUtils.deleteFile(taskInstanceLogAbsolutePath);
- }
}