우당탕탕 Sentry 도입기 (With Vue3)

현빈·2024년 3월 3일

기술더하기

목록 보기
4/8
post-thumbnail

우리 서비스에 Sentry를,,?

입사한지 3개월 정식계약을 맺은 달 팀장님이 제게 Sentry도입을 맡기셨다.
여지껏 SI와 B2B 회사를 다닌 나는 운영 에러에 대한 고민을 해보지 못했다. (이렇기에 B2C회사로 이직했다)
그렇기에 Sentry에 대해서 무지했고 Sentry를 이용한 운영 에러 관리를 알 수 있는 좋은 기회라 생각이 들었다.
Sentry에 대해 공부하고 적용하면서 알게된 지식들을 남기고자 글을 쓰게 되었다!

Sentry란?

Sentry는 실시간 로그 취합 및 분석 도구이자 모니터링 플랫폼이다.
로그에 대해 다양한 정보를 제공하고 이벤트별, 타임라인으로 얼마나 많은 이벤트가 발생하는지 알 수 있고 설정에 따라 알림을 받을 수 있다.
발생한 로그들을 시각화 도구로 쉽게 분석할 수 있도록 도와주며 다양한 플랫폼을 지원한다.
여기까지가 오피셜적인 Sentry 설명이라면 내가 사용하면서 정의내린 Sentry를 설명하겠다!
Sentry는 실시간 운영 에러에 대한 처리를 손쉽게 도와주는 플랫폼이다.
여기서 손쉽게라고 느껴진 포인트들은 이렇다

  1. 실시간 발생되는 에러들이 대쉬보드에 비슷한 오류 통합하여 보여주니 에러들을 한 눈에 보기 편했다.
    => 같은 이벤트면 하나의 항목에 EVENTS 갯수가 오르며, 발생된 USER수를 USERS에 보여준다.
  2. 에러를 커스텀하여 가치를 높일 수 있고 커스텀한 내용은 에러 상세에 표시된다.
    => 에러 커스텀은 밑에서 자세하게 다루겠다.
  3. 에러에 대한 알림을 여러 플랫폼과 연결할 수 있어 운영중에 에러 관리가 수월해진다.
    => 무료버전에서는 플랫폼 제한이 있지만,,, 그래도 회사에서는 유료버전을 사용하기에 좋다고 느꼈다!
  4. 화면 Replay 기능을 제공하여 에러 발생 시 사용자가 어떤 행위를 했는지 볼 수 있어 좋았다.
    => 에러 발생을 유발 시킨 행위를 알 수 있어 에러 추적이 매우 쉬웠다.

이렇듯 Sentry를 사용하면 유지보수 특히, 운영 중 에러 관리가 매우 손쉬워질 수 있다.

Vue 프로젝트에 Sentry 적용

  1. Sentry 설치
yarn add @sentry/vue
  1. Sentry 설정
    main.js에 Sentry 설정 기입 (자세한 설명은 주석 참고하세요!)
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 소스맵을 제출하는 부분이 포함 되어있다.
그렇기에 Sentry에는 소스맵을 제출하되 프로젝트 빌드 후에는 소스맵을 삭제하는 방식을 도입했다.
(vite vue 기준 입니다.)

  1. vue 프로젝트 설정에 소스맵 설정을 켜준다.
// vite.config.ts
  build: {
	...
    sourcemap: 'hidden',
  },
  1. sentryVitePlugin에 소스맵 관련 설정을 해준다.
// vite.config.ts
plugins: [
	...
    sentryVitePlugin({
	...
      sourcemaps: {
        assets: ['./dist/assets/**'],
        filesToDeleteAfterUpload: ['./dist/assets/*.js.map'],
      },
    }),
  ],
  1. 배포 관련 YAML 파일에 Sentry 시크릿 키를 등록한다. (깃허브 액션 기준)
    해당 키는 Sentry 홈페이지에서 발급 받을 수 있다.
env: SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}

다른 분들은 여기까지 하면 빌드 후 자동으로 소스맵이 삭제 된다고 하는데 삭제 되지 않는 문제점이 발생하였다.
시행 착오 끝에 깃허브 액션 YAML 파일에서 빌드 후 강제로 소스맵을 삭제하는 로직을 추가하였다😔

  1. 배포 관련 YAML 파일에 소스맵 삭제 로직을 추가한다.
 - name: Remove .js.map files
        run: |
          find dist -name "*.js.map" -type f -delete

여기까지 Sentry 초기 설정을 맞췄다!
이제 Sentry 상세 설명을 하겠다!


에러 가치 높이기!

Sentry Issue 대쉬보드를 보면 여러가지 에러들이 보인다.
그 중 에러 하나를 선택해 에러 상세 페이지에 들어가보면 에러에 대한 여러가지 사항들을 볼 수 있다.
여러가지 사항들이 무엇을 의미하고 어떻게 커스텀할지에 대한 내용을 적어보겠다

이벤트 로그

  1. Exception & Message: 이벤트 로그 메시지 및 코드 라인 정보 ⇒ 소스맵 설정 필요

  2. Device: 이벤트 발생 장비 정보 (name, family, model, memory 등)

  3. Browser: 이벤트 발생 브라우저 정보 (name, version 등)

  4. OS: 이벤트 발생 OS 정보 (name, version, build, kernelVersion 등)

  5. Breadcrumbs: 이벤트 발생 과정

이벤트 로그 커스텀

기본 옵저버에서 제공되는 이벤트 로그 말고 코드 상에서 정보를 추가로 제공하여 커스텀 이벤트 로그를 남길 수 있다.
이렇게 하면 에러에 대한 필요한 정보를 손쉽게 얻어 효율을 높일 수 있다.

  1. Context 세팅
    에러 처리 부분에서 콘텍스트 라벨과 넣고싶은 정보를 추가한다.
Sentry.setContext('Api Response Error', {
  status,
  path,
});

에러가 발생되면 아래와 같이 이벤트 로그 Context에 추가로 표시된다.

  1. tag 세팅
    에러 처리 부분에서 tag 네임과 value를 추가한다.
Sentry.withScope((scope) => {
	scope.setTag('type', 'api');
	scope.setTag('api-status', status);
	scope.setTag('api-path', path);
});

에러가 발생되면 아래와 같이 이벤트 로그 tag에 추가로 표시된다.

  1. 에러 네임 설정
    에러 처리 부분에서 이름을 추가한다.
Sentry.withScope((scope) => {
  //new Error(status) 이 부분이 이름이 된다.
      Sentry.captureException(new Error(status));
});

에러가 발생되면 Issue 리스트에 설정한 이름으로 표시된다.

  1. 에러 레벨 설정
    에러 처리 부분에서 레벨을 추가한다.
Sentry.withScope((scope) => {
      scope.setLevel('error');
});

/*
에러 레벨
Fatal = 'fatal',  

Error = 'error',  

Warning = 'warning',  

Log = 'log',  

Info = 'info',  

Debug = 'debug',  

Critical = 'critical',
*/

이렇게 에러 레벨을 설정하면 대쉬보드에서 에러 관리가 수월해 진다!


플랫폼 연동하기!

다양한 플랫폼 연동 가능하나 유료 구독 회원만 지원하는 플랫폼이 대다수

  1. Setting → Integrations 으로 들어가서 원하는 플랫폼 설치

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

  • 어떤 프로젝트의 어떤 환경을 대상으로 할 것인가?
  • WHEN (ex. 새로운 이슈가 생성 됐을때, 해결한 이슈가 다시 발생됐을때 등)
  • IF (ex. 이슈가 10분 이상 경과하면 등)
  • THEN (ex. 연결된 플랫폼으로 알람을 보낸다 등)
    ⇒ 종합하면 새로운 이슈가 생성 됐을 때 이슈가 10분 이상 경과하면 연결된 플랫폼으로 알람을 보낸다.
    (이런 식으로 Alert 설정 가능)
  1. interval과 alert name 설정 하면 끝!
profile
FE = 현빈

1개의 댓글

comment-user-thumbnail
2024년 3월 7일

잘 봤습니다

답글 달기