Skip to content

Commit 254d9cb

Browse files
committed
Improve volume upload summary logs
1 parent 0df310f commit 254d9cb

1 file changed

Lines changed: 71 additions & 27 deletions

File tree

sdk-bulkwriter/src/main/java/io/milvus/bulkwriter/VolumeFileManager.java

Lines changed: 71 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import java.util.HashMap;
4545
import java.util.HashSet;
4646
import java.util.List;
47+
import java.util.Locale;
4748
import java.util.Map;
4849
import java.util.Set;
4950
import java.util.concurrent.*;
@@ -79,20 +80,29 @@ public CompletableFuture<UploadFilesResult> uploadFilesAsync(UploadFilesRequest
7980
String localDirOrFilePath = request.getSourceFilePath();
8081
Pair<List<String>, Long> localPathPair = FileUtils.processLocalPath(localDirOrFilePath);
8182
String volumePath = convertDirPath(request.getTargetVolumePath());
82-
83-
UploadContext uploadContext = new UploadContext(refreshVolumeAndClient(volumePath));
84-
VolumeSession initialSession = uploadContext.currentSession();
85-
initValidator(localPathPair, initialSession.applyVolumeResponse);
8683
int uploadConcurrency = Math.max(1, request.getUploadConcurrency());
8784
int maxRetries = Math.max(1, request.getMaxRetries());
8885
long retryIntervalMillis = Math.max(0L, request.getRetryIntervalMillis());
8986
long partSizeBytes = Math.max(0L, request.getPartSizeBytes());
90-
ExecutorService uploadExecutor = Executors.newFixedThreadPool(uploadConcurrency);
91-
9287
long totalBytes = localPathPair.getValue();
9388
long totalFilesCount = localPathPair.getKey().size();
94-
UploadProgressTracker progressTracker = new UploadProgressTracker(totalBytes, totalFilesCount, request.getProgressListener());
9589
long startTime = System.currentTimeMillis();
90+
logger.info("Starting volume upload: sourcePath:{}, volumeName:{}, volumePath:{}, totalFileCount:{}, totalFileSize:{} bytes ({}), uploadConcurrency:{}, maxRetries:{}, retryInterval:{}, partSize:{}, startTime:{}",
91+
localDirOrFilePath, volumeName, volumePath, totalFilesCount, totalBytes, formatBytes(totalBytes),
92+
uploadConcurrency, maxRetries, formatDurationMillis(retryIntervalMillis),
93+
formatPartSize(partSizeBytes), Instant.ofEpochMilli(startTime));
94+
95+
UploadContext uploadContext;
96+
try {
97+
uploadContext = new UploadContext(refreshVolumeAndClient(volumePath));
98+
VolumeSession initialSession = uploadContext.currentSession();
99+
initValidator(localPathPair, initialSession.applyVolumeResponse);
100+
} catch (RuntimeException e) {
101+
logUploadFailed(localDirOrFilePath, volumePath, startTime);
102+
throw e;
103+
}
104+
ExecutorService uploadExecutor = Executors.newFixedThreadPool(uploadConcurrency);
105+
UploadProgressTracker progressTracker = new UploadProgressTracker(totalBytes, totalFilesCount, request.getProgressListener());
96106

97107
return CompletableFuture.allOf(localPathPair.getKey().stream()
98108
.map(localFilePath -> CompletableFuture.runAsync(() -> {
@@ -114,13 +124,19 @@ public CompletableFuture<UploadFilesResult> uploadFilesAsync(UploadFilesRequest
114124
}, uploadExecutor)).toArray(CompletableFuture[]::new))
115125
.whenComplete((v, t) -> {
116126
uploadExecutor.shutdown();
127+
if (t != null) {
128+
logUploadFailed(localDirOrFilePath, volumePath, startTime);
129+
}
117130
})
118131
.thenApply(v -> {
119132
progressTracker.finishUpload();
120-
long totalElapsed = (System.currentTimeMillis() - startTime) / 1000;
133+
long endTime = System.currentTimeMillis();
134+
long totalElapsed = endTime - startTime;
121135
VolumeSession session = uploadContext.currentSession();
122-
logger.info("all files in {} has been async uploaded to volume, volumeName:{}, volumePath:{}, totalFileCount:{}, totalFileSize:{}, cost times:{} s",
123-
localDirOrFilePath, session.applyVolumeResponse.getVolumeName(), volumePath, localPathPair.getKey().size(), localPathPair.getValue(), totalElapsed);
136+
logger.info("Volume upload completed: sourcePath:{}, volumeName:{}, volumePath:{}, totalFileCount:{}, totalFileSize:{} bytes ({}), endTime:{}, totalElapsed:{}",
137+
localDirOrFilePath, session.applyVolumeResponse.getVolumeName(), volumePath,
138+
localPathPair.getKey().size(), localPathPair.getValue(), formatBytes(localPathPair.getValue()),
139+
Instant.ofEpochMilli(endTime), formatDurationMillis(totalElapsed));
124140
return UploadFilesResult.builder()
125141
.volumeName(session.applyVolumeResponse.getVolumeName())
126142
.path(volumePath)
@@ -141,6 +157,51 @@ public UploadFilesResult uploadFiles(UploadFilesRequest request) throws Executio
141157
public void shutdownGracefully() {
142158
}
143159

160+
private void logUploadFailed(String localDirOrFilePath, String volumePath, long startTime) {
161+
long endTime = System.currentTimeMillis();
162+
logger.warn("Volume upload failed: sourcePath:{}, volumeName:{}, volumePath:{}, endTime:{}, totalElapsed:{}",
163+
localDirOrFilePath, volumeName, volumePath,
164+
Instant.ofEpochMilli(endTime), formatDurationMillis(endTime - startTime));
165+
}
166+
167+
private static String formatPartSize(long partSizeBytes) {
168+
if (partSizeBytes <= 0L) {
169+
return "auto";
170+
}
171+
return partSizeBytes + " bytes (" + formatBytes(partSizeBytes) + ")";
172+
}
173+
174+
private static String formatBytes(long bytes) {
175+
if (bytes < 1024L) {
176+
return bytes + " B";
177+
}
178+
double value = bytes;
179+
String[] units = new String[]{"B", "KiB", "MiB", "GiB", "TiB", "PiB"};
180+
int unitIndex = 0;
181+
while (value >= 1024.0 && unitIndex < units.length - 1) {
182+
value /= 1024.0;
183+
unitIndex++;
184+
}
185+
return String.format(Locale.ROOT, "%.2f %s", value, units[unitIndex]);
186+
}
187+
188+
private static String formatDurationMillis(long durationMillis) {
189+
if (durationMillis < 0L) {
190+
return "unknown";
191+
}
192+
long totalSeconds = (durationMillis + 999L) / 1000L;
193+
long hours = totalSeconds / 3600L;
194+
long minutes = (totalSeconds % 3600L) / 60L;
195+
long seconds = totalSeconds % 60L;
196+
if (hours > 0L) {
197+
return String.format(Locale.ROOT, "%dh %02dm %02ds", hours, minutes, seconds);
198+
}
199+
if (minutes > 0L) {
200+
return String.format(Locale.ROOT, "%dm %02ds", minutes, seconds);
201+
}
202+
return String.format(Locale.ROOT, "%ds", seconds);
203+
}
204+
144205
private void initValidator(Pair<List<String>, Long> localPathPair, ApplyVolumeResponse applyVolumeResponse) {
145206
Long maxContentLength = applyVolumeResponse.getCondition().getMaxContentLength();
146207
Long uploadFileContentLength = localPathPair.getValue();
@@ -459,23 +520,6 @@ private long estimatedRemainingTimeMillis(long currentUploadedBytes, long speedB
459520
return (long) Math.ceil(remainingBytes * 1000.0 / speedBps);
460521
}
461522

462-
private String formatDurationMillis(long durationMillis) {
463-
if (durationMillis < 0L) {
464-
return "unknown";
465-
}
466-
long totalSeconds = (durationMillis + 999L) / 1000L;
467-
long hours = totalSeconds / 3600L;
468-
long minutes = (totalSeconds % 3600L) / 60L;
469-
long seconds = totalSeconds % 60L;
470-
if (hours > 0L) {
471-
return String.format("%dh %02dm %02ds", hours, minutes, seconds);
472-
}
473-
if (minutes > 0L) {
474-
return String.format("%dm %02ds", minutes, seconds);
475-
}
476-
return String.format("%ds", seconds);
477-
}
478-
479523
private UploadProgress progressIfNeeded(String currentFile, long currentFileUploadedBytes, long currentFileTotalBytes) {
480524
long now = System.currentTimeMillis();
481525
double percent = percent();

0 commit comments

Comments
 (0)