프로젝트 에러관리 - Sentry self-hosted 적용 이유
우리 회사는 스타트업이긴 하지만 시리즈 C투자를 받을 정도로 매출이 있고 전망이 밝은 회사다.
그럼에도 불구하고 아래와 같은 순서로 에러에 대응하고 있었다.
[Sentry 적용 전 서비스 에러 발생시]
1. 유저의 문의
2. 제휴팀에서 캡처요구 및 에러발생시간, 경로 등을 구두로 소통하여 정보 획득
3. 개발팀에 전달
4. 전달받은 정보를 토대로 에러 재현 및 코드 분석
이런 과정을 통해 개발자에게 전달되기까지 어마어마한 에너지의 손실이 발생한다.
마치 퍼널처럼 걸러지고 걸러져서 담당 개발자에게 온전히 전달되는 에러건은 실제 발생건의 아주 일부일 것이다.
심지어 고객이 "화면에 뻐끔뻐끔뻐끔이라는 글자만 나와요!" 라고 하면 정말 난감하다.

"화면에 뻐끔뻐끔뻐끔이라는 글자만 나와요!" 라는 고객의 제보를 듣고 이런 상황을 밝혀내기까지 얼마나 많은 에너지가 소모될까.
위 과정을 자세히 생각해 보면
1단계 유저의 문의부터 대폭 걸러진다. 에러에 불만을 가지고 무려 '캡처'를 해주는 유저가 몇이나 될까?
나는 안되면 그냥 떠나버리는 유저로써 무려 '캡쳐'를 해주는 유저에게는 절이라도 해야 한다고 생각한다.
2단계 제휴팀에서 실제 유저와 통화를 하는데, 이때 유용한 정보가 다시 한번 걸러진다.
애써 '캡처'에 '전화'까지 한 유저로부터 에러 해결에 유용한 정보를 획득하지 못한다. 개발자가 아니니 당연하다.
3단계 개발팀에 전달하면서 다시 한번 에너지가 새어나간다.
4단계가 제일 현타 오게 만들었던 이유인데 유저가 캡처한 사진과 구두로 전달받은 내용을 가지고 에러 재현에 나선다.
사실 말이 캡처지 개발자도구 캡처가 아니라 그냥 404 에러 화면에 url이라도 있으면 다행이다.
제휴팀으로 전달받은 내용으로 에러를 재현하려면
스스로 짠 코드를 부정하며 제삼자의 객관적인 눈으로 내 뇌를 바라보는 명상의 시간이 필요하다.
이런 과정을 줄이고 우리를 찾아준 유저에게 불편함 없는 서비스를 제공하려면
유저가 말하지 않아도 알아서 선제적인 대응이 필요하다고 생각하게 되었다.
다른 서비스들은 어떻게 대응하는지 찾아보니 sentry나 LogRocket 같은 서비스를 이용하고 있었다.
나는 이런저런 점들을 비교해서 Sentry를 적용하기로 결정했고
본부장님께 강력한 건의를 드려서 Sentry를 적용하기 위한 시간을 얻었다.
비용문제로 온프레미스 방식의 self-hosted 서비스를 이용했다.
이를 통해 다음과 같이 에러관리를 하고자 한다.
[Sentry 적용 후 서비스 에러 발생 시]
1. 유저에게 에러 발생 시 에러 해결에 필요한 정보가 담긴 로그를 저장하고 개발자에게 실시간으로 알려준다.
끝! 에너지의 손실 없이 모든 에러가 100% 개발자에게 도달한다.
이로써 제휴팀의 인력까지 아낄 수 있다.. 안 할 이유가 없다.
Self-hosted 방식은 sentry.io의 서비스를 클라우드방식으로 사용하는 게 아니라
우리 인프라에 서비스를 유지하는 방식이다.
나는 아직 리눅스 클라우드 컴퓨터를 다루는데 익숙하지 않고 Docker도 처음 경험하다 보니 꽤 오랜 시간이 걸렸고
에러도 엄청나게 많이 만났다..
일단 ec2를 하나 만든다. 리눅스 컴퓨터를 하나 빌린 것이다. 이 ec2에 원격으로 접속한다.
https://github.com/getsentry/self-hosted
위 레포에 보면 센트리 self hosted를 구현하기 위한 최소한의 스펙이 명시되어 있다. 참고하여 스펙을 충족하는 ec2를 빌리자.
이 컴퓨터에 잘 접속했다면 Docker와 docker-compose를 설치한다.
(아래의 모든 과정은 https://yumserv.tistory.com/440 YUMSERV님의 블로그를 참고했습니다)
yum install docker-ce-19.03.6 docker-ce-cli-v containerd.io-1.4.4 docker-compose-plugin
curl -SsL "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/bin/docker-compose
chmod 755 /usr/bin/docker-compose
참고한 블로그에도 아래 명령에 대한 설명이 없었는데 도커 데몬을 띄워주는 명령인 것 같다.
systemctl start docker
systemctl enable docker
설치했으면 버전을 확인해 보자, 위 레포에 도커버전도 명시되어 있으니 최소버전 이상의 도커를 설치하자.
docker version
docker-compose version
여기까지 하면 내가 빌린 ec2에 도커가 설치되었으니 이제 sentry selfhosted 레포를 클론 받아서 설치해 준다.
# mkdir /data/sentry-self-hosted
# cd /data/sentry-self-hosted/
# git clone https://github.com/getsentry/self-hosted.git .
# vi .env
YUMSERV님은 환경변수 파일에 들어가서 SENTRY_EVENT_RETENTION_DAYS=180으로 수정하셨는데
나는 아직 이게 뭔지 파악이 안 되어서 수정은 안 했다.
여기까지 하면 컴퓨터의 sentry-self-hosted 폴더에 프로젝트가 클론 되어 파일들이 생겼다.
이중에 install.sh라는 쉘스크립트 파일이 있다. 이걸 실행해 준다.
./install.sh
쉘스크립트 파일이란 리눅스 명령줄을 담고 있는 파일인데, Sentry개발자들이 이 파일만 실행하면 알아서 설치가 되도록
리눅스 명령을 입력해 놓았다. 궁금해서 로컬에 클론을 받아서 봤더니

이런 명령이 있다. 무슨 말인지는 모르겠다. 추측하건대, 이 파일을 실행함으로써 install 폴더 안에 있는 또 다른 sh파일들이 실행된다.
예를 들어 하나만 보면 build-docker-images.sh가 실행되는데 이 파일은 이렇게 생겼다.

역시 무슨 말인지 모르겠다.
하나하나는 무슨말인지 모르지만 일단 install.sh를 실행하면 저런 파일들이 실행되면서 내 ec2에 도커 이미지들을 만들어 준다.
그리고 마지막에 이런 안내가 나온다

docker-compose up -d 명령을 입력하라고 한다.
docker-compose는 쉘스크립트 파일과 비슷하게 도커명령을 알아서 잘 수행해 주는 명령들을 모아놓은 파일이라고 볼 수 있다.
위 파일도 궁금하면 로컬에서 볼 수 있다.

sentry개발자들이 잘 써놓은 docker-compose를 실행하면 위에서 만든 이미지들이 실행되며 컨테이너가 생성된다.
컨테이너가 모두 실행되면 9000번 포트로 센트리 self-hosted 접속이 가능해진다.
예를 들면 http://20.20.20.20:9000 으로 접속하면 서비스가 잘 로드된 것을 볼 수 있다.
이제 내 프로젝트에 가서 이 서버와 연결을 해주면 된다.
추가적으로 서비스를 운영환경에 배포하려니 https에서 http로 request를 보내면서 mixed contents에러가 발생했다.
그래서 나의 ec2에 https설정을 해야 했는데, 내가 하다가 한계에 봉착하여 다른 개발자분이 도와주셨다.
위 과정에서 수많은 에러를 만나면서 한 7일 정도 소요되었는데,
docker나 ec2관련 인프라 관련 지식들까지.. 꽤나 배움이 있으면서도 힘든 시간이었다.
무엇보다 이제부터 에러를 에너지 손실 없이 받고 관리할 수 있다는 점이 굉장히 만족스럽다.
앞으로는 sentry를 공부하고 사용하면서 배우는 것들도 종종 업로드할 예정이다.