Skip to content

Commit

Permalink
refactor: change sendErrorNotification to return Mono<Void>
Browse files Browse the repository at this point in the history
  • Loading branch information
gmkim20713 committed Aug 15, 2024
1 parent 082a3df commit 410a193
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 92 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package kr.mafoo.user.handler;

import kr.mafoo.user.slack.SlackNotificationService;
import kr.mafoo.user.service.SlackService;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -17,28 +17,28 @@
@RequiredArgsConstructor
public class GlobalExceptionHandler {
private final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
private final SlackNotificationService slackNotificationService;
private final SlackService slackService;

@ExceptionHandler(Exception.class)
public Mono<ResponseEntity<String>> handleException(ServerWebExchange exchange, Exception ex) {
String method = exchange.getRequest().getMethod().toString();
String userAgent = exchange.getRequest().getHeaders().getFirst("User-Agent");
String proxyIp = exchange.getRequest().getHeaders().getFirst("X-Forwarded-For");
InetSocketAddress address = exchange.getRequest().getRemoteAddress();
String originIp = proxyIp != null ? proxyIp : (address != null ? address.toString() : "UNKNOWN SOURCE");
String fullPath = exchange.getRequest().getURI().getPath() +
(exchange.getRequest().getURI().getQuery() != null ? "?" + exchange.getRequest().getURI().getQuery() : "");

logger.error("Exception occurred: {} {} {} ERROR {} {}", exchange.getRequest().getMethod(), fullPath, originIp, ex.getMessage(), userAgent);
logger.error("Exception occurred: {} {} {} ERROR {} {}", method, fullPath, originIp, ex.getMessage(), userAgent);

slackNotificationService.sendErrorNotification(
ex,
exchange.getRequest().getMethod().toString(),
exchange.getRequest().getURI().toString(),
HttpStatus.INTERNAL_SERVER_ERROR.toString(),
System.currentTimeMillis(), // or appropriate execution time
exchange.getRequest().getHeaders().getFirst("User-Agent")
return slackService.sendErrorNotification(
method,
fullPath,
originIp,
userAgent,
ex.getMessage()
).then(
Mono.just(new ResponseEntity<>("Internal Server Error", HttpStatus.INTERNAL_SERVER_ERROR))
);

return Mono.just(new ResponseEntity<>("Internal Server Error", HttpStatus.INTERNAL_SERVER_ERROR));
}
}
196 changes: 116 additions & 80 deletions user-service/src/main/java/kr/mafoo/user/service/SlackService.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
package kr.mafoo.user.service;

import com.slack.api.methods.MethodsClient;
import com.slack.api.methods.SlackApiException;
import com.slack.api.methods.request.chat.ChatPostMessageRequest;
import com.slack.api.model.block.Blocks;
import com.slack.api.model.block.LayoutBlock;
import com.slack.api.model.block.composition.MarkdownTextObject;
import com.slack.api.model.block.composition.TextObject;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import static com.slack.api.model.block.Blocks.*;
import static com.slack.api.model.block.composition.BlockCompositions.markdownText;
import static com.slack.api.model.block.composition.BlockCompositions.plainText;

@Service
Expand All @@ -32,86 +28,126 @@ public class SlackService {

private final MethodsClient methodsClient;

public void sendErrorNotification(Throwable throwable, String method, String uri, String statusCode, long executionTime, String userAgent) {
try {
List<TextObject> textObjects = new ArrayList<>();

textObjects.add(markdownText(">*μ˜ˆμƒν•˜μ§€ λͺ»ν•œ μ—λŸ¬κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€!*\n"));
textObjects.add(markdownText("\n"));

textObjects.add(markdownText("*λ©”μ†Œλ“œ:* \n`" + method + "`\n"));
textObjects.add(markdownText("*URI:* \n`" + uri + "`\n"));
textObjects.add(markdownText("*μƒνƒœμ½”λ“œ:* \n`" + statusCode + "`\n"));
textObjects.add(markdownText("*메세지:* \n`" + throwable.getMessage() + "`\n"));
textObjects.add(markdownText("*μ†Œμš”μ‹œκ°„:* \n`" + executionTime + " ms`\n"));
textObjects.add(markdownText("*μ‚¬μš©μž:* \n`" + userAgent + "`\n"));

ChatPostMessageRequest request = ChatPostMessageRequest
.builder()
.channel(errorChannel)
.blocks(
asBlocks(
divider(),
section(
section -> section.fields(textObjects)
)
))
.build();

methodsClient.chatPostMessage(request);
} catch (SlackApiException | IOException e) {
throw new RuntimeException("Can't send Slack Message.", e);
}
public Mono<Void> sendErrorNotification(String method, String uri, String originIp, String userAgent, String message) {
return Mono.fromCallable(() -> {
List<LayoutBlock> layoutBlocks = new ArrayList<>();

// Header μ‚½μž…
layoutBlocks.add(
Blocks.header(
headerBlockBuilder ->
headerBlockBuilder.text(plainText("🚨 μ˜ˆμƒν•˜μ§€ λͺ»ν•œ μ—λŸ¬ λ°œμƒ"))
)
);

layoutBlocks.add(divider());

// Content μ‚½μž…
MarkdownTextObject errorMethodMarkdown =
MarkdownTextObject.builder().text("`METHOD`\n" + method).build();

MarkdownTextObject errorUriMarkdown =
MarkdownTextObject.builder().text("`URI`\n" + uri).build();

layoutBlocks.add(
section(
section -> section.fields(List.of(errorMethodMarkdown, errorUriMarkdown))
)
);

MarkdownTextObject errorOriginIpMarkdown =
MarkdownTextObject.builder().text("`μ—λŸ¬ λ°œμƒ IP`\n" + originIp).build();

MarkdownTextObject errorUserAgentMarkdown =
MarkdownTextObject.builder().text("`μ—λŸ¬ λ°œμƒ ν™˜κ²½`\n" + userAgent).build();

layoutBlocks.add(
section(
section -> section.fields(List.of(errorOriginIpMarkdown, errorUserAgentMarkdown))
)
);

MarkdownTextObject errorMessageMarkdown =
MarkdownTextObject.builder().text("`메세지`\n" + message).build();

layoutBlocks.add(
section(
section -> section.fields(List.of(errorMessageMarkdown))
)
);

ChatPostMessageRequest chatPostMessageRequest =
ChatPostMessageRequest
.builder()
.text("μ˜ˆμƒν•˜μ§€ λͺ»ν•œ μ—λŸ¬ λ°œμƒ μ•Œλ¦Ό")
.channel(errorChannel)
.blocks(layoutBlocks)
.build();

return methodsClient.chatPostMessage(chatPostMessageRequest);

}).then();
}

public Mono<Void> sendNewMemberNotification(String memberId, String memberName, String memberProfileImageUrl, String memberCreatedAt, String userAgent) {
return Mono.fromCallable(() -> {
List<LayoutBlock> layoutBlocks = new ArrayList<>();

layoutBlocks.add(
Blocks.header(
headerBlockBuilder ->
headerBlockBuilder.text(plainText("πŸŽ‰ μ‹ κ·œ μ‚¬μš©μž κ°€μž…"))));
layoutBlocks.add(divider());

MarkdownTextObject userIdMarkdown =
MarkdownTextObject.builder().text("`μ‚¬μš©μž ID`\n" + memberId).build();

MarkdownTextObject userNameMarkdown =
MarkdownTextObject.builder().text("`μ‚¬μš©μž λ‹‰λ„€μž„`\n" + memberName).build();

layoutBlocks.add(
section(
section -> section.fields(List.of(userIdMarkdown, userNameMarkdown))));

MarkdownTextObject userProfileImageMarkdown =
MarkdownTextObject.builder().text("`ν”„λ‘œν•„ 이미지`\n" + memberProfileImageUrl).build();

MarkdownTextObject userCreatedAtMarkdown =
MarkdownTextObject.builder().text("`κ°€μž… 일자`\n" + memberCreatedAt).build();

layoutBlocks.add(
section(
section -> section.fields(List.of(userProfileImageMarkdown, userCreatedAtMarkdown))));

MarkdownTextObject userUserAgentMarkdown =
MarkdownTextObject.builder().text("`κ°€μž… ν™˜κ²½`\n" + userAgent).build();

layoutBlocks.add(
section(
section -> section.fields(List.of(userUserAgentMarkdown))));

ChatPostMessageRequest chatPostMessageRequest =
ChatPostMessageRequest
.builder()
.text("μ‹ κ·œ μ‚¬μš©μž κ°€μž… μ•Œλ¦Ό")
.channel(memberChannel)
.blocks(layoutBlocks)
.build();

return methodsClient.chatPostMessage(chatPostMessageRequest);
})
.then();
List<LayoutBlock> layoutBlocks = new ArrayList<>();

// Header μ‚½μž…
layoutBlocks.add(
Blocks.header(
headerBlockBuilder ->
headerBlockBuilder.text(plainText("πŸŽ‰ μ‹ κ·œ μ‚¬μš©μž κ°€μž…"))
)
);

layoutBlocks.add(divider());

// Content μ‚½μž…
MarkdownTextObject userIdMarkdown =
MarkdownTextObject.builder().text("`μ‚¬μš©μž ID`\n" + memberId).build();

MarkdownTextObject userNameMarkdown =
MarkdownTextObject.builder().text("`μ‚¬μš©μž λ‹‰λ„€μž„`\n" + memberName).build();

layoutBlocks.add(
section(
section -> section.fields(List.of(userIdMarkdown, userNameMarkdown))
)
);

MarkdownTextObject userProfileImageMarkdown =
MarkdownTextObject.builder().text("`ν”„λ‘œν•„ 이미지`\n" + memberProfileImageUrl).build();

MarkdownTextObject userCreatedAtMarkdown =
MarkdownTextObject.builder().text("`κ°€μž… 일자`\n" + memberCreatedAt).build();

layoutBlocks.add(
section(
section -> section.fields(List.of(userProfileImageMarkdown, userCreatedAtMarkdown))
)
);

MarkdownTextObject userUserAgentMarkdown =
MarkdownTextObject.builder().text("`κ°€μž… ν™˜κ²½`\n" + userAgent).build();

layoutBlocks.add(
section(
section -> section.fields(List.of(userUserAgentMarkdown))
)
);

ChatPostMessageRequest chatPostMessageRequest =
ChatPostMessageRequest
.builder()
.text("μ‹ κ·œ μ‚¬μš©μž κ°€μž… μ•Œλ¦Ό")
.channel(memberChannel)
.blocks(layoutBlocks)
.build();

return methodsClient.chatPostMessage(chatPostMessageRequest);

}).then();
}

}

0 comments on commit 410a193

Please sign in to comment.