Skip to content

Commit

Permalink
[OING-208] feat: Sentry 고도화 (#186)
Browse files Browse the repository at this point in the history
* chore: Divide Sentry environment to dev and prod

* feat: Advance Sentry captureException and Extract it as SentryGateway component

* feat: Add Sentry capture at JWT token exception handler that is not handled from SpringWebExceptionHandler(JwtAuthenticationEntryPoint, JwtAccessDeniedHandler)
  • Loading branch information
Kwon770 authored Feb 27, 2024
1 parent 7e6bbef commit 17c82e5
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 25 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
secrets:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_DEV_AUTH_TOKEN }}

call-deploy-workflow:
if: github.event_name == 'push'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ jobs:
secrets:
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
DOCKER_PASSWORD: ${{ secrets.DOCKER_PASSWORD }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_PROD_AUTH_TOKEN }}

call-deploy-workflow:
if: github.event_name == 'push'
Expand Down
61 changes: 61 additions & 0 deletions gateway/src/main/java/com/oing/component/SentryGateway.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.oing.component;

import io.sentry.Sentry;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

@Component
@RequiredArgsConstructor
public class SentryGateway {

public static void captureException(HttpServletRequest request, Throwable exception) {
// Add extra data to future events in this scope.
Sentry.withScope(scope -> {
scope.setExtra("method", request.getMethod());

if (!request.getQueryString().isEmpty()) {
scope.setExtra("queryString", request.getQueryString());
}
if (!request.getRequestURI().isEmpty()) {
scope.setExtra("requestURI", request.getRequestURI());
}
if (!request.getRequestURL().isEmpty()) {
scope.setExtra("requestURL", request.getRequestURL().toString());
}
if (!request.getParameterMap().isEmpty()) {
for (String key : request.getParameterMap().keySet()) {
scope.setExtra(key, request.getParameter(key));
}
}
if (request.getContentLength() > 0) { // if request body is not empty
scope.setExtra("requestBody", getBody(request));
}

Sentry.captureException(exception);
});

}

private static String getBody(HttpServletRequest request) {
try (
InputStream inputStream = request.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))
) {
StringBuilder stringBuilder = new StringBuilder();
while (bufferedReader.ready()) {
stringBuilder.append(bufferedReader.readLine());
}

return stringBuilder.toString();

} catch (IOException e) {
return "Error reading the request body";
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package com.oing.config;

import com.google.common.io.CharStreams;
import com.oing.component.SentryGateway;
import com.oing.domain.ErrorReportDTO;
import com.oing.dto.response.ErrorResponse;
import com.oing.exception.TokenNotValidException;
import com.oing.exception.DomainException;
import com.oing.exception.ErrorCode;
import io.sentry.Sentry;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.ConstraintViolationException;
import lombok.RequiredArgsConstructor;
Expand All @@ -28,12 +28,6 @@
import java.security.InvalidParameterException;
import java.util.Enumeration;

/**
* server
* User: CChuYong
* Date: 2023/11/22
* Time: 4:32 PM
*/
@RequiredArgsConstructor
@Slf4j
@RestControllerAdvice
Expand All @@ -42,7 +36,7 @@ public class SpringWebExceptionHandler {

@ExceptionHandler(DomainException.class)
ResponseEntity<ErrorResponse> handleDomainException(HttpServletRequest request, DomainException exception) {
Sentry.captureException(exception);
SentryGateway.captureException(request, exception);
log.debug("[DomainException]", exception);
if (exception.getErrorCode() == ErrorCode.UNKNOWN_SERVER_ERROR) {
return handleUnhandledException(request, exception);
Expand All @@ -61,8 +55,8 @@ ResponseEntity<ErrorResponse> handleDomainException(HttpServletRequest request,
ConstraintViolationException.class,
MethodArgumentTypeMismatchException.class,
})
ResponseEntity<ErrorResponse> handleValidateException(Exception exception) {
Sentry.captureException(exception);
ResponseEntity<ErrorResponse> handleValidateException(HttpServletRequest request, Exception exception) {
SentryGateway.captureException(request, exception);
log.warn("[InvalidParameterException]", exception);

return ResponseEntity
Expand All @@ -73,8 +67,8 @@ ResponseEntity<ErrorResponse> handleValidateException(Exception exception) {
@ExceptionHandler(value = {
HttpRequestMethodNotSupportedException.class,
})
ResponseEntity<ErrorResponse> handleMethodNotAllowedException(HttpRequestMethodNotSupportedException exception) {
Sentry.captureException(exception);
ResponseEntity<ErrorResponse> handleMethodNotAllowedException(HttpServletRequest request, HttpRequestMethodNotSupportedException exception) {
SentryGateway.captureException(request, exception);
log.warn("[HttpRequestMethodNotSupportedException]", exception);

return ResponseEntity
Expand All @@ -83,8 +77,8 @@ ResponseEntity<ErrorResponse> handleMethodNotAllowedException(HttpRequestMethodN
}

@ExceptionHandler(TokenNotValidException.class)
ResponseEntity<ErrorResponse> handleAuthenticationFailedException(TokenNotValidException exception) {
Sentry.captureException(exception);
ResponseEntity<ErrorResponse> handleAuthenticationFailedException(HttpServletRequest request, TokenNotValidException exception) {
SentryGateway.captureException(request, exception);
log.warn("[AuthenticationFailedException]", exception);

return ResponseEntity
Expand All @@ -94,7 +88,7 @@ ResponseEntity<ErrorResponse> handleAuthenticationFailedException(TokenNotValidE

@ExceptionHandler(IOException.class)
ResponseEntity<ErrorResponse> handleClientCancelException(HttpServletRequest request, IOException exception) {
Sentry.captureException(exception);
SentryGateway.captureException(request, exception);
if (exception.getMessage().contains("Broken pipe")) {
log.warn("[IOException] Broken Pipe");
} else {
Expand All @@ -109,7 +103,7 @@ ResponseEntity<ErrorResponse> handleClientCancelException(HttpServletRequest req

@ExceptionHandler(Throwable.class)
ResponseEntity<ErrorResponse> handleUnhandledException(HttpServletRequest request, Throwable exception) {
Sentry.captureException(exception);
SentryGateway.captureException(request, exception);
StringBuilder dump = dumpRequest(request).append("\n ").append(getStackTraceAsString(exception));
log.error("[UnhandledException] {} \n", dump);

Expand All @@ -119,6 +113,7 @@ ResponseEntity<ErrorResponse> handleUnhandledException(HttpServletRequest reques
.body(ErrorResponse.of(ErrorCode.UNKNOWN_SERVER_ERROR));
}


private String getStackTraceAsString(Throwable throwable) {
StringWriter stringWriter = new StringWriter();
throwable.printStackTrace(new PrintWriter(stringWriter));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.oing.config.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.oing.component.SentryGateway;
import com.oing.dto.response.ErrorResponse;
import com.oing.exception.ErrorCode;
import jakarta.servlet.ServletException;
Expand Down Expand Up @@ -30,6 +31,7 @@ public void handle(
HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException
) throws IOException, ServletException {
writeErrorResponse(response, accessDeniedException);
SentryGateway.captureException(request, accessDeniedException);
}

private void writeErrorResponse(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.oing.config.filter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.oing.component.SentryGateway;
import com.oing.dto.response.ErrorResponse;
import com.oing.exception.ErrorCode;
import jakarta.servlet.http.HttpServletRequest;
Expand Down Expand Up @@ -29,6 +30,7 @@ public void commence(
HttpServletRequest request, HttpServletResponse response, AuthenticationException authException
) throws IOException {
writeErrorResponse(response, authException);
SentryGateway.captureException(request, authException);
}

private void writeErrorResponse(
Expand Down
9 changes: 9 additions & 0 deletions gateway/src/main/resources/application-dev.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,12 @@ management:
web:
exposure:
include: health,info,prometheus

sentry:
environment: development
logging:
enabled: true
minimum-event-level: info
minimum-breadcrumb-level: info
dsn: ${SENTRY_DEV_DSN:}
traces-sample-rate: 1.0
11 changes: 11 additions & 0 deletions gateway/src/main/resources/application-prod.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,14 @@ management:
web:
exposure:
include: health,info,prometheus

sentry:
environment: production
logging:
enabled: true
minimum-event-level: info
minimum-breadcrumb-level: info
dsn: ${SENTRY_PROD_DSN:}
# Set traces-sample-rate to 1.0 to capture 100% of transactions for performance monitoring.
# We recommend adjusting this value in production.
traces-sample-rate: 0.8
8 changes: 1 addition & 7 deletions gateway/src/main/resources/application.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,4 @@ management:
endpoints:
web:
exposure:
include: health,info,prometheus

sentry:
dsn: ${SENTRY_DSN:}
# Set traces-sample-rate to 1.0 to capture 100% of transactions for performance monitoring.
# We recommend adjusting this value in production.
traces-sample-rate: 0.5
include: health,info,prometheus

0 comments on commit 17c82e5

Please sign in to comment.