Skip to content

Commit 35f7e86

Browse files
author
Lee Euije
authored
YEL-113 [feat] 500에러 슬랙 알람 추가
YEL-113 [feat] 500에러 슬랙 알람 추가
2 parents 065359b + be47690 commit 35f7e86

File tree

5 files changed

+111
-3
lines changed

5 files changed

+111
-3
lines changed

build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ dependencies {
5757
// Swagger
5858
implementation 'org.springdoc:springdoc-openapi-ui:1.5.4'
5959

60-
//
60+
// p6spy
6161
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.7'
6262

6363
// Http
@@ -81,6 +81,8 @@ dependencies {
8181
// rabbitmq
8282
implementation 'org.springframework.amqp:spring-rabbit:2.3.12'
8383

84+
// slack-webhook
85+
implementation "net.gpedro.integrations.slack:slack-webhook:1.4.0"
8486
}
8587

8688
tasks.named('test') {

src/main/java/com/yello/server/domain/purchase/controller/PurchaseController.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,10 @@ public BaseResponse<AppleVerifyReceiptResponse> verifyReceipt(
4848
content = @Content(mediaType = "application/json", schema = @Schema(implementation = UserSubscribeNeededResponse.class))
4949
)
5050
})
51-
@GetMapping("/subscribe_need")
51+
@GetMapping("/subscribeNeed")
5252
public BaseResponse<UserSubscribeNeededResponse> getUserSubscribeNeeded(
5353
@AccessTokenUser User user) {
5454
val data = purchaseService.getUserSubscribe(user, LocalDateTime.now());
5555
return BaseResponse.success(USER_SUBSCRIBE_NEEDED_READ_SUCCESS, data);
5656
}
57-
5857
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.yello.server.global.common.util;
2+
3+
import net.gpedro.integrations.slack.SlackApi;
4+
import org.springframework.beans.factory.annotation.Value;
5+
import org.springframework.context.annotation.Bean;
6+
import org.springframework.context.annotation.Configuration;
7+
8+
@Configuration
9+
public class SlackUtil {
10+
11+
@Value("${slack.token}")
12+
String slackToken;
13+
14+
@Bean
15+
SlackApi slackApi() {
16+
System.out.println("slackToken = " + slackToken);
17+
return new SlackApi("https://hooks.slack.com/services/" + slackToken);
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.yello.server.global.configuration;
2+
3+
import org.springframework.context.annotation.Bean;
4+
import org.springframework.context.annotation.Configuration;
5+
import org.springframework.core.task.TaskExecutor;
6+
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
7+
8+
@Configuration
9+
public class ThreadPoolConfiguration {
10+
11+
@Bean
12+
public TaskExecutor threadPoolTaskExecutor() {
13+
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
14+
executor.setCorePoolSize(5);
15+
executor.setMaxPoolSize(5);
16+
executor.initialize();
17+
return executor;
18+
}
19+
}

src/main/java/com/yello/server/global/exception/ControllerExceptionAdvice.java

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import static org.springframework.http.HttpStatus.NOT_FOUND;
1010
import static org.springframework.http.HttpStatus.UNAUTHORIZED;
1111

12+
import com.yello.server.domain.authorization.JwtTokenProvider;
1213
import com.yello.server.domain.authorization.exception.AuthBadRequestException;
1314
import com.yello.server.domain.authorization.exception.CustomAuthenticationException;
1415
import com.yello.server.domain.authorization.exception.ExpiredTokenException;
@@ -21,15 +22,32 @@
2122
import com.yello.server.domain.friend.exception.FriendNotFoundException;
2223
import com.yello.server.domain.group.exception.GroupNotFoundException;
2324
import com.yello.server.domain.question.exception.QuestionNotFoundException;
25+
import com.yello.server.domain.user.entity.User;
2426
import com.yello.server.domain.user.exception.UserBadRequestException;
2527
import com.yello.server.domain.user.exception.UserConflictException;
2628
import com.yello.server.domain.user.exception.UserException;
2729
import com.yello.server.domain.user.exception.UserNotFoundException;
30+
import com.yello.server.domain.user.repository.UserRepository;
2831
import com.yello.server.domain.vote.exception.VoteForbiddenException;
2932
import com.yello.server.domain.vote.exception.VoteNotFoundException;
3033
import com.yello.server.global.common.dto.BaseResponse;
3134
import com.yello.server.infrastructure.redis.exception.RedisException;
3235
import com.yello.server.infrastructure.redis.exception.RedisNotFoundException;
36+
import java.time.LocalDateTime;
37+
import java.time.format.DateTimeFormatter;
38+
import java.util.ArrayList;
39+
import java.util.Arrays;
40+
import java.util.Collections;
41+
import java.util.List;
42+
import java.util.Optional;
43+
import javax.servlet.http.HttpServletRequest;
44+
import lombok.RequiredArgsConstructor;
45+
import net.gpedro.integrations.slack.SlackApi;
46+
import net.gpedro.integrations.slack.SlackAttachment;
47+
import net.gpedro.integrations.slack.SlackField;
48+
import net.gpedro.integrations.slack.SlackMessage;
49+
import org.springframework.core.task.TaskExecutor;
50+
import org.springframework.http.HttpHeaders;
3351
import org.springframework.http.ResponseEntity;
3452
import org.springframework.http.converter.HttpMessageConversionException;
3553
import org.springframework.http.converter.HttpMessageNotReadableException;
@@ -40,8 +58,59 @@
4058
import org.springframework.web.bind.annotation.RestControllerAdvice;
4159

4260
@RestControllerAdvice
61+
@RequiredArgsConstructor
4362
public class ControllerExceptionAdvice {
4463

64+
private final TaskExecutor taskExecutor;
65+
private final SlackApi slackApi;
66+
private final UserRepository userRepository;
67+
private final JwtTokenProvider jwtTokenProvider;
68+
69+
@ExceptionHandler(Exception.class)
70+
void handleException(HttpServletRequest request, Exception exception) throws Exception {
71+
SlackAttachment slackAttachment = new SlackAttachment();
72+
73+
slackAttachment.setFallback("Error");
74+
slackAttachment.setColor("danger");
75+
slackAttachment.setTitle("긴급 환자가 이송되었습니다");
76+
slackAttachment.setTitleLink(request.getContextPath());
77+
slackAttachment.setText(Arrays.toString(exception.getStackTrace()));
78+
slackAttachment.setColor("danger");
79+
80+
List<SlackField> slackFieldList = new ArrayList<>();
81+
slackFieldList.add(new SlackField().setTitle("Request URL").setValue(request.getRequestURL().toString()));
82+
slackFieldList.add(new SlackField().setTitle("Request Method").setValue(request.getMethod()));
83+
slackFieldList.add(new SlackField().setTitle("Request Time").setValue(
84+
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now())));
85+
slackFieldList.add(new SlackField().setTitle("Request IP").setValue(request.getRemoteAddr()));
86+
slackFieldList.add(
87+
new SlackField().setTitle("Request User-Agent").setValue(request.getHeader(HttpHeaders.USER_AGENT)));
88+
slackFieldList.add(
89+
new SlackField().setTitle("인증/인가 정보 - Authorization")
90+
.setValue(request.getHeader(HttpHeaders.AUTHORIZATION)));
91+
92+
final String token = request.getHeader(HttpHeaders.AUTHORIZATION).substring("Bearer ".length());
93+
final Long userId = jwtTokenProvider.getUserId(token);
94+
final Optional<User> user = userRepository.findById(userId);
95+
String userInfo = "";
96+
userInfo = user.map(value -> "userId : " + userId
97+
+ "\nyelloId : " + value.getYelloId()
98+
+ "\ndeviceToken : " + value.getDeviceToken()).orElseGet(() -> "userId : " + userId);
99+
slackFieldList.add(
100+
new SlackField().setTitle("인증/인가 정보 - 유저").setValue(userInfo));
101+
102+
slackAttachment.setFields(slackFieldList);
103+
104+
SlackMessage slackMessage = new SlackMessage();
105+
slackMessage.setAttachments(Collections.singletonList(slackAttachment));
106+
slackMessage.setText("긴급 환자가 이송되었습니다");
107+
slackMessage.setUsername("옐로 소방서");
108+
109+
Runnable runnable = () -> slackApi.call(slackMessage);
110+
taskExecutor.execute(runnable);
111+
throw exception;
112+
}
113+
45114
/**
46115
* 400 BAD REQUEST
47116
*/

0 commit comments

Comments
 (0)