fix(syslog-consumer): 修复算法批次序号无法递增
- 兼容 yyyyMMdd_NNNN-algorithmId 批次号格式 - 仅解析日期后的批次序号,忽略算法 ID 后缀 - 同一轮任务的所有算法共享同一批次序号 - 保持算法 ID 后缀用于区分算法处理记录 - 补充普通、长算法 ID 及异常格式测试
This commit is contained in:
+35
-8
@@ -151,6 +151,8 @@ public class AccessLogAlertService {
|
|||||||
|
|
||||||
LocalDateTime currentTime = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES);
|
LocalDateTime currentTime = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES);
|
||||||
int pageSize = Math.min(Math.max(algorithmPageSize, 100), 2000);
|
int pageSize = Math.min(Math.max(algorithmPageSize, 100), 2000);
|
||||||
|
// 同一轮任务共享当天序号,算法 ID 仅作为后缀区分各算法审计记录。
|
||||||
|
String taskBatchNo = generateBatchNo();
|
||||||
for (SecExceptionAlgorithm algorithm : algorithmCache.values()) {
|
for (SecExceptionAlgorithm algorithm : algorithmCache.values()) {
|
||||||
String algorithmId = String.valueOf(algorithm.getId());
|
String algorithmId = String.valueOf(algorithm.getId());
|
||||||
String version = algorithm.getUpdateTime() == null ? "legacy" : algorithm.getUpdateTime().toString();
|
String version = algorithm.getUpdateTime() == null ? "legacy" : algorithm.getUpdateTime().toString();
|
||||||
@@ -177,7 +179,7 @@ public class AccessLogAlertService {
|
|||||||
cursorId = last.getId();
|
cursorId = last.getId();
|
||||||
if (page.size() < pageSize) break;
|
if (page.size() < pageSize) break;
|
||||||
}
|
}
|
||||||
String batchNo = generateBatchNo() + "-" + algorithmId;
|
String batchNo = taskBatchNo + "-" + algorithmId;
|
||||||
alarmVisitProcesslogMapper.insert(AlarmVisitProcesslog.builder().batchNo(batchNo)
|
alarmVisitProcesslogMapper.insert(AlarmVisitProcesslog.builder().batchNo(batchNo)
|
||||||
.logCount(totalInput).startTime(windowStart).endTime(currentTime).build());
|
.logCount(totalInput).startTime(windowStart).endTime(currentTime).build());
|
||||||
// [SYSLOG-ALARM][ALGOCP][已修复] API、响应解析、告警写入和审计全部成功后才推进该算法独立水位。
|
// [SYSLOG-ALARM][ALGOCP][已修复] API、响应解析、告警写入和审计全部成功后才推进该算法独立水位。
|
||||||
@@ -562,19 +564,44 @@ public class AccessLogAlertService {
|
|||||||
|
|
||||||
int seq = 1;
|
int seq = 1;
|
||||||
if (maxBatchNo != null && !maxBatchNo.isEmpty()) {
|
if (maxBatchNo != null && !maxBatchNo.isEmpty()) {
|
||||||
// batch_no 格式: yyyyMMdd_XXXX,解析序号部分
|
OptionalInt nextSequence = parseNextBatchSequence(maxBatchNo);
|
||||||
int underscoreIdx = maxBatchNo.lastIndexOf('_');
|
if (nextSequence.isPresent()) {
|
||||||
if (underscoreIdx >= 0 && underscoreIdx < maxBatchNo.length() - 1) {
|
seq = nextSequence.getAsInt();
|
||||||
try {
|
} else {
|
||||||
seq = Integer.parseInt(maxBatchNo.substring(underscoreIdx + 1)) + 1;
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
log.warn("解析批次序号失败: {}, 使用默认序号1", maxBatchNo);
|
log.warn("解析批次序号失败: {}, 使用默认序号1", maxBatchNo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return todayPrefix + "_" + String.format("%04d", seq);
|
return todayPrefix + "_" + String.format("%04d", seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析当前最大批次号并返回下一个序号。
|
||||||
|
* 支持 yyyyMMdd_NNNN 和算法任务实际写入的 yyyyMMdd_NNNN-algorithmId 两种格式。
|
||||||
|
*/
|
||||||
|
static OptionalInt parseNextBatchSequence(String batchNo) {
|
||||||
|
if (batchNo == null || batchNo.isEmpty()) {
|
||||||
|
return OptionalInt.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
int underscoreIdx = batchNo.lastIndexOf('_');
|
||||||
|
if (underscoreIdx < 0 || underscoreIdx == batchNo.length() - 1) {
|
||||||
|
return OptionalInt.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
int suffixIdx = batchNo.indexOf('-', underscoreIdx + 1);
|
||||||
|
int sequenceEndIdx = suffixIdx >= 0 ? suffixIdx : batchNo.length();
|
||||||
|
if (sequenceEndIdx == underscoreIdx + 1) {
|
||||||
|
return OptionalInt.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return OptionalInt.of(Integer.parseInt(
|
||||||
|
batchNo.substring(underscoreIdx + 1, sequenceEndIdx)) + 1);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
return OptionalInt.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
package com.common.service;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.OptionalInt;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||||
|
|
||||||
|
class AccessLogAlertServiceBatchNoTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void parsesBatchNumberWithAlgorithmSuffix() {
|
||||||
|
OptionalInt nextSequence = AccessLogAlertService.parseNextBatchSequence("20260915_0001-9");
|
||||||
|
|
||||||
|
assertEquals(2, nextSequence.getAsInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void parsesBatchNumberWithLongAlgorithmSuffixFromProduction() {
|
||||||
|
OptionalInt nextSequence = AccessLogAlertService.parseNextBatchSequence(
|
||||||
|
"20260915_0001-2092817404786315266");
|
||||||
|
|
||||||
|
assertEquals(2, nextSequence.getAsInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void parsesLegacyBatchNumberWithoutAlgorithmSuffix() {
|
||||||
|
OptionalInt nextSequence = AccessLogAlertService.parseNextBatchSequence("20260915_0099");
|
||||||
|
|
||||||
|
assertEquals(100, nextSequence.getAsInt());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void rejectsMalformedBatchNumbers() {
|
||||||
|
assertFalse(AccessLogAlertService.parseNextBatchSequence("202609150001-9").isPresent());
|
||||||
|
assertFalse(AccessLogAlertService.parseNextBatchSequence("20260915_abcd-9").isPresent());
|
||||||
|
assertFalse(AccessLogAlertService.parseNextBatchSequence("20260915_-9").isPresent());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user