fix(syslog-consumer): 修复算法批次序号无法递增

- 兼容 yyyyMMdd_NNNN-algorithmId 批次号格式
- 仅解析日期后的批次序号,忽略算法 ID 后缀
- 同一轮任务的所有算法共享同一批次序号
- 保持算法 ID 后缀用于区分算法处理记录
- 补充普通、长算法 ID 及异常格式测试
This commit is contained in:
王绍宏
2026-09-15 13:14:24 +08:00
parent 668a0aca88
commit 5a86a4f950
2 changed files with 76 additions and 9 deletions
@@ -151,6 +151,8 @@ public class AccessLogAlertService {
LocalDateTime currentTime = LocalDateTime.now().truncatedTo(ChronoUnit.MINUTES);
int pageSize = Math.min(Math.max(algorithmPageSize, 100), 2000);
// 同一轮任务共享当天序号,算法 ID 仅作为后缀区分各算法审计记录。
String taskBatchNo = generateBatchNo();
for (SecExceptionAlgorithm algorithm : algorithmCache.values()) {
String algorithmId = String.valueOf(algorithm.getId());
String version = algorithm.getUpdateTime() == null ? "legacy" : algorithm.getUpdateTime().toString();
@@ -177,7 +179,7 @@ public class AccessLogAlertService {
cursorId = last.getId();
if (page.size() < pageSize) break;
}
String batchNo = generateBatchNo() + "-" + algorithmId;
String batchNo = taskBatchNo + "-" + algorithmId;
alarmVisitProcesslogMapper.insert(AlarmVisitProcesslog.builder().batchNo(batchNo)
.logCount(totalInput).startTime(windowStart).endTime(currentTime).build());
// [SYSLOG-ALARM][ALGOCP][已修复] API、响应解析、告警写入和审计全部成功后才推进该算法独立水位。
@@ -562,19 +564,44 @@ public class AccessLogAlertService {
int seq = 1;
if (maxBatchNo != null && !maxBatchNo.isEmpty()) {
// batch_no 格式: yyyyMMdd_XXXX,解析序号部分
int underscoreIdx = maxBatchNo.lastIndexOf('_');
if (underscoreIdx >= 0 && underscoreIdx < maxBatchNo.length() - 1) {
try {
seq = Integer.parseInt(maxBatchNo.substring(underscoreIdx + 1)) + 1;
} catch (NumberFormatException e) {
log.warn("解析批次序号失败: {}, 使用默认序号1", maxBatchNo);
}
OptionalInt nextSequence = parseNextBatchSequence(maxBatchNo);
if (nextSequence.isPresent()) {
seq = nextSequence.getAsInt();
} else {
log.warn("解析批次序号失败: {}, 使用默认序号1", maxBatchNo);
}
}
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();
}
}
@@ -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());
}
}