Sentry는 on premise로 직접 sentry를 띄우면 무료로 팀 계정을 사용할 수 있게 해주는데 이 구축기를 공유해보려한다.
도입 배경
뽀각 서비스를 운영하면서 기존 에러 추적을 위해서 Sentry를 개발 계정으로 한 명이서 관리를 하고 있었다.
무료 계정이다보니 팀원 모두가 사용할 수 없어 불편함이 있어 이를 on premise로 옮기기로 결정!
최소 권장 사양
- 4 CPU Cores
- 16 GB RAM
- 20 GB Free Disk Space
AWS에서 제공하는 프리티어 사양으로는 돌릴 수 없기 때문에 리눅스 컴에 직접 돌리기로 결정하였다.
설치 방법
git clone https://github.com/getsentry/self-hosted.git
cd self-hosted
sudo ./install.sh
sudo docker-compose up -d
이 과정이 Sentry docs에서 제공하는 기본 방법인데 나는 순탄치 않았다..
문제 발생 1
./install.sh
/usr/bin/env: ‘bash\r’: No such file or directory
이는 스크립트 파일에 Windows 형식의 줄바꿈(CRLF, \r\n)이 포함되어 있어서 발생하는 문제인데 스크립트 파일의 줄바꿈 형식을 Unix 형식으로 변경하면 된다.
dos2unix install.sh #unix 스타일로 변경
./install.sh
: invalid option name 1: set: pipefail
set 명령어에 pipefail이라는 option은 없다고 하는데..
이는 bash가 아닌 다른 shell에서 해당 스크립트를 실행하고 있을 수 있다고 한다.
근데 나는 기본 shell이 bash다...
#!/usr/bin/bash #심지어 bash로 실행하라고 명시되어있음
echo "This is a test.0" #어디가 문제인지 로그를 찍어보자
# set -eE
# Pre-pre-flight?
if [[ -n "$MSYSTEM" ]]; then
echo "Seems like you are using an MSYS2-based system (such as Git Bash) which is not supported. Please use WSL instead."
exit 1
fi
echo "This is a test.1" #어디가 문제인지 로그를 찍어보자
source install/_lib.sh
echo "This is a test.2" #어디가 문제인지 로그를 찍어보자
# Pre-flight. No impact yet.
source install/parse-cli.sh
install.sh 파일에 들어가 직접 중간중간 로그를 찍어보았다.
로그를 찍어보니 source install/_lib.sh 여기서 문제가 발생했다.
문제는 sentry가 제공하는 self-hosted 디렉토리는 모두 줄바꿈이 window 형식으로 적용되어있는 것이 문제였다.
find . -type f -exec dos2unix {} \; #모든 파일을 unix 줄바꿈으로 바꿔줌
self-hosted 디렉토리의 모든 파일을 unix 줄바꿈 형식으로 바꾸어주자.
# ./install.sh
...
Would you like to create a user account now? [Y/n]: y
Email: 계정Email
Password: 패스워드
Repeat for confirmation: 패스워드
Should this user have Super Admin role? (This grants them all permissions available) [y/N]: y
이제 정상적으로 돌아가는 모습이다.
이메일, 비번을 넣어 admin 계정을 등록해주자.
이제 http://본인public-ip:9000 으로 접속하면 위와 같은 로그인 페이지를 볼 수 있다.
아까 생성했던 admin의 이메일, 비번을 입력하면 되는데..
문제 발생 2
이메일, 비번을 입력하니 CSRF 인증에 실패했다.
구글링을 통해 해당 sentry의 self-hosted 레포지토리의 이슈 페이지를 발견했다.
https://github.com/getsentry/self-hosted/issues/2751
selt-hosted 디렉토리 안에는 sentry/config.yml이라는 파일이 있는데 설정 중 system.url-prefix: 을 자신의 public ip로 수정해보라고 한다.
# The URL prefix in which Sentry is accessible
# system.url-prefix: https://example.sentry.com <= 얘를 내 ip로 바꾸고 주석을 해제했다.
system.internal-url-prefix: 'http://web:9000'
symbolicator.enabled: true
symbolicator.options:
url: "http://symbolicator:3021"
흠.. 바꿔도 안된다..
sentry.conf.py 파일에 CSRF_TRUSTED_ORIGINS 변수를 포함하도록 구성했나요? 파일을 수정한 후 ./install.sh를 실행했나요? 실행했는데도 작동하지 않았다면 해당 특정 변수의 값을 확인할 수 있나요?
이번엔 sentry.conf.py 의 설정을 바꾸어 보자
#################
# CSRF Settings #
#################
# Since version 24.1.0, Sentry migrated to Django 4 which contains stricter CSRF protection.
# If you are accessing Sentry from multiple domains behind a reverse proxy, you should set
# this to match your IPs/domains. Ports should be included if you are using custom ports.
# https://docs.djangoproject.com/en/4.2/ref/settings/#std-setting-CSRF_TRUSTED_ORIGINS
CSRF_TRUSTED_ORIGINS = ["http://[내 ip]:9000","https://example.com", "http://127.0.0.1:9000"]
CSRF_TRUSTED_ORIGINS에 내 ip를 추가해줬다.
오.. 일단 이걸 하니 CSRF 인증 실패는 뜨지 않고 다시 로그인 페이지로 리다이렉션된다.
진전이 있다.
여러가지 고민을 하던중 sentry/config.yml 파일의 SSL/TLS 설정을 바꾸어주었던 기억이났다.
###########
# SSL/TLS #
###########
# If you're using a reverse SSL proxy, you should enable the X-Forwarded-Proto
# header and enable the settings below
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
USE_X_FORWARDED_HOST = True
# 아래 세 개 설정을 모두 False로 변경하였다. 기본은 주석처리되어 있던 것으로 안다.
SESSION_COOKIE_SECURE = False
CSRF_COOKIE_SECURE = False
SOCIAL_AUTH_REDIRECT_IS_HTTPS = False
# CSRF_TRUSTED_ORIGINS = ["example.com", "127.0.0.1:9000"] 같이 바꿔봐라
# End of SSL/TLS settings
SESSION_COOKIE_SECURE 설정을 True로 하면 HTTPS 연결에서만 세션 쿠키가 전송되고 False로 하면 http, https 모두 쿠키 전송이 된다.
현재 ip에는 https 설정이 안되어 있으므로 False로 해야한다.
밑에 나머지 설정들도 https에서만 가능하게 하는 설정이므로 모두 꺼준다.
이제 로그인에 성공하는 모습이다.
별도의 설정없이 continue를 해주어도 된다.
성공이다!
Spring Boot 설정하기
//sentry
implementation 'io.sentry:sentry-spring-boot-starter-jakarta:7.14.0'
sentry를 gradle에 적용해주고
sentry:
dsn: ${SENTRY_DSN}
enable-tracing: true
tracesSampleRate: 1.0
debug: true
environment: local
- dsn: ${SENTRY_DSN}: Sentry에 이벤트를 전송하기 위한 데이터 소스 네임(DSN)을 환경 변수에서 불러옴
- enable-tracing: true: 트랜잭션 추적을 활성화하여 성능 데이터를 수집.
- tracesSampleRate: 1.0: 100%의 트랜잭션을 샘플링하여 Sentry에 전송함.
- debug: true: 디버그 모드를 활성화하여 Sentry의 상세 로그를 출력.
- environment: local: 현재 환경을 'local'로 설정하여, Sentry에서 환경별 오류 및 성능 데이터를 구분.
import com.server.bbo_gak.global.error.exception.BusinessException;
import io.sentry.Sentry;
import io.sentry.SentryOptions;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SentryConfig {
@Value("${sentry.dsn}")
private String dsn;
@Bean
public Sentry.OptionsConfiguration<SentryOptions> sentryOptions() {
return options -> {
options.setDsn(dsn);
options.setBeforeSend((event, hint) -> {
// 특정 예외 필터링 로직
if (event.getThrowable() != null && event.getThrowable() instanceof BusinessException) {
return null; // 이 이벤트는 Sentry로 전송되지 않음
}
return event; // 필터링하지 않을 경우, 이벤트 반환
});
};
}
}
위와 같이 SentryConfig를 작성해서 원치 않는 예외는 Sentry로 전송하지 않을 수 있다.
일단 handling 하지 않고 있는 500번대 에러만 보내기로 하였다.
예외가 잘 모니터링 되고 있는 것을 확인할 수 있다.
마치며..
Sentry를 on premise로 적용하면서 비용 부과 없이 모니터링 환경을 구축할 수 있게되었다.
팀원들이 불편하지 않게 쓸 수 있게 된 것 같아 기쁘다.
'spring' 카테고리의 다른 글
Java reflection을 통해 RestDocs 생성 테스트 코드 작성 시간 1/2로 줄이기 (2) | 2024.09.27 |
---|---|
[스프링] service 인터페이스 도입과 접근제한자 (1) | 2024.09.20 |
[spring security] 왜 500번 에러도 401(Unauthorized)에러가 될까? (0) | 2024.04.07 |
이미지 저장/조회 서버 만들기(3) - AWS Presigned URL 이미지 업로드 (0) | 2024.02.26 |
이미지 저장/조회 서버 만들기(2) - 이미지 파일 어떻게 받아오지? (0) | 2024.02.12 |