mirror of
https://github.com/dromara/hertzbeat.git
synced 2026-09-17 09:40:58 +00:00
[fix] keep monitor instance identity stable across edits (#4329)
This commit is contained in:
+30
-24
@@ -138,6 +138,34 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
@Autowired
|
||||
private MetricsFavoriteService metricsFavoriteService;
|
||||
|
||||
/**
|
||||
* Idempotent: an instance already carrying a port is left untouched, so repeated
|
||||
* edits cannot grow it (host:443:443...). A missing instance falls back to the
|
||||
* host param - never concatenated onto null, which produced "null:443" identities.
|
||||
*/
|
||||
private void resolveMonitorInstance(Monitor monitor, List<Param> params) {
|
||||
String instance = monitor.getInstance();
|
||||
if (!StringUtils.hasText(instance)) {
|
||||
instance = params.stream()
|
||||
.filter(param -> "host".equals(param.getField()))
|
||||
.map(Param::getParamValue)
|
||||
.filter(StringUtils::hasText)
|
||||
.findFirst()
|
||||
.orElse(StringUtils.hasText(monitor.getName()) ? monitor.getName() : "unknown");
|
||||
}
|
||||
Param portParam = params.stream()
|
||||
.filter(param -> PARAM_FIELD_PORT.equals(param.getField()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
String portWithMark = (Objects.isNull(portParam) || !StringUtils.hasText(portParam.getParamValue()))
|
||||
? ""
|
||||
: SignConstants.DOUBLE_MARK + portParam.getParamValue();
|
||||
if (!IpDomainUtil.isHasPortWithMark(instance)) {
|
||||
instance = instance + portWithMark;
|
||||
}
|
||||
monitor.setInstance(instance);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public void detectMonitor(Monitor monitor, List<Param> params, String collector) throws MonitorDetectException {
|
||||
@@ -184,19 +212,8 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
appDefine.setScheduleType(monitor.getScheduleType());
|
||||
appDefine.setCronExpression(monitor.getCronExpression());
|
||||
|
||||
resolveMonitorInstance(monitor, params);
|
||||
String instance = monitor.getInstance();
|
||||
// The port field may be null
|
||||
Param portParam = params.stream()
|
||||
.filter(param -> PARAM_FIELD_PORT.equals(param.getField()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
String portWithMark = (Objects.isNull(portParam) || !StringUtils.hasText(portParam.getParamValue()))
|
||||
? ""
|
||||
: SignConstants.DOUBLE_MARK + portParam.getParamValue();
|
||||
if (!IpDomainUtil.isHasPortWithMark(instance)) {
|
||||
instance = instance + portWithMark;
|
||||
}
|
||||
monitor.setInstance(instance);
|
||||
|
||||
Map<String, String> metadata = Map.of(CommonConstants.LABEL_INSTANCE_NAME, monitor.getName(),
|
||||
CommonConstants.LABEL_INSTANCE, instance);
|
||||
@@ -384,19 +401,8 @@ public class MonitorServiceImpl implements MonitorService {
|
||||
labelDao.saveAll(addLabels);
|
||||
}
|
||||
|
||||
resolveMonitorInstance(monitor, params);
|
||||
String instance = monitor.getInstance();
|
||||
// The port field may be null
|
||||
Param portParam = params.stream()
|
||||
.filter(param -> PARAM_FIELD_PORT.equals(param.getField()))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
String portWithMark = (Objects.isNull(portParam) || !StringUtils.hasText(portParam.getParamValue()))
|
||||
? ""
|
||||
: SignConstants.DOUBLE_MARK + portParam.getParamValue();
|
||||
if (Objects.nonNull(instance)) {
|
||||
instance = instance + portWithMark;
|
||||
}
|
||||
monitor.setInstance(instance);
|
||||
|
||||
boolean isStatic = CommonConstants.SCRAPE_STATIC.equals(monitor.getScrape())
|
||||
|| !StringUtils.hasText(monitor.getScrape());
|
||||
|
||||
+53
@@ -225,6 +225,59 @@ class MonitorServiceTest {
|
||||
assertDoesNotThrow(() -> monitorService.addMonitor(monitor, params, null, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
void addMonitorWithoutInstanceFallsBackToHostParam() {
|
||||
Monitor monitor = Monitor.builder()
|
||||
.intervals(1)
|
||||
.name("memory")
|
||||
.app("demoApp")
|
||||
.build();
|
||||
Job job = new Job();
|
||||
when(appService.getAppDefine(monitor.getApp())).thenReturn(job);
|
||||
when(collectJobScheduling.addAsyncCollectJob(job, null)).thenReturn(1L);
|
||||
when(monitorDao.save(monitor)).thenReturn(monitor);
|
||||
List<Param> params = List.of(
|
||||
Param.builder().field("host").paramValue("www.example.com").build(),
|
||||
Param.builder().field("port").paramValue("443").build());
|
||||
when(paramDao.saveAll(params)).thenReturn(params);
|
||||
assertDoesNotThrow(() -> monitorService.addMonitor(monitor, params, null, null));
|
||||
assertEquals("www.example.com:443", monitor.getInstance());
|
||||
}
|
||||
|
||||
@Test
|
||||
void addMonitorInstanceStaysStableAcrossRepeatedResolution() {
|
||||
Monitor monitor = Monitor.builder()
|
||||
.intervals(1)
|
||||
.name("memory")
|
||||
.app("demoApp")
|
||||
.instance("www.example.com:443")
|
||||
.build();
|
||||
Job job = new Job();
|
||||
when(appService.getAppDefine(monitor.getApp())).thenReturn(job);
|
||||
when(collectJobScheduling.addAsyncCollectJob(job, null)).thenReturn(1L);
|
||||
when(monitorDao.save(monitor)).thenReturn(monitor);
|
||||
List<Param> params = List.of(Param.builder().field("port").paramValue("443").build());
|
||||
when(paramDao.saveAll(params)).thenReturn(params);
|
||||
assertDoesNotThrow(() -> monitorService.addMonitor(monitor, params, null, null));
|
||||
assertEquals("www.example.com:443", monitor.getInstance());
|
||||
}
|
||||
|
||||
@Test
|
||||
void modifyMonitorKeepsInstanceStableAcrossEdits() {
|
||||
long monitorId = 7L;
|
||||
Monitor stored = Monitor.builder().jobId(1L).intervals(1).app("demoApp").name("ssl")
|
||||
.instance("www.example.com:443").id(monitorId).build();
|
||||
when(monitorDao.findById(monitorId)).thenReturn(Optional.of(stored));
|
||||
List<Param> params = List.of(Param.builder().field("port").paramValue("443").build());
|
||||
|
||||
for (int edit = 0; edit < 2; edit++) {
|
||||
Monitor dto = Monitor.builder().jobId(1L).intervals(1).app("demoApp").name("ssl")
|
||||
.instance("www.example.com:443").id(monitorId).build();
|
||||
assertDoesNotThrow(() -> monitorService.modifyMonitor(dto, params, null, null));
|
||||
assertEquals("www.example.com:443", dto.getInstance());
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void addMonitorException() {
|
||||
Monitor monitor = Monitor.builder()
|
||||
|
||||
Reference in New Issue
Block a user