From c7419e8f87d430c5fdd6d93927cfe33873a891f7 Mon Sep 17 00:00:00 2001 From: jmin Date: Tue, 4 Nov 2025 10:37:01 +0900 Subject: [PATCH 1/2] modify the alarm API --- .../common/service/RabbitMqAlertService.java | 28 ++++---- .../service/KubernetesMonitoringService.java | 64 +++++++++++++++---- src/main/resources/application.yaml | 5 +- 3 files changed, 70 insertions(+), 27 deletions(-) diff --git a/src/main/java/kr/co/mcmp/softwarecatalog/common/service/RabbitMqAlertService.java b/src/main/java/kr/co/mcmp/softwarecatalog/common/service/RabbitMqAlertService.java index 4fcb676..f790fb4 100644 --- a/src/main/java/kr/co/mcmp/softwarecatalog/common/service/RabbitMqAlertService.java +++ b/src/main/java/kr/co/mcmp/softwarecatalog/common/service/RabbitMqAlertService.java @@ -1,5 +1,6 @@ package kr.co.mcmp.softwarecatalog.common.service; +import com.fasterxml.jackson.annotation.JsonProperty; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; @@ -12,6 +13,9 @@ import lombok.extern.slf4j.Slf4j; +import java.util.HashMap; +import java.util.Map; + /** * RabbitMQ를 통한 알람 전송 서비스 */ @@ -36,10 +40,7 @@ public class RabbitMqAlertService { @Value("${rabbitmq.alert.password:mc-agent}") private String password; - - @Value("${rabbitmq.alert.slack-channel-id:#kubernetes-alerts}") - private String defaultSlackChannelId; - + public RabbitMqAlertService() { this.restTemplate = new RestTemplate(); this.objectMapper = new ObjectMapper(); @@ -71,24 +72,21 @@ public boolean sendScaleOutAlert(String title, String message, String channelNam // JSON 문자열로 변환 String payload = objectMapper.writeValueAsString(alertMessage); - + log.info("Alert payload: {}", payload); + // RabbitMQ 요청 본문 생성 RabbitMqRequest request = new RabbitMqRequest(); - request.setRoutingKey("alert.queue"); // 담당자 예시에 맞춤 + request.setRoutingKey("alert-manual.queue"); // 담당자 예시에 맞춤 request.setPayload(payload); request.setPayloadEncoding("string"); - - String requestBody = objectMapper.writeValueAsString(request); - - log.info("Alert payload: {}", payload); - log.info("RabbitMQ request body: {}", requestBody); + log.info("RabbitMQ request body: {}", request); // HTTP 요청 헤더 설정 HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON); headers.setBasicAuth(username, password); - HttpEntity entity = new HttpEntity<>(requestBody, headers); + HttpEntity entity = new HttpEntity<>(request, headers); // RabbitMQ에 POST 요청 org.springframework.http.ResponseEntity response = restTemplate.exchange( @@ -139,14 +137,16 @@ public static class AlertMessage { * RabbitMQ HTTP API 요청 DTO */ public static class RabbitMqRequest { - private Object properties = new Object(); + private Map properties = new HashMap<>(); + @JsonProperty("routing_key") private String routingKey; private String payload; + @JsonProperty("payload_encoding") private String payloadEncoding; // Getters and Setters public Object getProperties() { return properties; } - public void setProperties(Object properties) { this.properties = properties; } + public void setProperties(Object properties) { this.properties = (Map) properties; } public String getRoutingKey() { return routingKey; } public void setRoutingKey(String routingKey) { this.routingKey = routingKey; } diff --git a/src/main/java/kr/co/mcmp/softwarecatalog/kubernetes/service/KubernetesMonitoringService.java b/src/main/java/kr/co/mcmp/softwarecatalog/kubernetes/service/KubernetesMonitoringService.java index 55c385b..b930225 100644 --- a/src/main/java/kr/co/mcmp/softwarecatalog/kubernetes/service/KubernetesMonitoringService.java +++ b/src/main/java/kr/co/mcmp/softwarecatalog/kubernetes/service/KubernetesMonitoringService.java @@ -11,6 +11,8 @@ import java.util.Objects; import java.util.stream.Collectors; +import kr.co.mcmp.softwarecatalog.SoftwareCatalog; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Service; @@ -70,6 +72,14 @@ public class KubernetesMonitoringService { @Value("${k8s.autoscaling.test-memory-threshold:0.1}") private double testMemoryThreshold; + @Value("${rabbitmq.alert.slack-channel-id}") + private String defaultSlackChannelId; + @Value("${rabbitmq.alert.email}") + private String defaultEmail; + @Value("${rabbitmq.alert.sms-phonenumber}") + private String defaultSmsPhonenumber; + @Value("${rabbitmq.alert.kakao-phonenumber}") + private String defaultKakaoPhonenumber; @Scheduled(fixedRate = 60000) // 1분마다 실행 public void monitorKubernetesResources() { @@ -927,21 +937,51 @@ private void sendScaleOutCompletedAlert(DeploymentHistory deployment, int newNod "Application '%s' has been successfully scaled out to %d nodes in cluster '%s' (namespace: %s).", appName, newNodeCount, clusterName, namespace ); - + // Slack 채널로 알람 전송 (환경변수에서 채널 ID 가져오기) - String recipients = System.getenv("ALERT_SLACK_CHANNEL_ID"); - if (recipients == null) { - recipients = "#kubernetes-alerts"; // 기본값 + String recipients = defaultSlackChannelId; + if (StringUtils.isNotBlank(recipients)) { + boolean sent = rabbitMqAlertService.sendScaleOutAlert(title, message, "slack", recipients); + if (sent) { + log.info("Scale out alert (slack) sent successfully for {} to {} nodes", appName, newNodeCount); + } else { + log.warn("Failed to send scale out alert (slack) for {}", appName); + } } - - boolean sent = rabbitMqAlertService.sendScaleOutAlert(title, message, "slack", recipients); - - if (sent) { - log.info("Scale out alert sent successfully for {} to {} nodes", appName, newNodeCount); - } else { - log.warn("Failed to send scale out alert for {}", appName); + + // Email + recipients = defaultEmail; + if (StringUtils.isNotBlank(recipients)) { + boolean sent = rabbitMqAlertService.sendScaleOutAlert(title, message, "email", recipients); + if (sent) { + log.info("Scale out alert (email) sent successfully for {} to {} nodes", appName, newNodeCount); + } else { + log.warn("Failed to send scale out alert (email) for {}", appName); + } } - + + // SMS + recipients = defaultSmsPhonenumber; + if (StringUtils.isNotBlank(recipients)) { + boolean sent = rabbitMqAlertService.sendScaleOutAlert(title, message, "sms", recipients); + if (sent) { + log.info("Scale out alert (sms) sent successfully for {} to {} nodes", appName, newNodeCount); + } else { + log.warn("Failed to send scale out alert (sms) for {}", appName); + } + } + + // kako + recipients = defaultKakaoPhonenumber; + if (StringUtils.isNotBlank(recipients)) { + boolean sent = rabbitMqAlertService.sendScaleOutAlert(title, message, "kakao", recipients); + if (sent) { + log.info("Scale out alert (kakao) sent successfully for {} to {} nodes", appName, newNodeCount); + } else { + log.warn("Failed to send scale out alert (kakao) for {}", appName); + } + } + } catch (Exception e) { log.error("Error sending scale out alert: {}", e.getMessage(), e); } diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 4fe3e4e..3a90b6a 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -113,6 +113,9 @@ rabbitmq: vhost: ${RABBITMQ_VHOST:test} username: ${RABBITMQ_USERNAME:mc-agent} password: ${RABBITMQ_PASSWORD:mc-agent} - slack-channel-id: ${ALERT_SLACK_CHANNEL_ID:#kubernetes-alerts} + slack-channel-id: ${ALERT_SLACK_CHANNEL_ID:C09QG93AZLL} + email: ${ALERT_EMAIL:} + sms-phonenumber: ${ALERT_SMS_PHONE_NUMBER:} + kakao-phonenumber: ${ALERT_KAKAO_PHONE_NUMBER:} \ No newline at end of file From a801e182fb6484eec4626e8edaaa54ab940e163f Mon Sep 17 00:00:00 2001 From: jmin Date: Tue, 4 Nov 2025 15:15:10 +0900 Subject: [PATCH 2/2] modify the alarm API --- .../common/service/RabbitMqAlertService.java | 23 ++++++++++++------- .../service/KubernetesMonitoringService.java | 8 +++++-- src/main/resources/application.yaml | 5 ++-- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/main/java/kr/co/mcmp/softwarecatalog/common/service/RabbitMqAlertService.java b/src/main/java/kr/co/mcmp/softwarecatalog/common/service/RabbitMqAlertService.java index f790fb4..c1e419c 100644 --- a/src/main/java/kr/co/mcmp/softwarecatalog/common/service/RabbitMqAlertService.java +++ b/src/main/java/kr/co/mcmp/softwarecatalog/common/service/RabbitMqAlertService.java @@ -12,8 +12,11 @@ import com.fasterxml.jackson.databind.ObjectMapper; import lombok.extern.slf4j.Slf4j; +import org.springframework.web.util.UriComponentsBuilder; +import java.net.URI; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -58,17 +61,21 @@ public RabbitMqAlertService() { public boolean sendScaleOutAlert(String title, String message, String channelName, String recipients) { try { // RabbitMQ HTTP API URL 생성 (담당자 예시에 맞춤) - String url = String.format("http://%s:%s/api/exchanges/%%2F%s/amq.default/publish", + String url = String.format("http://%s:%s/api/exchanges/%%2f%s/alert-manual.exchange/publish", rabbitmqUrl, rabbitmqPort, vhost); - - log.info("Sending alert to RabbitMQ: {}", url); + + URI uri = UriComponentsBuilder.fromHttpUrl(url) + .build(true) + .toUri(); + + log.info("Sending alert to RabbitMQ: {}", uri.toString()); // 알람 메시지 생성 AlertMessage alertMessage = new AlertMessage(); alertMessage.setTitle(title); alertMessage.setMessage(message); alertMessage.setChannelName(channelName); - alertMessage.setRecipients(recipients); + alertMessage.setRecipients(List.of(recipients)); // JSON 문자열로 변환 String payload = objectMapper.writeValueAsString(alertMessage); @@ -90,7 +97,7 @@ public boolean sendScaleOutAlert(String title, String message, String channelNam // RabbitMQ에 POST 요청 org.springframework.http.ResponseEntity response = restTemplate.exchange( - url, + uri, HttpMethod.POST, entity, String.class @@ -117,7 +124,7 @@ public static class AlertMessage { private String title; private String message; private String channelName; - private String recipients; + private List recipients; // Getters and Setters public String getTitle() { return title; } @@ -129,8 +136,8 @@ public static class AlertMessage { public String getChannelName() { return channelName; } public void setChannelName(String channelName) { this.channelName = channelName; } - public String getRecipients() { return recipients; } - public void setRecipients(String recipients) { this.recipients = recipients; } + public List getRecipients() { return recipients; } + public void setRecipients(List recipients) { this.recipients = recipients; } } /** diff --git a/src/main/java/kr/co/mcmp/softwarecatalog/kubernetes/service/KubernetesMonitoringService.java b/src/main/java/kr/co/mcmp/softwarecatalog/kubernetes/service/KubernetesMonitoringService.java index b930225..d2588f1 100644 --- a/src/main/java/kr/co/mcmp/softwarecatalog/kubernetes/service/KubernetesMonitoringService.java +++ b/src/main/java/kr/co/mcmp/softwarecatalog/kubernetes/service/KubernetesMonitoringService.java @@ -960,10 +960,14 @@ private void sendScaleOutCompletedAlert(DeploymentHistory deployment, int newNod } } - // SMS + // SMS - 글자제약으로 메시지 내용 축약 recipients = defaultSmsPhonenumber; + String smsTitle = String.format("Scale-out OK. %s", appName); + String smsMessage = String.format("Node: %d, Cluster: '%s', NS: %s", + newNodeCount, clusterName, namespace + ); if (StringUtils.isNotBlank(recipients)) { - boolean sent = rabbitMqAlertService.sendScaleOutAlert(title, message, "sms", recipients); + boolean sent = rabbitMqAlertService.sendScaleOutAlert(smsTitle, smsMessage, "sms", recipients); if (sent) { log.info("Scale out alert (sms) sent successfully for {} to {} nodes", appName, newNodeCount); } else { diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 3a90b6a..137ec82 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -108,14 +108,13 @@ k8s: rabbitmq: alert: - url: ${RABBITMQ_URL:localhost} + url: ${RABBITMQ_URL:210.207.104.130} port: ${RABBITMQ_PORT:15672} vhost: ${RABBITMQ_VHOST:test} username: ${RABBITMQ_USERNAME:mc-agent} password: ${RABBITMQ_PASSWORD:mc-agent} - slack-channel-id: ${ALERT_SLACK_CHANNEL_ID:C09QG93AZLL} + slack-channel-id: ${ALERT_SLACK_CHANNEL_ID:} email: ${ALERT_EMAIL:} sms-phonenumber: ${ALERT_SMS_PHONE_NUMBER:} kakao-phonenumber: ${ALERT_KAKAO_PHONE_NUMBER:} - \ No newline at end of file