Skip to content

Commit f9ec7f4

Browse files
authored
Merge pull request #4116 from wuyzh39/github_feat/zone
feat: 支持国际化时区 #3924
2 parents dadf234 + c868bf8 commit f9ec7f4

File tree

4 files changed

+231
-83
lines changed

4 files changed

+231
-83
lines changed

src/backend/job-logsvr/boot-job-logsvr/src/test/java/com/tencent/bk/job/logsvr/service/impl/LogServiceImplIntegrationTest.java

Lines changed: 96 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@
3232
import com.tencent.bk.job.logsvr.model.ScriptLogQuery;
3333
import com.tencent.bk.job.logsvr.model.ScriptTaskLogDoc;
3434
import com.tencent.bk.job.logsvr.model.TaskExecuteObjectLog;
35+
import com.tencent.bk.job.common.util.date.DateUtils;
36+
import com.tencent.bk.job.logsvr.model.service.FileTaskTimeAndRawLogDTO;
37+
import com.tencent.bk.job.logsvr.model.service.ServiceFileTaskLogDTO;
3538
import com.tencent.bk.job.logsvr.mongo.FileLogsCollectionLoader;
3639
import com.tencent.bk.job.logsvr.mongo.LogCollectionFactory;
3740
import com.tencent.bk.job.logsvr.mongo.LogCollectionLoaderFactory;
@@ -46,6 +49,8 @@
4649
import org.springframework.test.context.ActiveProfiles;
4750
import org.springframework.test.context.TestPropertySource;
4851

52+
import java.time.ZoneId;
53+
import java.time.temporal.ChronoUnit;
4954
import java.util.ArrayList;
5055
import java.util.Collections;
5156
import java.util.List;
@@ -294,6 +299,7 @@ void testSaveScriptLogV2() {
294299

295300
@Nested
296301
@DisplayName("测试保存文件分发日志")
302+
@SuppressWarnings("deprecation")
297303
class SaveFileLogTest {
298304

299305
@Test
@@ -357,10 +363,10 @@ void testSaveFileLog() {
357363
assertThat(resultFileTaskLog1.getSize()).isEqualTo("100MB");
358364
assertThat(resultFileTaskLog1.getSpeed()).isEqualTo("100KB/S");
359365
assertThat(resultFileTaskLog1.getProcess()).isEqualTo("50%");
360-
// 验证contentList包含1个map
361-
assertThat(resultFileTaskLog1.getContentList()).hasSize(1);
362-
assertThat(resultFileTaskLog1.getContentList().get(0)).isInstanceOf(Map.class);
363-
Map<String, Object> logEntry1 = (Map<String, Object>) resultFileTaskLog1.getContentList().get(0);
366+
// 验证timeLogList包含1条LogEntry(Map对象)
367+
assertThat(resultFileTaskLog1.getTimeLogList()).hasSize(1);
368+
assertThat(resultFileTaskLog1.getTimeLogList().get(0)).isInstanceOf(Map.class);
369+
Map<String, Object> logEntry1 = (Map<String, Object>) resultFileTaskLog1.getTimeLogList().get(0);
364370
assertThat(logEntry1.get("logTime")).isEqualTo(1596078000000L);
365371
assertThat(logEntry1.get("content")).isEqualTo("Downloading...\n");
366372

@@ -415,16 +421,14 @@ void testSaveFileLog() {
415421
assertThat(resultFileTaskLog1.getSize()).isEqualTo("100MB");
416422
assertThat(resultFileTaskLog1.getSpeed()).isEqualTo("0KB/S");
417423
assertThat(resultFileTaskLog1.getProcess()).isEqualTo("100%");
418-
// 验证contentList包含2个map
419-
assertThat(resultFileTaskLog1.getContentList()).hasSize(2);
424+
// 验证timeLogList包含2条LogEntry(Map对象)
425+
assertThat(resultFileTaskLog1.getTimeLogList()).hasSize(2);
420426
// 第1条
421-
assertThat(resultFileTaskLog1.getContentList().get(0)).isInstanceOf(Map.class);
422-
Map<String, Object> logEntry1Final = (Map<String, Object>) resultFileTaskLog1.getContentList().get(0);
427+
Map<String, Object> logEntry1Final = (Map<String, Object>) resultFileTaskLog1.getTimeLogList().get(0);
423428
assertThat(logEntry1Final.get("logTime")).isEqualTo(1596078000000L);
424429
assertThat(logEntry1Final.get("content")).isEqualTo("Downloading...\n");
425430
// 第2条
426-
assertThat(resultFileTaskLog1.getContentList().get(1)).isInstanceOf(Map.class);
427-
Map<String, Object> logEntry2 = (Map<String, Object>) resultFileTaskLog1.getContentList().get(1);
431+
Map<String, Object> logEntry2 = (Map<String, Object>) resultFileTaskLog1.getTimeLogList().get(1);
428432
assertThat(logEntry2.get("logTime")).isEqualTo(1596079800000L);
429433
assertThat(logEntry2.get("content")).isEqualTo("Download success\n");
430434
}
@@ -434,7 +438,8 @@ void testSaveFileLog() {
434438
void testCompatiblySaveFileLog() {
435439
long stepInstanceId = 2L;
436440

437-
// 第一次写入:使用老版本方式(只有content字段)
441+
// === 第一次写入:使用老版本方式(只有content字段) ===
442+
// 老 logsvr 只写 contentList(纯String),不写 timeLogList
438443
FileTaskLogDoc fileTaskLog1 = buildFileTaskDetailLog(
439444
FileTaskModeEnum.DOWNLOAD.getValue(),
440445
102L,
@@ -453,7 +458,7 @@ void testCompatiblySaveFileLog() {
453458
"100KB/S",
454459
"100MB",
455460
"50%");
456-
oldFileTaskLogAddContent(fileTaskLog1, "[2020-07-30 11:00:00] Downloading1...\n");
461+
oldFileTaskLogAddContent(fileTaskLog1, "[" + formatTime(1596078000000L) + "] Downloading1...\n");
457462

458463
List<FileTaskLogDoc> fileTaskLogList = new ArrayList<>();
459464
fileTaskLogList.add(fileTaskLog1);
@@ -486,12 +491,21 @@ void testCompatiblySaveFileLog() {
486491
assertThat(resultFileTaskLog1.getSize()).isEqualTo("100MB");
487492
assertThat(resultFileTaskLog1.getSpeed()).isEqualTo("100KB/S");
488493
assertThat(resultFileTaskLog1.getProcess()).isEqualTo("50%");
489-
// 验证contentList包含老格式数据(字符串
494+
// 验证contentList包含1条纯String(老版写入
490495
assertThat(resultFileTaskLog1.getContentList()).hasSize(1);
491-
assertThat(resultFileTaskLog1.getContentList().get(0)).isInstanceOf(String.class);
492-
assertThat(resultFileTaskLog1.getContentList().get(0)).isEqualTo("[2020-07-30 11:00:00] Downloading1...\n");
493-
494-
// 第二次写入:使用新版本方式(writeContentList字段,包含LogEntry对象)
496+
assertThat(resultFileTaskLog1.getContentList().get(0))
497+
.isEqualTo("[" + formatTime(1596078000000L) + "] Downloading1...\n");
498+
// 验证timeLogList为null(老版不写timeLogList)
499+
assertThat(resultFileTaskLog1.getTimeLogList()).isNull();
500+
// 验证 toServiceFileTaskLogDTO 兼容读取(timeLogList为空 → 降级使用contentList,time=null)
501+
ServiceFileTaskLogDTO serviceDTO1 = resultFileTaskLog1.toServiceFileTaskLogDTO();
502+
assertThat(serviceDTO1.getContentList()).hasSize(1);
503+
assertThat(serviceDTO1.getContentList().get(0).getTime()).isNull();
504+
assertThat(serviceDTO1.getContentList().get(0).getRawLog())
505+
.isEqualTo("[" + formatTime(1596078000000L) + "] Downloading1...\n");
506+
507+
// === 第二次写入:使用新版本方式(writeContentList字段,包含LogEntry对象) ===
508+
// 新 logsvr 同时写 timeLogList(LogEntry对象)和 contentList(拼接的纯String)
495509
fileTaskLog1 = buildFileTaskDetailLog(
496510
FileTaskModeEnum.DOWNLOAD.getValue(),
497511
102L,
@@ -510,9 +524,8 @@ void testCompatiblySaveFileLog() {
510524
"100KB/S",
511525
"100MB",
512526
"60%");
513-
// 设置writeContentList(新版本格式)
527+
// 设置writeContentList(新版本格式),timestamp=1596078180000L
514528
List<FileTaskLogDoc.LogEntry> writeContentList = new ArrayList<>();
515-
// 1596078180000L 对应 东八区时间 2020-07-30 11:03:00
516529
writeContentList.add(new FileTaskLogDoc.LogEntry(1596078180000L, "Downloading2...\n"));
517530
fillWriteList(fileTaskLog1, writeContentList);
518531

@@ -525,16 +538,31 @@ void testCompatiblySaveFileLog() {
525538
fileLogDocs = logService.listFileLogs(searchRequest);
526539
assertThat(fileLogDocs).hasSize(1);
527540
resultFileTaskLog1 = fileLogDocs.get(0);
528-
// 验证contentList包含2条数据:1条老格式(字符串)+ 1条新格式(LogEntry对象)
541+
// 验证contentList包含2条纯String:1条老版 + 1条新版拼接的
529542
assertThat(resultFileTaskLog1.getContentList()).hasSize(2);
530-
assertThat(resultFileTaskLog1.getContentList().get(0)).isInstanceOf(String.class);
531-
assertThat(resultFileTaskLog1.getContentList().get(0)).isEqualTo("[2020-07-30 11:00:00] Downloading1...\n");
532-
assertThat(resultFileTaskLog1.getContentList().get(1)).isInstanceOf(Map.class);
533-
Map<String, Object> logEntry = (Map<String, Object>) resultFileTaskLog1.getContentList().get(1);
543+
// 第1条:老版写入的纯String,原样保留
544+
assertThat(resultFileTaskLog1.getContentList().get(0))
545+
.isEqualTo("[" + formatTime(1596078000000L) + "] Downloading1...\n");
546+
// 第2条:新版写入时拼接的 "[timestamp转化后的时间] log" 格式(content自带换行符)
547+
assertThat(resultFileTaskLog1.getContentList().get(1))
548+
.isEqualTo("[" + formatTime(1596078180000L) + "] Downloading2...\n");
549+
// 验证timeLogList包含1条LogEntry(只有新版写入的那条)
550+
assertThat(resultFileTaskLog1.getTimeLogList()).hasSize(1);
551+
Map<String, Object> logEntry = (Map<String, Object>) resultFileTaskLog1.getTimeLogList().get(0);
534552
assertThat(logEntry.get("logTime")).isEqualTo(1596078180000L);
535553
assertThat(logEntry.get("content")).isEqualTo("Downloading2...\n");
536-
537-
// 第三次写入:再次使用老版本方式(只有content字段)
554+
// 验证 toServiceFileTaskLogDTO 兼容读取
555+
// timeLogList.size(1) != contentList.size(2) → 降级使用contentList,所有time=null
556+
ServiceFileTaskLogDTO serviceDTO2 = resultFileTaskLog1.toServiceFileTaskLogDTO();
557+
assertThat(serviceDTO2.getContentList()).hasSize(2);
558+
assertThat(serviceDTO2.getContentList().get(0).getTime()).isNull();
559+
assertThat(serviceDTO2.getContentList().get(0).getRawLog())
560+
.isEqualTo("[" + formatTime(1596078000000L) + "] Downloading1...\n");
561+
assertThat(serviceDTO2.getContentList().get(1).getTime()).isNull();
562+
assertThat(serviceDTO2.getContentList().get(1).getRawLog())
563+
.isEqualTo("[" + formatTime(1596078180000L) + "] Downloading2...\n");
564+
565+
// === 第三次写入:再次使用老版本方式(只有content字段) ===
538566
fileTaskLog1 = buildFileTaskDetailLog(
539567
FileTaskModeEnum.DOWNLOAD.getValue(),
540568
102L,
@@ -553,7 +581,7 @@ void testCompatiblySaveFileLog() {
553581
"0KB/S",
554582
"100MB",
555583
"100%");
556-
oldFileTaskLogAddContent(fileTaskLog1, "[2020-07-30 11:30:00] Downloading3...\n");
584+
oldFileTaskLogAddContent(fileTaskLog1, "[" + formatTime(1596079800000L) + "] Downloading3...\n");
557585

558586
fileTaskLogList.clear();
559587
fileTaskLogList.add(fileTaskLog1);
@@ -581,19 +609,38 @@ void testCompatiblySaveFileLog() {
581609
assertThat(resultFileTaskLog1.getSpeed()).isEqualTo("0KB/S");
582610
assertThat(resultFileTaskLog1.getProcess()).isEqualTo("100%");
583611

584-
// 验证contentList包含3条数据:老格式 + 新格式 + 老格式
612+
// 验证contentList包含3条纯String:老格式 + 新格式拼接的 + 老格式
585613
assertThat(resultFileTaskLog1.getContentList()).hasSize(3);
586-
// 第1条:老格式(字符串)
587-
assertThat(resultFileTaskLog1.getContentList().get(0)).isInstanceOf(String.class);
588-
assertThat(resultFileTaskLog1.getContentList().get(0)).isEqualTo("[2020-07-30 11:00:00] Downloading1...\n");
589-
// 第2条:新格式(LogEntry对象)
590-
assertThat(resultFileTaskLog1.getContentList().get(1)).isInstanceOf(Map.class);
591-
Map<String, Object> logEntry2 = (Map<String, Object>) resultFileTaskLog1.getContentList().get(1);
614+
// 第1条:老版写入的 "[时间] 日志" 格式
615+
assertThat(resultFileTaskLog1.getContentList().get(0))
616+
.isEqualTo("[" + formatTime(1596078000000L) + "] Downloading1...\n");
617+
// 第2条:新版写入时 timestamp 转化后拼接的 "[时间] 日志" 格式(content自带换行符)
618+
assertThat(resultFileTaskLog1.getContentList().get(1))
619+
.isEqualTo("[" + formatTime(1596078180000L) + "] Downloading2...\n");
620+
// 第3条:老版写入的 "[时间] 日志" 格式
621+
assertThat(resultFileTaskLog1.getContentList().get(2))
622+
.isEqualTo("[" + formatTime(1596079800000L) + "] Downloading3...\n");
623+
624+
// 验证timeLogList只包含1条(只有第二次新版写入时才push到timeLogList)
625+
assertThat(resultFileTaskLog1.getTimeLogList()).hasSize(1);
626+
@SuppressWarnings("unchecked")
627+
Map<String, Object> logEntry2 = (Map<String, Object>) resultFileTaskLog1.getTimeLogList().get(0);
592628
assertThat(logEntry2.get("logTime")).isEqualTo(1596078180000L);
593629
assertThat(logEntry2.get("content")).isEqualTo("Downloading2...\n");
594-
// 第3条:老格式(字符串)
595-
assertThat(resultFileTaskLog1.getContentList().get(2)).isInstanceOf(String.class);
596-
assertThat(resultFileTaskLog1.getContentList().get(2)).isEqualTo("[2020-07-30 11:30:00] Downloading3...\n");
630+
631+
// 验证 toServiceFileTaskLogDTO 兼容读取
632+
// timeLogList.size(1) != contentList.size(3) → 降级使用contentList,所有time=null
633+
ServiceFileTaskLogDTO serviceDTO3 = resultFileTaskLog1.toServiceFileTaskLogDTO();
634+
assertThat(serviceDTO3.getContentList()).hasSize(3);
635+
for (FileTaskTimeAndRawLogDTO item : serviceDTO3.getContentList()) {
636+
assertThat(item.getTime()).isNull();
637+
}
638+
assertThat(serviceDTO3.getContentList().get(0).getRawLog())
639+
.isEqualTo("[" + formatTime(1596078000000L) + "] Downloading1...\n");
640+
assertThat(serviceDTO3.getContentList().get(1).getRawLog())
641+
.isEqualTo("[" + formatTime(1596078180000L) + "] Downloading2...\n");
642+
assertThat(serviceDTO3.getContentList().get(2).getRawLog())
643+
.isEqualTo("[" + formatTime(1596079800000L) + "] Downloading3...\n");
597644
}
598645
}
599646

@@ -630,6 +677,18 @@ void fillWriteList(FileTaskLogDoc doc, List<FileTaskLogDoc.LogEntry> writeConten
630677
doc.setWriteContentList(writeContentList);
631678
}
632679

680+
/**
681+
* 使用系统默认时区将时间戳格式化为时间字符串,与 pushFileTaskLogContentCompatibly 逻辑一致
682+
*/
683+
private String formatTime(long timestampMillis) {
684+
return DateUtils.formatUnixTimestamp(
685+
timestampMillis,
686+
ChronoUnit.MILLIS,
687+
DateUtils.FILE_TASK_LOG_FORMAT,
688+
ZoneId.systemDefault()
689+
);
690+
}
691+
633692
FileTaskLogDoc buildFileTaskDetailLog(Integer mode,
634693
Long hostId,
635694
Long srcHostId,

0 commit comments

Comments
 (0)