From 5a86a4f9504e3400e0a7152e2207191e399530f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E7=BB=8D=E5=AE=8F?= <994233303@qq.com> Date: Tue, 15 Sep 2026 13:14:24 +0800 Subject: [PATCH] =?UTF-8?q?fix(syslog-consumer):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E7=AE=97=E6=B3=95=E6=89=B9=E6=AC=A1=E5=BA=8F=E5=8F=B7=E6=97=A0?= =?UTF-8?q?=E6=B3=95=E9=80=92=E5=A2=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 兼容 yyyyMMdd_NNNN-algorithmId 批次号格式 - 仅解析日期后的批次序号,忽略算法 ID 后缀 - 同一轮任务的所有算法共享同一批次序号 - 保持算法 ID 后缀用于区分算法处理记录 - 补充普通、长算法 ID 及异常格式测试 --- .../common/service/AccessLogAlertService.java | 45 +++++++++++++++---- .../AccessLogAlertServiceBatchNoTest.java | 40 +++++++++++++++++ 2 files changed, 76 insertions(+), 9 deletions(-) create mode 100644 haobang-security-dm/syslog-consumer/src/test/java/com/common/service/AccessLogAlertServiceBatchNoTest.java diff --git a/haobang-security-dm/syslog-consumer/src/main/java/com/common/service/AccessLogAlertService.java b/haobang-security-dm/syslog-consumer/src/main/java/com/common/service/AccessLogAlertService.java index 7353a6a..1ccec5a 100644 --- a/haobang-security-dm/syslog-consumer/src/main/java/com/common/service/AccessLogAlertService.java +++ b/haobang-security-dm/syslog-consumer/src/main/java/com/common/service/AccessLogAlertService.java @@ -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(); + } + } + diff --git a/haobang-security-dm/syslog-consumer/src/test/java/com/common/service/AccessLogAlertServiceBatchNoTest.java b/haobang-security-dm/syslog-consumer/src/test/java/com/common/service/AccessLogAlertServiceBatchNoTest.java new file mode 100644 index 0000000..a817add --- /dev/null +++ b/haobang-security-dm/syslog-consumer/src/test/java/com/common/service/AccessLogAlertServiceBatchNoTest.java @@ -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()); + } +}