feat(syslog): 为三个生产模块增加启动版本标识

- syslog-serve 增加 SYSLOG_BUILD_READY 启动日志
- syslog-consumer 增加 SYSLOG_BUILD_READY 启动日志
- 更新 syslog-consumer-rule 代码修订标识至 v63
- 输出模块名、代码修订号、运行环境及关键非敏感配置
- 支持通过容器日志快速确认实际部署的 JAR 版本
- 补充 syslog-serve 和 syslog-consumer 启动日志测试
- 不输出数据库密码、API 凭据等敏感信息
- 不修改 Maven POM 配置
This commit is contained in:
王绍宏
2026-09-17 18:47:25 +08:00
parent 8f1a8b6283
commit 2d297eb996
67 changed files with 3132 additions and 88 deletions
@@ -1,6 +1,7 @@
package com.haobang.apipull;
import com.common.mapper.DeviceCollectApiMapper;
import com.haobang.dispatch.DeviceContextResolver;
import com.haobang.apipull.persistence.DeviceCollectApiCheckpoint;
import com.haobang.apipull.persistence.DeviceCollectApiConfig;
import com.haobang.apipull.persistence.DeviceCollectApiRun;
@@ -31,6 +32,7 @@ public class ApiPullScheduler {
private final DeviceCollectApiMapper mapper;
private final ApiPullRunner runner;
private final SyslogWalService wal;
private final DeviceContextResolver deviceResolver;
private ExecutorService executor;
private Semaphore global;
private final ConcurrentHashMap<String, Semaphore> hosts = new ConcurrentHashMap<>();
@@ -40,11 +42,13 @@ public class ApiPullScheduler {
ApiPullProperties properties,
DeviceCollectApiMapper mapper,
ApiPullRunner runner,
SyslogWalService wal) {
SyslogWalService wal,
DeviceContextResolver deviceResolver) {
this.properties = properties;
this.mapper = mapper;
this.runner = runner;
this.wal = wal;
this.deviceResolver = deviceResolver;
}
@PostConstruct
@@ -110,6 +114,7 @@ public class ApiPullScheduler {
private DeviceCollectApiRun trySubmit(DeviceCollectApiConfig c, String trigger) {
if (!c.isEnabled()) return null;
if (!requireApiCollectionMode(c, "MANUAL".equals(trigger))) return null;
if (wal.getFatalFailure() != null || wal.isDiskCritical() || wal.shouldPauseTcp()) {
mapper.scheduleNext(c.getCollectTaskId(), c.getConfigVersion(), c.getPollIntervalSeconds());
return null;
@@ -167,7 +172,18 @@ public class ApiPullScheduler {
executor.execute(
() -> {
try {
runner.execute(c, leasedCheckpoint, run);
// 模式可能在排队期间变化;执行 HTTP 前再次校验,避免已提交线程绕过新策略。
if (requireApiCollectionMode(c, false)) {
runner.execute(c, leasedCheckpoint, run);
} else {
run.setStatus("FAILED");
run.setErrorCode("COLLECTION_MODE_DENIED");
run.setErrorSummary("设备采集模式不允许 API_PULL");
run.setFinishedAt(LocalDateTime.now(ApiPullTime.DATABASE_ZONE));
mapper.updateRun(run);
mapper.releaseLease(
c.getCollectTaskId(), properties.getInstanceId(), leasedCheckpoint.getFencingToken());
}
} finally {
releaseLocal(c.getCollectTaskId(), hostPermit);
}
@@ -188,6 +204,24 @@ public class ApiPullScheduler {
}
}
/**
* 调度扫描遇到禁止 API 的设备时推进 next_run_at,避免同一到期任务按 5 秒扫描周期空转。
*/
private boolean requireApiCollectionMode(DeviceCollectApiConfig c, boolean failRequest) {
DeviceContextResolver.Resolution resolution = deviceResolver.resolveDeviceId(c.getDeviceId());
if (resolution.isRegistered()) return true;
mapper.scheduleNext(c.getCollectTaskId(), c.getConfigVersion(), c.getPollIntervalSeconds());
String reason = resolution.getReason() == null ? "设备不允许 API_PULL" : resolution.getReason();
log.warn("设备 API 拉取已被设备策略跳过: taskId={}, deviceId={}, type={}, reason={}",
c.getCollectTaskId(), c.getDeviceId(), resolution.getType(), reason);
if (failRequest) {
String code = resolution.getType() == DeviceContextResolver.Type.COLLECTION_MODE_DENIED
? "COLLECTION_MODE_DENIED" : "DEVICE_CONTEXT_DENIED";
throw new ApiPullException(code, reason, org.springframework.http.HttpStatus.CONFLICT);
}
return false;
}
private void releaseLocal(Integer taskId, Semaphore host) {
if (host != null) host.release();
global.release();