Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -11,6 +12,12 @@
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;

/**
* RabbitMQ를 통한 알람 전송 서비스
Expand All @@ -36,10 +43,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();
Expand All @@ -57,42 +61,43 @@ 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);

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<String> entity = new HttpEntity<>(requestBody, headers);
HttpEntity<RabbitMqRequest> entity = new HttpEntity<>(request, headers);

// RabbitMQ에 POST 요청
org.springframework.http.ResponseEntity<String> response = restTemplate.exchange(
url,
uri,
HttpMethod.POST,
entity,
String.class
Expand All @@ -119,7 +124,7 @@ public static class AlertMessage {
private String title;
private String message;
private String channelName;
private String recipients;
private List<String> recipients;

// Getters and Setters
public String getTitle() { return title; }
Expand All @@ -131,22 +136,24 @@ 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<String> getRecipients() { return recipients; }
public void setRecipients(List<String> recipients) { this.recipients = recipients; }
}

/**
* RabbitMQ HTTP API 요청 DTO
*/
public static class RabbitMqRequest {
private Object properties = new Object();
private Map<String, Object> 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<String, Object>) properties; }

public String getRoutingKey() { return routingKey; }
public void setRoutingKey(String routingKey) { this.routingKey = routingKey; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -927,21 +937,55 @@ 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;
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(smsTitle, smsMessage, "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);
}
Expand Down
8 changes: 5 additions & 3 deletions src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +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:#kubernetes-alerts}
slack-channel-id: ${ALERT_SLACK_CHANNEL_ID:}
email: ${ALERT_EMAIL:}
sms-phonenumber: ${ALERT_SMS_PHONE_NUMBER:}
kakao-phonenumber: ${ALERT_KAKAO_PHONE_NUMBER:}


Loading