mirror of
https://github.com/dromara/hertzbeat.git
synced 2026-09-17 09:40:58 +00:00
[fix] fix cyclic silence time matching and cross-midnight handling (#4081)
Co-authored-by: yunfan24 <yunfan24@outlook.com> Co-authored-by: Tomsun28 <tomsun28@outlook.com>
This commit is contained in:
co-authored by
yunfan24
Tomsun28
parent
b9e07d81f9
commit
a4d2630320
+30
-4
@@ -18,6 +18,7 @@
|
||||
package org.apache.hertzbeat.alert.reduce;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -95,10 +96,35 @@ public class AlarmSilenceReduce {
|
||||
* @return true if alert should not be silenced, false if alert should be silenced
|
||||
*/
|
||||
private boolean checkAndSave(LocalDateTime now, AlertSilence alertSilence) {
|
||||
boolean startMatch = alertSilence.getPeriodStart() == null
|
||||
|| now.isAfter(alertSilence.getPeriodStart().toLocalDateTime());
|
||||
boolean endMatch = alertSilence.getPeriodEnd() == null
|
||||
|| now.isBefore(alertSilence.getPeriodEnd().toLocalDateTime());
|
||||
boolean startMatch;
|
||||
boolean endMatch;
|
||||
if (alertSilence.getType() == 1) {
|
||||
LocalTime nowTime = now.toLocalTime();
|
||||
LocalTime startTime = alertSilence.getPeriodStart() == null ? null : alertSilence.getPeriodStart().toLocalTime();
|
||||
LocalTime endTime = alertSilence.getPeriodEnd() == null ? null : alertSilence.getPeriodEnd().toLocalTime();
|
||||
if (startTime == null && endTime == null) {
|
||||
startMatch = true;
|
||||
endMatch = true;
|
||||
} else if (startTime == null) {
|
||||
startMatch = true;
|
||||
endMatch = !nowTime.isAfter(endTime);
|
||||
} else if (endTime == null) {
|
||||
startMatch = !nowTime.isBefore(startTime);
|
||||
endMatch = true;
|
||||
} else if (!startTime.isAfter(endTime)) {
|
||||
startMatch = !nowTime.isBefore(startTime);
|
||||
endMatch = !nowTime.isAfter(endTime);
|
||||
} else {
|
||||
// Cross-midnight window, e.g. 23:00-02:00.
|
||||
startMatch = !nowTime.isBefore(startTime) || !nowTime.isAfter(endTime);
|
||||
endMatch = true;
|
||||
}
|
||||
} else {
|
||||
startMatch = alertSilence.getPeriodStart() == null
|
||||
|| now.isAfter(alertSilence.getPeriodStart().toLocalDateTime());
|
||||
endMatch = alertSilence.getPeriodEnd() == null
|
||||
|| now.isBefore(alertSilence.getPeriodEnd().toLocalDateTime());
|
||||
}
|
||||
|
||||
if (startMatch && endMatch) {
|
||||
int time = Optional.ofNullable(alertSilence.getTimes()).orElse(0);
|
||||
|
||||
+82
@@ -119,6 +119,88 @@ class AlarmSilenceReduceTest {
|
||||
verify(alertSilenceDao).save(silenceRule);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCyclicSilenceRuleTimeMatchesButDateDifferent_shouldNotForwardAlert() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
LocalDateTime yesterday = now.minusDays(1);
|
||||
LocalDateTime start = yesterday.withHour(now.getHour())
|
||||
.withMinute(Math.max(0, now.getMinute() - 10))
|
||||
.withSecond(0)
|
||||
.withNano(0);
|
||||
LocalDateTime end = yesterday.withHour(now.getHour())
|
||||
.withMinute(Math.min(59, now.getMinute() + 10))
|
||||
.withSecond(59)
|
||||
.withNano(0);
|
||||
|
||||
AlertSilence silenceRule = AlertSilence.builder()
|
||||
.enable(true)
|
||||
.matchAll(false)
|
||||
.type((byte) 1)
|
||||
.labels(createLabels("service", "web"))
|
||||
.periodStart(start.atZone(ZoneId.systemDefault()))
|
||||
.periodEnd(end.atZone(ZoneId.systemDefault()))
|
||||
.days(Collections.singletonList((byte) now.getDayOfWeek().getValue()))
|
||||
.times(0)
|
||||
.build();
|
||||
|
||||
when(alertSilenceDao.findAlertSilencesByEnableTrue()).thenReturn(Collections.singletonList(silenceRule));
|
||||
when(alertSilenceDao.save(any(AlertSilence.class))).thenReturn(silenceRule);
|
||||
|
||||
GroupAlert alert = createGroupAlert("firing", createLabels("service", "web"));
|
||||
alarmSilenceReduce.silenceAlarm(alert);
|
||||
|
||||
verify(alertNoticeDispatch, never()).dispatchAlarm(alert);
|
||||
verify(alertSilenceDao).save(silenceRule);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenMatchingCrossMidnightCyclicSilenceRule_shouldNotForwardAlert() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
AlertSilence silenceRule = AlertSilence.builder()
|
||||
.enable(true)
|
||||
.matchAll(false)
|
||||
.type((byte) 1)
|
||||
.labels(createLabels("service", "web"))
|
||||
.periodStart(now.minusHours(1).atZone(ZoneId.systemDefault()))
|
||||
.periodEnd(now.minusHours(2).atZone(ZoneId.systemDefault()))
|
||||
.days(Collections.singletonList((byte) now.getDayOfWeek().getValue()))
|
||||
.times(0)
|
||||
.build();
|
||||
|
||||
when(alertSilenceDao.findAlertSilencesByEnableTrue()).thenReturn(Collections.singletonList(silenceRule));
|
||||
when(alertSilenceDao.save(any(AlertSilence.class))).thenReturn(silenceRule);
|
||||
|
||||
GroupAlert alert = createGroupAlert("firing", createLabels("service", "web"));
|
||||
alarmSilenceReduce.silenceAlarm(alert);
|
||||
|
||||
verify(alertNoticeDispatch, never()).dispatchAlarm(alert);
|
||||
verify(alertSilenceDao).save(silenceRule);
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenCrossMidnightCyclicSilenceRuleDoesNotIncludeCurrentDay_shouldForwardAlert() {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
byte previousDay = (byte) now.minusDays(1).getDayOfWeek().getValue();
|
||||
AlertSilence silenceRule = AlertSilence.builder()
|
||||
.enable(true)
|
||||
.matchAll(false)
|
||||
.type((byte) 1)
|
||||
.labels(createLabels("service", "web"))
|
||||
.periodStart(now.minusHours(1).atZone(ZoneId.systemDefault()))
|
||||
.periodEnd(now.minusHours(2).atZone(ZoneId.systemDefault()))
|
||||
.days(Collections.singletonList(previousDay))
|
||||
.times(0)
|
||||
.build();
|
||||
|
||||
when(alertSilenceDao.findAlertSilencesByEnableTrue()).thenReturn(Collections.singletonList(silenceRule));
|
||||
|
||||
GroupAlert alert = createGroupAlert("firing", createLabels("service", "web"));
|
||||
alarmSilenceReduce.silenceAlarm(alert);
|
||||
|
||||
verify(alertNoticeDispatch).dispatchAlarm(alert);
|
||||
verify(alertSilenceDao, never()).save(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void whenSilenceRuleExpired_shouldForwardAlert() {
|
||||
AlertSilence silenceRule = AlertSilence.builder()
|
||||
|
||||
Reference in New Issue
Block a user