Spring Boot에서 Sentry, Slack 연동하기
Sentry 시작하기
Sentry는 애플리케이션에서 발생하는 로그를 수집하고 특정 조건에 따라 slack 등으로 알람을 보낼 수 있는 솔루션입니다. 또한 로그에서 오류 발생 위치나 요청 URL, 요청 brower 정보 등 다양한 정보를 수집할 수 있어 오류 분석에 도움이 됩니다.
Sentry는 클라우드 버전과 설치형(On-Premise)버전이 있습니다. 클라우드 버전은 인프라와 솔루션을 제공하기 때문에 편리하게 사용가능하지만 버전에 따라 금액이 책정될 수 있습니다. 무료 버전은 개발자 혼자 사용하고 특정 기능의 제약이 있을 수 있습니다. 설치형은 인프라 구축, 운영을 직접해야 되지만 민감한 정보가 외부로 유출되는 것을 막을 수 있습니다. 여기서는 테스트를 위해 무료 클라우드 버전을 사용 해보겠습니다.
https://sentry.io/signup/ 에서 회원가입을 하여 로그인 합니다.
계정관리에서 Timezone을 서울로 변경합니다.
SpringBoot Sentry 설정 방법
springframework 프로젝트 설정 방법은 아래쪽에서 설명합니다.
Sentry의 SpringBoot 연동은 버전 2.1.0 이상 지원이 됩니다.
Gradle
implementation 'io.sentry:sentry-logback:5.6.2'
implementation 'io.sentry:sentry-spring-boot-starter:5.6.2'
SpringBoot - sentry 설정
application.yml 파일에 DSN을 추가합니다.
DSN(Client Key)은 프로젝트 최초 생성 시 안내 화면 또는 Settings > Project > Client Keys에서도 확인할 수 있습니다.
sentry:
dsn: https://56de5b525b004f0a98a843d430bad707@...
traces-sample-rate: 1.0
send-default-pii: true
logging:
enabled: false
minimum-event-level: error
traces-sample-rate : 1.0 to capture 100% of transactions for performance monitoring
minimum-event-level : sentry issue로 발생시킬 최소 log level
send-default-pii: sentry issue 상세페이지에서 사용자 정보 표시여부(현재 로그인 id, ip정보)
enabled: false true이면 자동으로 sentry 전송. false면 logback에 설정된 profile에 따라 전송할 수 있음.
SpringBoot - logback 설정
https://docs.sentry.io/platforms/java/guides/spring-boot/logging-frameworks/
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<springProperty name="LOG_INFO_PATTERN" source="logging.info-pattern" />
<springProperty name="LOG_ERROR_PATTERN" source="logging.error-pattern" />
<!-- Slack -->
<appender name="SENTRY" class="io.sentry.logback.SentryAppender" />
<!--INFO 로그 콘솔 출력 설정-->
<appender name="INFO_SOUT" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>${LOG_INFO_PATTERN}</pattern>
</encoder>
</appender>
<!--오류 로그 콘솔 출력 설정-->
<appender name="ERROR_SOUT" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder>
<pattern>${LOG_ERROR_PATTERN}</pattern>
</encoder>
</appender>
<!-- 로컬 환경 -->
<springProfile name="local">
<root level="INFO">
<appender-ref ref="INFO_SOUT" />
<appender-ref ref="ERROR_SOUT" />
</root>
</springProfile>
<!-- 개발서버 환경 -->
<springProfile name="dev">
<root level="INFO">
<appender-ref ref="INFO_SOUT" />
<appender-ref ref="ERROR_SOUT" />
</root>
</springProfile>
<!-- 운영 환경 -->
<springProfile name="prod">
<root level="INFO">
<appender-ref ref="SENTRY" />
<appender-ref ref="INFO_SOUT" />
<appender-ref ref="ERROR_SOUT" />
</root>
</springProfile>
</configuration>
SpringBoot - Sentry 테스트
@Controller
public class PostalController {
@GetMapping(value="/sentryTest")
public void sentryTest() {
throw new FailResponseApiException("Error!! Sentry Test!!");
}
@ControllerAdvice
public class CommonExceptionHandler {
private static final String ERROR_PAGE = "error/dispatcher-internal-error";
@ExceptionHandler(FailResponseApiException.class)
public String handleFailResponseApiException(FailResponseApiException e, Model model) {
log.error(e.getMessage(), e);
model.addAttribute(CommonUtil.ERROR_MSSAGE_CODE, ExceptionType.FAIL_RESPONSE_API);
return ERROR_PAGE;
}
...
}
브라우저에서 http://localhost:8080/sentryTest를 호출합니다.
센트리 프로젝트 홈에서 Issues를 확인합니다.
상세 페이지에서 오류메시지, 오류 코드 위치, 요청 URL, 요청 클라이언트 정보 등을 볼 수 있습니다.
Springframework에서 Sentry 설정 방법
프로젝트 생성하기 - 플랫폼 선택화면에서 Java를 선택하면 되고, java 1.8 이상 추천하며
상세 설명은 https://docs.sentry.io/platforms/java/ 를 참조하세요.
java 1.7버전은 설정관련 정보는 https://docs.sentry.io/platforms/java/legacy/ 를 참조할 수 있습니다.
Springframework - sentry 설정
maven에 dependency를 추가합니다.
<dependency>
<groupId>io.sentry</groupId>
<artifactId>sentry-spring</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>io.sentry</groupId>
<artifactId>sentry-logback</artifactId>
<version>1.7.30</version>
</dependency>
/src/main/resources/sentry.properties 파일을 생성하고 DSN코드 넣고 저장합니다.
DSN(Client Key)은 프로젝트 최초 생성 시 안내 화면 또는 Settings > Project > Client Keys에서도 확인할 수 있습니다.
dsn=https://abcf6dadf9934942855bdbcc7ec6b5ff@...
Config 클래스를 생성합니다.
package kdr.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerExceptionResolver;
import io.sentry.spring.SentryExceptionResolver;
@Configuration
public class SentryConfig {
@Bean
public HandlerExceptionResolver sentryExceptionResolver() {
return new SentryExceptionResolver();
}
}
테스트 시에 아래와 같은 오류가 발생한다면?
io.sentry.connection.ConnectionException: An exception occurred while submitting the event to the Sentry server.
....
Caused by: sun.security.validator.ValidatorException: PKIX path building failed
java 1.7 또는 java 1.8(8u202 and earlier) 버전의 경우 sentry 인증서를 처리 못하여 발생하는 오류입니다.
이를 해결하기 위해서는 아래와 같은 순서로 작업하면 됩니다.
-
chrome(안될 시 네이버 웨일)에서 sentry의 DSN 주소로 접속한 다음 인증서 내보내기.
-
java bin경로에 인증서를 copy하고 cmd관리자모드에서 아래 명령 실행.
다운받은 sentry.cer 파일을 jre/lib/security/ 경로로 옮기고 해당 디렉토리의 cacerts 파일은 백업해두고 실행하는 것이 안전합니다.
bin> keytool -import -alias sentry -keystore "C:\Program Files\Java\jdk1.7.0_80\jre\lib\security\cacerts" -file sentry.cer 또는 C:\Program Files\Java\jdk1.7.0_80\jre\bin>keytool -importcert -file "C:/Program Files/Java/jdk1.7.0_80/jre/lib/security/sentry.cer" -alias psentryroduct -keystore "C:/Program Files/Java/jdk1.7.0_80/jre/lib/security/cacerts" 키 저장소 비밀번호 입력: changeit 소유자: CN=*.ingest.sentry.io 발행자: CN=R3, O=Let's Encrypt, C=US ... 이 인증서를 신뢰합니까? [아니오]: 예 인증서가 키 저장소에 추가되었습니다.
-
재시도(동일 오류 발생 시 재부팅 후 재시도.)
참고: https://stackoverflow.com/a/36427118
오류 알림 Slack으로 받기
Slack 좌측 메뉴바에서 채널추가를 눌러 Sentry에서 알람을 받을 채널 하나를 만듭니다.
settings - Integrations - Slack을 추가합니다.
프로젝트 상세 페이지에서 Create Alert를 클릭합니다.
Set Conditions를 클릭합니다.
기본정보 Alert 조건을 설정하고 알람을 받을 Slack정보를 기입합니다.
위에서 작성한 오류 테스트용 /sentryTest를 호출하여 slack에 추가한 채널을 확인합니다.
(주의: 위에서 Set action interval 이내 동일한 오류는 alerting되지 않습니다.)
여기까지 Spring에서 발생한 오류를 Sentry로 전송하고 Alert 기능으로 Slack에게 메시지를 전송하는 것 까지 해보았습니다.
Java 1.7에서 Slack 메시지 전송 시 다음과 같은 오류가 발생할 수 있습니다
javax.net.ssl.SSLException: Received fatal alert: protocol_version
Runtime 시 다음 옵션 추가.
-Dhttps.protocols=TLSv1.2
eclipse 내 tomcat 테스트 시에는 Run - Run Configurations - Arguments탭 - VM arguments에 추가.
intellij의 경우에는 Help -> Edit Custom VM Options
댓글남기기