Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,15 @@ public byte[] getWholeLogBytes(TaskInstance taskInstance) {
if (checkNodeExists(taskInstance)) {
TaskInstanceLogFileDownloadResponse response = localLogClient.getWholeLog(taskInstance);
if (response.getCode() == LogResponseStatus.SUCCESS) {
return response.getLogBytes();
// For local logs, also get rolling log files if they exist
String logPath = taskInstance.getLogPath();
java.io.File logFile = new java.io.File(logPath);
if (logFile.exists()) {
return org.apache.dolphinscheduler.common.utils.LogUtils
.getFileContentBytesWithRollingLogs(logPath);
} else {
return response.getLogBytes();
}
Comment on lines +81 to +89
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the local-log success path, this code only includes rolling logs if the API server can directly see the log file path on its local filesystem. In typical deployments logs reside on the worker/master host and are returned via the RPC (response.getLogBytes()), so rolling segments will still be omitted. The more reliable fix is to include rolling log handling in the provider side (ILogService/LogServiceImpl) or enhance the RPC response to include rolled files rather than trying to re-read local disk here.

Suggested change
// For local logs, also get rolling log files if they exist
String logPath = taskInstance.getLogPath();
java.io.File logFile = new java.io.File(logPath);
if (logFile.exists()) {
return org.apache.dolphinscheduler.common.utils.LogUtils
.getFileContentBytesWithRollingLogs(logPath);
} else {
return response.getLogBytes();
}
return response.getLogBytes();

Copilot uses AI. Check for mistakes.
} else {
log.warn("get whole log bytes is not success for task instance {}; reason :{}", taskInstance.getId(),
response.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class RemoteLogClient {
* @return Returns the log content in byte array format.
*/
public byte[] getWholeLog(TaskInstance taskInstance) {
return LogUtils.getFileContentBytesFromRemote(taskInstance.getLogPath());
return LogUtils.getFileContentBytesWithRollingLogs(taskInstance.getLogPath());
}
Comment on lines 35 to 37
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RemoteLogClient#getWholeLog now reads logs via getFileContentBytesWithRollingLogs(taskInstance.getLogPath()), which only works when the log file exists on the local filesystem. This removes the previous remote-fetch behavior (RemoteLogUtils.getRemoteLog) and will fail when logs are stored remotely / need downloading. Consider keeping the remote download step and then reading rolling files (e.g., fetch base + rolled files from remote before concatenation), or delegate to an API that preserves remote-logging support.

Copilot uses AI. Check for mistakes.

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Expand Down Expand Up @@ -79,11 +82,21 @@
int limit) {
File file = new File(filePath);
if (file.exists() && file.isFile()) {
try (Stream<String> stream = Files.lines(Paths.get(filePath))) {
return stream.skip(skipLine).limit(limit).collect(Collectors.toList());
} catch (IOException e) {
log.error("read file error", e);
throw new RuntimeException(String.format("Read file: %s error", filePath), e);
log.info("readPartFileContentFromLocal Reading log file");
// Check if there are rolling log files
List<File> logFiles = getRollingLogFiles(filePath);

if (logFiles.size() > 1) {
// Handle rolling log files
return readFromRollingLogFiles(logFiles, skipLine, limit);
} else {
// Handle single log file
try (Stream<String> stream = Files.lines(Paths.get(filePath))) {
return stream.skip(skipLine).limit(limit).collect(Collectors.toList());
} catch (IOException e) {
log.error("read file error", e);
throw new RuntimeException(String.format("Read file: %s error", filePath), e);
}
}
} else {
throw new RuntimeException("The file path: " + filePath + " not exists");
Expand Down Expand Up @@ -169,4 +182,154 @@
return loggerContext.getProperty("log.base.ctx");
}

/**
* Get all rolling log files for a given base file path.
* Returns a sorted list containing the base file and its rolled versions (e.g., .1, .2, etc.)
* ordered from newest to oldest (base file first, then .1, .2, etc.)
*/
private static List<File> getRollingLogFiles(String basePath) {
List<File> allFiles = new ArrayList<>();

File baseFile = new File(basePath);
File parentDir = baseFile.getParentFile();
String fileName = baseFile.getName();

// Add the base file if it exists
if (baseFile.exists()) {
allFiles.add(baseFile);
}

// Look for rolling files with pattern: basePath.N
if (parentDir != null) {
File[] files = parentDir.listFiles((dir, name) -> name.startsWith(fileName + ".") &&
Pattern.matches(Pattern.quote(fileName) + "\\.\\d+", name));

if (files != null) {
allFiles.addAll(Arrays.asList(files));
}
}

// Sort all files in reverse order based on rolling number
// Base file (without number) is treated as having number 0, so it comes last
// descending order (larger numbers first)
allFiles.sort((file1, file2) -> {
int num1 = isRollingFile(file1) ? extractRollingNumber(file1) : 0;
int num2 = isRollingFile(file2) ? extractRollingNumber(file2) : 0;
return Integer.compare(num2, num1);
});

return allFiles;
Comment on lines +185 to +221
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Javadoc for getRollingLogFiles says the list is ordered "from newest to oldest (base file first, then .1, .2, etc.)", but the implementation sorts rolling files by descending index and treats the base file as 0 (so it ends up last). Please update either the ordering or the documentation so callers know what order to expect (this affects pagination semantics).

Copilot uses AI. Check for mistakes.
}

/**
* Extract the rolling number from a file name (e.g., from "xxx.log.3" extract 3)
*/
private static int extractRollingNumber(File file) {
String fileName = file.getName();
int lastDotIndex = fileName.lastIndexOf('.');
if (lastDotIndex != -1 && lastDotIndex < fileName.length() - 1) {
try {
return Integer.parseInt(fileName.substring(lastDotIndex + 1));
} catch (NumberFormatException e) {
return Integer.MAX_VALUE; // Put invalid files at the end
}
}
return Integer.MAX_VALUE;
}

/**
* Check if the file is a rolling file (has a number suffix like .1, .2, etc.)
*/
private static boolean isRollingFile(File file) {
String fileName = file.getName();
// Check if the filename matches the pattern of a rolling file (basename.number)
int lastDotIndex = fileName.lastIndexOf('.');
if (lastDotIndex != -1 && lastDotIndex < fileName.length() - 1) {
String suffix = fileName.substring(lastDotIndex + 1);
return suffix.matches("\\d+");
}
return false;
}

/**
* Read lines from multiple rolling log files in order
*/
private static List<String> readFromRollingLogFiles(List<File> logFiles, int skipLine, int limit) {
List<String> allLines = new ArrayList<>();

// Read all lines from all log files in order
for (File file : logFiles) {
log.info("Reading log file: {}", file.getAbsolutePath());
try (Stream<String> stream = Files.lines(file.toPath())) {
List<String> fileLines = stream.collect(Collectors.toList());
allLines.addAll(fileLines);
} catch (IOException e) {
log.error("Error reading file: " + file.getAbsolutePath(), e);
throw new RuntimeException(String.format("Read file: %s error", file.getAbsolutePath()), e);

Check warning on line 268 in dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/LogUtils.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace generic exceptions with specific library exceptions or a custom exception.

See more on https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&issues=AZ0-FyREoxp4O0LdRY4e&open=AZ0-FyREoxp4O0LdRY4e&pullRequest=17935
}
}

// Apply skip and limit with overflow protection
int startIndex = Math.min(skipLine, allLines.size());
// Prevent integer overflow when calculating end index
int endIndex;
if (limit > allLines.size() - startIndex) {
endIndex = allLines.size();
} else {
endIndex = startIndex + limit;
}

return allLines.subList(startIndex, endIndex);
Comment on lines +258 to +282
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

readFromRollingLogFiles reads all lines from every rolling file into memory (collect + addAll) and only then applies skip/limit. For large logs this can be very memory-expensive and can negate the benefit of rolling. Prefer streaming across files: skip across files incrementally and stop reading as soon as limit lines are collected (without materializing entire files).

Suggested change
List<String> allLines = new ArrayList<>();
// Read all lines from all log files in order
for (File file : logFiles) {
log.info("Reading log file: {}", file.getAbsolutePath());
try (Stream<String> stream = Files.lines(file.toPath())) {
List<String> fileLines = stream.collect(Collectors.toList());
allLines.addAll(fileLines);
} catch (IOException e) {
log.error("Error reading file: " + file.getAbsolutePath(), e);
throw new RuntimeException(String.format("Read file: %s error", file.getAbsolutePath()), e);
}
}
// Apply skip and limit with overflow protection
int startIndex = Math.min(skipLine, allLines.size());
// Prevent integer overflow when calculating end index
int endIndex;
if (limit > allLines.size() - startIndex) {
endIndex = allLines.size();
} else {
endIndex = startIndex + limit;
}
return allLines.subList(startIndex, endIndex);
List<String> result = new ArrayList<>();
int remainingToSkip = Math.max(0, skipLine);
int remainingToTake = limit < 0 ? 0 : limit;
// Stream lines from log files in order, applying skip and limit across files
for (File file : logFiles) {
if (remainingToTake == 0) {
break;
}
log.info("Reading log file: {}", file.getAbsolutePath());
try (Stream<String> stream = Files.lines(file.toPath())) {
java.util.Iterator<String> iterator = stream.iterator();
while (iterator.hasNext() && remainingToTake > 0) {
String line = iterator.next();
if (remainingToSkip > 0) {
remainingToSkip--;
continue;
}
result.add(line);
remainingToTake--;
}
} catch (IOException e) {
log.error("Error reading file: " + file.getAbsolutePath(), e);
throw new RuntimeException(String.format("Read file: %s error", file.getAbsolutePath()), e);
}
}
return result;

Copilot uses AI. Check for mistakes.
}

/**
* Get content of multiple log files (including rolling log files) as byte array
* Reads files in reverse order (xxx.log.n, xxx.log.n-1, ..., xxx.log)
*
* @param filePath base file path
* @return byte array of all log files content
*/
public static byte[] getFileContentBytesWithRollingLogs(String filePath) {
File file = new File(filePath);
if (file.exists() && file.isFile()) {
// Check if there are rolling log files
List<File> logFiles = getRollingLogFiles(filePath);

if (logFiles.size() > 1) {
// Handle multiple log files (base file + rolling files)
return getBytesFromMultipleLogFiles(logFiles);
} else {
// Handle single log file
return getFileContentBytesFromLocal(filePath);
}
} else {
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getFileContentBytesWithRollingLogs throws if the base log file doesn't exist, and it doesn't attempt RemoteLogUtils.getRemoteLog even when remote logging is enabled. Since this method is now used by RemoteLogClient, it can break log download when logs must be fetched from remote storage. Consider adding a remote-aware variant (download base + rolled files when remote logging is enabled) or integrating remote fallback into this method.

Suggested change
} else {
} else {
// Local base log file does not exist, try to fetch from remote storage
log.info("Local log file: {} does not exist, try to get remote log.", filePath);
try {
byte[] remoteLogBytes = RemoteLogUtils.getRemoteLog(filePath);
if (remoteLogBytes != null && remoteLogBytes.length > 0) {
return remoteLogBytes;
}
log.warn("Remote log file: {} is empty or not found.", filePath);
} catch (Exception ex) {
log.warn("Failed to get remote log file: {}", filePath, ex);
}

Copilot uses AI. Check for mistakes.
throw new RuntimeException("The file path: " + filePath + " not exists");

Check warning on line 306 in dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/LogUtils.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace generic exceptions with specific library exceptions or a custom exception.

See more on https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&issues=AZ0-FyREoxp4O0LdRY4f&open=AZ0-FyREoxp4O0LdRY4f&pullRequest=17935
}
}

/**
* Read bytes from multiple log files in order
*/
private static byte[] getBytesFromMultipleLogFiles(List<File> logFiles) {
List<byte[]> allBytes = new ArrayList<>();

// Read all bytes from all log files in order
for (File file : logFiles) {
log.info("Reading log file for download: {}", file.getAbsolutePath());
byte[] fileBytes = getFileContentBytesFromLocal(file.getAbsolutePath());
allBytes.add(fileBytes);
}

// Combine all bytes
int totalLength = allBytes.stream().mapToInt(bytes -> bytes.length).sum();
byte[] result = new byte[totalLength];
int position = 0;

for (byte[] bytes : allBytes) {
System.arraycopy(bytes, 0, result, position, bytes.length);
position += bytes.length;
}

return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/*
* 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.common.utils;

import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.File;
import java.net.URL;
import java.util.List;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class LogUtilsTest {

Check warning on line 32 in dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/LogUtilsTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this 'public' modifier.

See more on https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&issues=AZ0-FyT6oxp4O0LdRY4r&open=AZ0-FyT6oxp4O0LdRY4r&pullRequest=17935

private String predefinedLogPath;

@BeforeEach
public void setUp() {

Check warning on line 37 in dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/LogUtilsTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this 'public' modifier.

See more on https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&issues=AZ0-FyT6oxp4O0LdRY4h&open=AZ0-FyT6oxp4O0LdRY4h&pullRequest=17935
URL resourceUrl = getClass().getClassLoader().getResource("log/730.log");
if (resourceUrl != null) {
predefinedLogPath = resourceUrl.getPath();
}
}
Comment on lines +36 to +42
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test setup allows predefinedLogPath to remain null (e.g., resource not found) and subsequent tests silently do nothing due to if (predefinedLogPath != null) guards. Tests should fail fast when the required resource is missing (e.g., assertNotNull(resourceUrl)) so the suite doesn't produce false positives.

Copilot uses AI. Check for mistakes.

@AfterEach
public void tearDown() {

Check failure on line 45 in dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/LogUtilsTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Add a nested comment explaining why this method is empty, throw an UnsupportedOperationException or complete the implementation.

See more on https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&issues=AZ0-FyT6oxp4O0LdRY4g&open=AZ0-FyT6oxp4O0LdRY4g&pullRequest=17935

Check warning on line 45 in dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/LogUtilsTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this 'public' modifier.

See more on https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&issues=AZ0-FyT6oxp4O0LdRY4i&open=AZ0-FyT6oxp4O0LdRY4i&pullRequest=17935
}

@Test
public void testReadPartFileContentFromLocal_Success() {

Check warning on line 49 in dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/LogUtilsTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this 'public' modifier.

See more on https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&issues=AZ0-FyT6oxp4O0LdRY4j&open=AZ0-FyT6oxp4O0LdRY4j&pullRequest=17935
if (predefinedLogPath != null) {
String path = predefinedLogPath.replace("%20", " ");
List<String> result = LogUtils.readPartFileContentFromLocal(path, 1, 3);

assertNotNull(result);
assertTrue(result.size() >= 0);
}
Comment on lines +49 to +56
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assertions like assertTrue(result.size() >= 0) are always true and don't validate behavior. Consider asserting expected sizes / expected content (or at least > 0 when reading a known fixture) so the test actually verifies the rolling-log read logic.

Copilot uses AI. Check for mistakes.
}

@Test
public void testReadPartFileContentFromLocal_SkipNoneLimitAll() {

Check warning on line 60 in dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/LogUtilsTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this 'public' modifier.

See more on https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&issues=AZ0-FyT6oxp4O0LdRY4k&open=AZ0-FyT6oxp4O0LdRY4k&pullRequest=17935
if (predefinedLogPath != null) {
String path = predefinedLogPath.replace("%20", " ");
List<String> result = LogUtils.readPartFileContentFromLocal(path, 0, 100);

assertNotNull(result);
assertTrue(result.size() >= 0);
}
}

@Test
public void testReadPartFileContentFromPredefinedRollingFiles() {

Check warning on line 71 in dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/LogUtilsTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this 'public' modifier.

See more on https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&issues=AZ0-FyT6oxp4O0LdRY4l&open=AZ0-FyT6oxp4O0LdRY4l&pullRequest=17935
if (predefinedLogPath != null) {
String mainLogPath = predefinedLogPath.replace("%20", " ");

File mainLogFile = new File(mainLogPath);
assertTrue(mainLogFile.exists(), "Main log file should exist");

File rollingLogFile = new File(mainLogPath + ".1");
assertTrue(rollingLogFile.exists(), "Rolling log file should exist");

List<String> result = LogUtils.readPartFileContentFromLocal(mainLogPath, 0, 50);

assertNotNull(result);
assertTrue(result.size() > 0, "Should have some content from the log files");

System.out.println("Number of lines read: " + result.size());
for (int i = 0; i < Math.min(5, result.size()); i++) {
System.out.println("Line " + i + ": " + result.get(i));
}
Comment on lines +85 to +89
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unit tests should avoid writing to stdout; the System.out.println debug output adds noise to test runs and CI logs. Please remove these prints (or replace with assertions / a logger if truly needed).

Suggested change
System.out.println("Number of lines read: " + result.size());
for (int i = 0; i < Math.min(5, result.size()); i++) {
System.out.println("Line " + i + ": " + result.get(i));
}

Copilot uses AI. Check for mistakes.
}
}

@Test
public void testReadPartFileContentFromLocal_SkipAll() {

Check warning on line 94 in dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/LogUtilsTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this 'public' modifier.

See more on https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&issues=AZ0-FyT6oxp4O0LdRY4m&open=AZ0-FyT6oxp4O0LdRY4m&pullRequest=17935
if (predefinedLogPath != null) {
String path = predefinedLogPath.replace("%20", " ");
List<String> result = LogUtils.readPartFileContentFromLocal(path, 1000, 5);

assertNotNull(result);
assertTrue(result.isEmpty());
}
}

@Test
public void testReadPartFileContentFromLocal_LimitZero() {

Check warning on line 105 in dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/LogUtilsTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this 'public' modifier.

See more on https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&issues=AZ0-FyT6oxp4O0LdRY4n&open=AZ0-FyT6oxp4O0LdRY4n&pullRequest=17935
if (predefinedLogPath != null) {
String path = predefinedLogPath.replace("%20", " ");
List<String> result = LogUtils.readPartFileContentFromLocal(path, 0, 0);

assertNotNull(result);
assertTrue(result.isEmpty());
}
}

@Test
public void testReadPartFileContentFromLocal_FileDoesNotExist() {

Check warning on line 116 in dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/LogUtilsTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this 'public' modifier.

See more on https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&issues=AZ0-FyT6oxp4O0LdRY4o&open=AZ0-FyT6oxp4O0LdRY4o&pullRequest=17935
assertThrows(RuntimeException.class, () -> {
LogUtils.readPartFileContentFromLocal("/non/existent/file.log", 0, 5);
});
}

@Test
public void testReadPartFileContentFromTwoSpecificRollingFiles() {

Check warning on line 123 in dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/LogUtilsTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this 'public' modifier.

See more on https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&issues=AZ0-FyT6oxp4O0LdRY4p&open=AZ0-FyT6oxp4O0LdRY4p&pullRequest=17935
String resourcePath = "log/730.log";
URL resourceUrl = getClass().getClassLoader().getResource(resourcePath);

if (resourceUrl != null) {
String mainLogPath = resourceUrl.getPath().replace("%20", " ");

File mainLogFile = new File(mainLogPath);
File rollingLogFile = new File(mainLogPath + ".1");

assertTrue(mainLogFile.exists(), "Main log file (730.log) should exist");
assertTrue(rollingLogFile.exists(), "Rolling log file (730.log.1) should exist");

List<String> result = LogUtils.readPartFileContentFromLocal(mainLogPath, 0, 100);

assertNotNull(result);
assertTrue(result.size() > 0, "Should read content from both log files");

System.out.println("Total lines from both files (730.log and 730.log.1): " + result.size());
}
}

@Test
public void testGetFileContentBytesWithRollingLogs() {

Check warning on line 146 in dolphinscheduler-common/src/test/java/org/apache/dolphinscheduler/common/utils/LogUtilsTest.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Remove this 'public' modifier.

See more on https://sonarcloud.io/project/issues?id=apache-dolphinscheduler&issues=AZ0-FyT6oxp4O0LdRY4q&open=AZ0-FyT6oxp4O0LdRY4q&pullRequest=17935
String resourcePath = "log/730.log";
URL resourceUrl = getClass().getClassLoader().getResource(resourcePath);

if (resourceUrl != null) {
String mainLogPath = resourceUrl.getPath().replace("%20", " ");

File mainLogFile = new File(mainLogPath);
File rollingLogFile = new File(mainLogPath + ".1");

assertTrue(mainLogFile.exists(), "Main log file (730.log) should exist");
assertTrue(rollingLogFile.exists(), "Rolling log file (730.log.1) should exist");

byte[] result = LogUtils.getFileContentBytesWithRollingLogs(mainLogPath);

assertNotNull(result);
assertTrue(result.length > 0, "Should read bytes from both log files");

System.out.println("Total bytes from both files (730.log and 730.log.1): " + result.length);
}
}
}
Loading
Loading