입사한지 3개월 정식계약을 맺은 달 팀장님이 제게 Sentry도입을 맡기셨다.
여지껏 SI와 B2B 회사를 다닌 나는 운영 에러에 대한 고민을 해보지 못했다. (이렇기에 B2C회사로 이직했다)
그렇기에 Sentry에 대해서 무지했고 Sentry를 이용한 운영 에러 관리를 알 수 있는 좋은 기회라 생각이 들었다.
Sentry에 대해 공부하고 적용하면서 알게된 지식들을 남기고자 글을 쓰게 되었다!
Sentry는 실시간 로그 취합 및 분석 도구이자 모니터링 플랫폼이다.
로그에 대해 다양한 정보를 제공하고 이벤트별, 타임라인으로 얼마나 많은 이벤트가 발생하는지 알 수 있고 설정에 따라 알림을 받을 수 있다.
발생한 로그들을 시각화 도구로 쉽게 분석할 수 있도록 도와주며 다양한 플랫폼을 지원한다.
여기까지가 오피셜적인 Sentry 설명이라면 내가 사용하면서 정의내린 Sentry를 설명하겠다!
Sentry는 실시간 운영 에러에 대한 처리를 손쉽게 도와주는 플랫폼이다.
여기서 손쉽게라고 느껴진 포인트들은 이렇다

이렇듯 Sentry를 사용하면 유지보수 특히, 운영 중 에러 관리가 매우 손쉬워질 수 있다.
yarn add @sentry/vue
Sentry.init({
app,
// dsn: 이벤트를 전송하기 위한 식별 키 (Sentry 홈페이지에서 발급)
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
// environment: 애플리케이션 환경 (개발 테스트 환경 또는 운영 환경)
environment: "prod",
// debug: true일 경우 Sentry SDK가 디버그 모드로 작동
// 브라우저 콘솔에 더 많은 디버깅 정보를 출력하게 됩니다. / 운영 환경에서는 false 추천
debug: false,
// integrations: 플랫폼 SDK별 통합 구성 설정
integrations: [
// Breadcrumbs를 활성화 및 콘솔(console) 이벤트를 기록하도록 설정됨 (Breadcrumbs 관련은 하기 참조!)
new Sentry.Integrations.Breadcrumbs({ console: true }),
//Browser Tracing: 브라우저에서의 트레이싱을 활성화
new Sentry.BrowserTracing({
// 트레이싱은 애플리케이션 내에서의 성능 이슈를 식별하는 데 사용
// tracingOrigin 및 tracePropagationTargets는 트레이싱의 대상을 설정
tracingOrigins: ['*'],
tracePropagationTargets: ['*'],
// Vue.js 라우터의 인스턴스를 받아 Sentry에 라우팅 이벤트를 보고할 수 있도록 도와주는 도구
// 라우터 이벤트의 추적은 사용자 경험을 모니터링하고, 발생한 오류와 연결된 페이지 정보를 제공하는 데 유용
routingInstrumentation: Sentry.vueRouterInstrumentation(options.router),
}),
// Replay를 활성화 (Sentry에 화면 기록이 저장됨)
new Sentry.Replay(),
],
// ignoreErrors: 특정 종류의 에러를 무시하도록 Sentry에게 지시
// ResizeObserver loop limit exceeded 에러는 성능에 문제는 되지 않고 해결하기는 어려워 보편적으로 제외 시킴
ignoreErrors: ['ResizeObserver loop limit exceeded'],
// tracesSampleRate: 성능 모니터링을 위한 트랜잭션 샘플링 비율을 설정
// 모든 트랜잭션을 모니터링하여 애플리케이션의 전반적인 성능을 파악하는 데 도움
// 만약 이 값을 낮추면 일부 트랜잭션만을 샘플링하여 전체 데이터 양을 줄임
// 그러면 에러 또는 성능 문제가 발생한 트랜잭션을 감지하는 데 시간이 걸릴 수 있음
tracesSampleRate: 1.0,
// Replay 관련 설정
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
});
현재 우리 프로젝트는 보안을 위해 소스맵을 등록하지 않고 있다.
이렇기에 Sentry에서 에러를 추적하려 해도 어느 파일에서 발생했는지 알 수 없다.
에러 상세에서 표시되는건 암호화된 소스 파일로 보여지고 있다,,
프로젝트 빌드 과정에 Sentry 소스맵을 제출하는 부분이 포함 되어있다.
그렇기에 Sentry에는 소스맵을 제출하되 프로젝트 빌드 후에는 소스맵을 삭제하는 방식을 도입했다.
(vite vue 기준 입니다.)
// vite.config.ts
build: {
...
sourcemap: 'hidden',
},
// vite.config.ts
plugins: [
...
sentryVitePlugin({
...
sourcemaps: {
assets: ['./dist/assets/**'],
filesToDeleteAfterUpload: ['./dist/assets/*.js.map'],
},
}),
],
env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
다른 분들은 여기까지 하면 빌드 후 자동으로 소스맵이 삭제 된다고 하는데 삭제 되지 않는 문제점이 발생하였다.
시행 착오 끝에 깃허브 액션 YAML 파일에서 빌드 후 강제로 소스맵을 삭제하는 로직을 추가하였다😔
- name: Remove .js.map files
run: |
find dist -name "*.js.map" -type f -delete
여기까지 Sentry 초기 설정을 맞췄다!
이제 Sentry 상세 설명을 하겠다!
Sentry Issue 대쉬보드를 보면 여러가지 에러들이 보인다.
그 중 에러 하나를 선택해 에러 상세 페이지에 들어가보면 에러에 대한 여러가지 사항들을 볼 수 있다.
여러가지 사항들이 무엇을 의미하고 어떻게 커스텀할지에 대한 내용을 적어보겠다
기본 옵저버에서 제공되는 이벤트 로그 말고 코드 상에서 정보를 추가로 제공하여 커스텀 이벤트 로그를 남길 수 있다.
이렇게 하면 에러에 대한 필요한 정보를 손쉽게 얻어 효율을 높일 수 있다.
Sentry.setContext('Api Response Error', {
status,
path,
});
에러가 발생되면 아래와 같이 이벤트 로그 Context에 추가로 표시된다.

Sentry.withScope((scope) => {
scope.setTag('type', 'api');
scope.setTag('api-status', status);
scope.setTag('api-path', path);
});
에러가 발생되면 아래와 같이 이벤트 로그 tag에 추가로 표시된다.

Sentry.withScope((scope) => {
//new Error(status) 이 부분이 이름이 된다.
Sentry.captureException(new Error(status));
});
에러가 발생되면 Issue 리스트에 설정한 이름으로 표시된다.

Sentry.withScope((scope) => {
scope.setLevel('error');
});
/*
에러 레벨
Fatal = 'fatal',
Error = 'error',
Warning = 'warning',
Log = 'log',
Info = 'info',
Debug = 'debug',
Critical = 'critical',
*/
이렇게 에러 레벨을 설정하면 대쉬보드에서 에러 관리가 수월해 진다!
다양한 플랫폼 연동 가능하나 유료 구독 회원만 지원하는 플랫폼이 대다수
Setting → Integrations 으로 들어가서 원하는 플랫폼 설치

Alert 진입 후 Create Alert 클릭 후 Alert rule 설정

잘 봤습니다