From 72d89125975b0730ddb2b559fdf4a5303c5a4f09 Mon Sep 17 00:00:00 2001 From: cho Date: Wed, 11 Feb 2026 13:24:44 +0900 Subject: [PATCH] =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=99=84?= =?UTF-8?q?=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../eai/custom/alarm/AlarmService.java | 44 +++++++++++-------- .../eai/custom/alarm/AlarmStateManager.java | 33 ++++++++++---- .../alarm/condition/AlarmCondition.java | 3 ++ .../eai/custom/alarm/event/AlarmEvent.java | 2 + .../eai/custom/alarm/key/AlarmKey.java | 1 + .../eai/custom/alarm/key/CoreAlarmKey.java | 4 +- .../eai/custom/alarm/key/DynamicAlarmKey.java | 3 ++ .../eai/custom/alarm/policy/AlarmPolicy.java | 14 ------ .../custom/alarm/policy/CounterPolicy.java | 2 +- .../eai/custom/alarm/policy/SendPolicy.java | 7 +-- .../eai/custom/alarm/policy/TimerPolicy.java | 2 +- 11 files changed, 67 insertions(+), 48 deletions(-) diff --git a/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java b/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java index bcd00ed..7f26e67 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java +++ b/src/main/java/com/eactive/eai/custom/alarm/AlarmService.java @@ -28,8 +28,9 @@ public class AlarmService { protected static Logger logger = Logger.getLogger(Logger.LOGGER_DEFAULT); final static String ALARM_GROUP = "Alarm"; - final static String ALARM_KEY = "Alarm"; + final static String ALARM_KEY = "{ALARM}"; final static String ALARM_RECIVER = "{RECIVER}"; + final static String ALARM_EABLE = "enable.alarm"; public Map getAlarmPolicy() { @@ -40,16 +41,16 @@ public class AlarmService { Properties props = PropManager.getInstance().getProperties(ALARM_GROUP); props.forEach((key, value) -> { + String keyName = (String) key; String configStr = (String) value; - if (keyName.contains(ALARM_RECIVER)) return; + if (keyName.contains(ALARM_KEY)) { - AlarmPolicy newPolicy = buildAlarmPolicy(keyName, configStr); - - - policyMap.put(newPolicy.getAlarmKey(), newPolicy); + AlarmPolicy newPolicy = buildAlarmPolicy(keyName, configStr); + policyMap.put(newPolicy.getAlarmKey(), newPolicy); + } }); } catch (Exception e) { @@ -60,29 +61,33 @@ public class AlarmService { return policyMap; } + public boolean isAlarmEnabled() { + return Optional.ofNullable(PropManager.getInstance().getProperty(ALARM_GROUP, ALARM_EABLE)) + .map(Boolean::valueOf).orElse(false); + } + private AlarmPolicy buildAlarmPolicy(String key, String configJsonStr) { JsonObject alarmConfig = Jsons.GSON.fromJson(configJsonStr, JsonObject.class); String policyType = alarmConfig.get("type").getAsString(); - int coolDownSec = Optional.ofNullable(alarmConfig.get("coolDownSec")).map(i -> i.getAsInt()).orElse(60); int thresholdCount = Optional.ofNullable(alarmConfig.get("thresholdCount")).map(i -> i.getAsInt()).orElse(5); int timeWindowSec = Optional.ofNullable(alarmConfig.get("timeWindowSec")).map(i -> i.getAsInt()).orElse(60); AlarmPolicy alarmPolicy; if ("count".equals(policyType)) { - alarmPolicy = CounterPolicy.builder().alarmKey(new DynamicAlarmKey(key)).coolDownMs(coolDownSec * 1000) - .thresholdCount(thresholdCount).build(); + alarmPolicy = CounterPolicy.builder().alarmKey(new DynamicAlarmKey(key)).thresholdCount(thresholdCount) + .build(); } else { - alarmPolicy = TimerPolicy.builder().alarmKey(new DynamicAlarmKey(key)).coolDownMs(coolDownSec * 1000) - .timeWindowMs(timeWindowSec * 1000).build(); + alarmPolicy = TimerPolicy.builder().alarmKey(new DynamicAlarmKey(key)).timeWindowMs(timeWindowSec * 1000) + .build(); } return alarmPolicy; } - + public Map getSendPolicy() { Map policyMap = new HashMap(); @@ -95,11 +100,11 @@ public class AlarmService { String keyName = (String) key; String configStr = (String) value; - if (!keyName.contains(ALARM_RECIVER)) return; + if (!keyName.contains(ALARM_RECIVER)) + return; SendPolicy newPolicy = buildSendPolicy(keyName, configStr); - - + policyMap.put(newPolicy.getAlarmKey(), newPolicy); }); @@ -111,12 +116,13 @@ public class AlarmService { return policyMap; } - + private SendPolicy buildSendPolicy(String key, String configStr) { - List reciverList = Optional.ofNullable(configStr).map( t -> Arrays.asList(t.split(",")) ).orElse(Collections.EMPTY_LIST); - - key = key.replaceAll(ALARM_RECIVER, "").trim(); + List reciverList = Optional.ofNullable(configStr).map(t -> Arrays.asList(t.split(","))) + .orElse(Collections.EMPTY_LIST); + + key = key.replace(ALARM_RECIVER, "").trim() + "{ALARM}"; SendPolicy sendPolicy = new SendPolicy(key, reciverList); diff --git a/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java index 5706b5d..719a204 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java +++ b/src/main/java/com/eactive/eai/custom/alarm/AlarmStateManager.java @@ -1,6 +1,7 @@ package com.eactive.eai.custom.alarm; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Optional; @@ -11,7 +12,6 @@ import java.util.concurrent.TimeUnit; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; -import com.eactive.eai.common.property.PropManager; import com.eactive.eai.common.util.ApplicationContextProvider; import com.eactive.eai.common.util.Logger; import com.eactive.eai.custom.alarm.event.AlarmEvent; @@ -85,19 +85,36 @@ public class AlarmStateManager { private void fireAlarm() { Map alarmPolicyMap = alarmService.getAlarmPolicy(); + Map sendPolicyMap = alarmService.getSendPolicy(); - for (AlarmEvent event : registerAlarmList) { + Iterator iterator = registerAlarmList.iterator(); + while (iterator.hasNext()) { + AlarmEvent event = iterator.next(); AlarmPolicy alarmPolicy = alarmPolicyMap.get(event.getKey()); - if (alarmPolicy.isAlarmTriggered(event)) { - + if (alarmPolicy != null && alarmPolicy.isAlarmTriggered(event)) { + // 알람 발송 로직 SendPolicy sendPolicy = sendPolicyMap.get(event.getKey()); - - send(sendPolicy, event); + if (alarmService.isAlarmEnabled()) { + send(sendPolicy, event); + } else { + logger.info("Alarm is disabled, event = {}, policy = {}", event, sendPolicy); + } + // 리스트에서 안전하게 제거 + iterator.remove(); + }else { //트리거 조건이 안되더라도, 이벤트발생한지 오래 되었으면 제거하여 OOM 예방. + + + long firstOcurredAt = event.getCondition().getOcurredAt(); + + long diffInMs = System.currentTimeMillis() - firstOcurredAt; + + if ( diffInMs >= TimeUnit.MINUTES.toMillis(60) ) { //1시간 지난거면 삭제 + iterator.remove(); + } } - } } @@ -108,7 +125,7 @@ public class AlarmStateManager { try { - List cellPhoneList = sendPolicy.getCellpohoneList(); + List cellPhoneList = sendPolicy.getCellPhoneList(); for (String cellPhone : cellPhoneList) { diff --git a/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java b/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java index 996dbd0..2313fdf 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java +++ b/src/main/java/com/eactive/eai/custom/alarm/condition/AlarmCondition.java @@ -2,12 +2,15 @@ package com.eactive.eai.custom.alarm.condition; import lombok.Builder; import lombok.Getter; +import lombok.ToString; @Builder @Getter +@ToString public class AlarmCondition { final long ocurredAt = System.currentTimeMillis(); long lastOcurredAt; // 일단, 미사용 + @Builder.Default long count = 1; public void onOcurr() { diff --git a/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java b/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java index 36f6d74..194128d 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java +++ b/src/main/java/com/eactive/eai/custom/alarm/event/AlarmEvent.java @@ -10,10 +10,12 @@ import com.eactive.eai.custom.alarm.policy.CounterPolicy; import lombok.Builder; import lombok.Getter; import lombok.Setter; +import lombok.ToString; @Setter @Getter @Builder +@ToString public class AlarmEvent { AlarmKey key; AlarmCondition condition; diff --git a/src/main/java/com/eactive/eai/custom/alarm/key/AlarmKey.java b/src/main/java/com/eactive/eai/custom/alarm/key/AlarmKey.java index c81778a..ddcf0ad 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/key/AlarmKey.java +++ b/src/main/java/com/eactive/eai/custom/alarm/key/AlarmKey.java @@ -1,5 +1,6 @@ package com.eactive.eai.custom.alarm.key; + public interface AlarmKey { String code(); } diff --git a/src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java b/src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java index 70c5027..cc1d79b 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java +++ b/src/main/java/com/eactive/eai/custom/alarm/key/CoreAlarmKey.java @@ -4,9 +4,9 @@ public final class CoreAlarmKey { private CoreAlarmKey() { } - public static final AlarmKey CircuitBreaker = new DynamicAlarmKey("CircuitBreaker"); + public static final AlarmKey CircuitBreaker = new DynamicAlarmKey("CircuitBreaker{ALARM}"); - public static final AlarmKey Timeout = new DynamicAlarmKey("Timeout"); + public static final AlarmKey Timeout = new DynamicAlarmKey("Timeout{ALARM}"); } \ No newline at end of file diff --git a/src/main/java/com/eactive/eai/custom/alarm/key/DynamicAlarmKey.java b/src/main/java/com/eactive/eai/custom/alarm/key/DynamicAlarmKey.java index c26298b..6a76d46 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/key/DynamicAlarmKey.java +++ b/src/main/java/com/eactive/eai/custom/alarm/key/DynamicAlarmKey.java @@ -1,5 +1,8 @@ package com.eactive.eai.custom.alarm.key; +import lombok.ToString; + +@ToString public final class DynamicAlarmKey implements AlarmKey { private final String code; diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java b/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java index d1230b6..3c6dd8f 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/AlarmPolicy.java @@ -1,6 +1,5 @@ package com.eactive.eai.custom.alarm.policy; -import com.eactive.eai.custom.alarm.condition.AlarmCondition; import com.eactive.eai.custom.alarm.event.AlarmEvent; import com.eactive.eai.custom.alarm.key.AlarmKey; @@ -12,13 +11,10 @@ public abstract class AlarmPolicy { private long timeWindowMs; - private long coolDownMs; - protected AlarmPolicy(Builder builder) { this.alarmKey = builder.alarmKey; this.thresholdCount = builder.thresholdCount; this.timeWindowMs = builder.timeWindowMs; - this.coolDownMs = builder.coolDownMs; } public AlarmKey getAlarmKey() { @@ -33,10 +29,6 @@ public abstract class AlarmPolicy { return timeWindowMs; } - public long getCoolDownMs() { - return coolDownMs; - } - public abstract boolean isAlarmTriggered(AlarmEvent event); @@ -55,7 +47,6 @@ public abstract class AlarmPolicy { private AlarmKey alarmKey; private int thresholdCount; private long timeWindowMs; - private long coolDownMs; public T alarmKey(AlarmKey alarmKey) { this.alarmKey = alarmKey; @@ -72,11 +63,6 @@ public abstract class AlarmPolicy { return self(); } - public T coolDownMs(long coolDownMs) { - this.coolDownMs = coolDownMs; - return self(); - } - protected abstract T self(); abstract AlarmPolicy build(); diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java b/src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java index 65d3f7f..7bf3c0a 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/CounterPolicy.java @@ -11,7 +11,7 @@ public class CounterPolicy extends AlarmPolicy { @Override public boolean isAlarmTriggered(AlarmEvent event) { - if (!event.equals(getAlarmKey())) { + if (!event.getKey().equals(getAlarmKey())) { return false; } diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/SendPolicy.java b/src/main/java/com/eactive/eai/custom/alarm/policy/SendPolicy.java index 945881d..592d529 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/policy/SendPolicy.java +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/SendPolicy.java @@ -1,22 +1,23 @@ package com.eactive.eai.custom.alarm.policy; -import java.util.ArrayList; import java.util.List; import com.eactive.eai.custom.alarm.key.AlarmKey; import com.eactive.eai.custom.alarm.key.DynamicAlarmKey; import lombok.Getter; - +import lombok.ToString; +@ToString @Getter public class SendPolicy { final AlarmKey alarmKey; - final List cellpohoneList = new ArrayList(); + final List cellPhoneList; public SendPolicy(String alarmKey, List cellPhoneList) { this.alarmKey = new DynamicAlarmKey(alarmKey); + this.cellPhoneList = cellPhoneList; } } diff --git a/src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java b/src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java index 0a51b02..29c719a 100644 --- a/src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java +++ b/src/main/java/com/eactive/eai/custom/alarm/policy/TimerPolicy.java @@ -13,7 +13,7 @@ public class TimerPolicy extends AlarmPolicy { @Override public boolean isAlarmTriggered(AlarmEvent event) { - if (event.equals(getAlarmKey())) { + if (event.getKey().equals(getAlarmKey())) { AlarmCondition condition = event.getCondition();