Sentry로 에러 모니터링하기(React/Vite)

date
Apr 4, 2024
slug
sentry
author
status
Public
tags
Sentry
summary
type
Post
thumbnail
blue-3.jpg
category
updatedAt
Jun 9, 2024 12:49 PM

Sentry란?

실시간 로그 취합 분석 도구 / 모니터링 플랫폼
로그에 대한 정보 제공 및 시각화 도구를 통해 발생한 이벤트들을 쉽게 분석할 수 있게 도와줍니다.
 

Sentry 적용을 통해 얻을 수 있는 효과

notion image
  • 에러 원인을 파악하고 정확하게 안내할 수 있게됩니다.
  • 특정 오류 재현에 오랜 시간을 들이지 않아도 에러 추적이 가능합니다.
 

프론트엔드 환경에서 발생할 수 있는 에러는 어떤 것들이 있을까?

  • 데이터 영역에서의 에러
  • 화면 영역에서의 에러
  • 외부요인에 의한 에러
  • 런타임 에러
 

시작하기

Sentry 계정 가입 후 프로젝트 생성

 
*Sentry를 이용한 에러 추적 프로세스
에러 데이터 쌓기 → severity 기준 설정 및 모니터링 → 에러 데이터 분석 → 분석 결과에 따른 개선
 
*Sentry SDK  7.47.0 이상부터 아래 설정을 적용할 수 있습니다. 아래 방법을 적용하면 Sentry에 sourcemap 업로드 & sourcemap 버전 관리를 자동화 할 수 있습니다.
⚠️ @sentry/tracing 모듈은 설치하지 않아도 됩니다. sentry sdk의 7.47.0 부터 해당 모듈은 deprecated 되었습니다.
npx @sentry/wizard@latest -i sourcemaps
sentry cli가 활성화 됩니다.
 
notion image
notion image
Sentry SDK가 없어보이는데, 설치할지를 친절하게 물어봐줍니다.
notion image
Sentry SaaS를 선택해주세요.
기존에 Sentry계정이 있다면, 계정 연동 후 cmd에 project를 선택하도록 나옵니다.
 
설치가 완료되면, .env.sentry-build-plugin 이라는 파일이 하나 생성됩니다. 이 파일에 auth_token 값을 가져다 .env 와 빌드 환경변수에 넣어주세요. env의 key값은 SENTRY_AUTH_TOKEN 로 적용해주세요.
 
notion image
cli로 진행 중 (sentry/react or sentry/vite-plugin)모듈 설치에 실패한 경우 직접 설치해주세요.
*sentry/react 모듈 설치
yarn add @sentry/react
*sentry/vite-plugin 설치
npm install @sentry/vite-plugin --save-dev
 

설정

ReactDOM이 createRoot를 사용해 DOM에 react를 붙이는 root파일에 Sentry.init 메서드를 추가합니다.
import ReactDOM from 'react-dom/client'; import App from './App.tsx'; import './index.css'; import './i18n/i18n.ts'; import * as Sentry from '@sentry/react'; Sentry.init({ dsn: import.meta.env.VITE_SENTRY_DSN, integrations: [ Sentry.browserTracingIntegration({}), Sentry.replayIntegration({ maskAllText: false, blockAllMedia: false, }), ], tracesSampleRate: 1.0, tracePropagationTargets: ['https://www.tour-bus.zzimcar.com'], replaysSessionSampleRate: 0.1, replaysOnErrorSampleRate: 1.0, }); ReactDOM.createRoot(document.getElementById('root')!).render(<App />);
*DSN은 Settings > project > Client Keys에서 확인 가능합니다.
이미지 참고
notion image
 

options에는 어떤 것들이 있을까?

  • dsn(data source name) 이벤트를 전송하기 위한 식별 키
  • release 애플리케이션 버전 (보통 package.json에 명시한 버전을 사용합니다. 이는 버전별 오류 추적을 용이하게 합니다.)
  • environment 애플리케이션 환경 (dev, production 등)
  • normalizeDepth 컨텍스트 데이터를 주어진 깊이로 정규화 (기본값: 3)
  • integrations 플랫폼 SDK별 통합 구성 설정 (React의 경우 react-router integration 설정 가능)
  • maxBreadcrumbs
    • 최대 breadcrumb의 양을 제어 (최근 n개의 데이터만 유지하고 삭제한다)
  • tracesSampleRate
    • Sentry에 보내는 트랜잭션의 샘플 비율 (0.0 ~ 1.0)
      너무 많은 이벤트를 기록하지 않도록 부하를 조절
  • tracePropagationTargets 설정된 URL 패턴에 대해서만 추적 정보를 전파
  • replaysSessionSampleRate
    • Sentry SDK에서 세션 리플레이 기능의 샘플링 비율을 제어
  • replaysOnErrorSampleRate
    • 오류가 발생한 세션 중 어느 정도의 비율로 리플레이 데이터를 수집할지 결정
       

배포 관련 sourcemap 설정하기

Sentry에 sourcemap을 업로드 하지 않으면, 오류 로깅 시 난독화된 소스코드가 나와 디버깅이 어렵습니다.
하지만 sourcemap을 번들에 포함하게 되면 외부에 코드가 그대로 유출되지요.
따라서, sourcemap을 Sentry에 업로드한 다음 삭제하는 작업이 필요합니다.
 
@sentry/vite-plugin 을 사용하면 위 작업을 할 수 있습니다.
sourcemaps 프로퍼티의 filesToDeleteAfterUpload 설정해 dist파일의 .map 파일 삭제하기
//vite.config.ts export default defineConfig({ plugins:[ sentryVitePlugin({ org: 'personal-org', project: 'project name', sourcemaps: { filesToDeleteAfterUpload: './dist/**/*.map', }, authToken: 'secret' }), })
notion image
 

각 sourcemap이 버전별로 업로드 되고 있는지 확인하려면

  1. 왼쪽 사이드바의 Releases 클릭
notion image
  1. Release항목 중 최근 버전의 Source Maps 확인
notion image
notion image
notion image
해당 파일 목록을 보면 소스맵(.map 파일)과 번들링된 js파일이 함께 업로드 되는 것을 볼 수 있습니다.
Sentry는 js와 소스맵을 비교해 오류가 발생한 경우 소스맵에서 어떤 요소에 오류가 발생했는지 보고해줍니다.
 

슬랙에 Sentry관련 Alert 추가하기

⇒ 프로젝트 선택 및 Slack 워크스페이스 / 채널 선택 / 태그 설정이 필요합니다.
notion image
 

Sentry설치 후 vite에서 Some chunks are larger than 500 kBs after minification 경고 메세지가 출력된다면 → 번들링 최적화가 필요한 시점!

notion image
※ manification(= 축소, 최소화)
: 웹 사이트에서 로드 시간과 대역폭 사용량을 줄이는 데 사용되는 주요 방법 중 하나로 웹 페이지 및 스크립트 파일에서 코드 및 마크업을 최소화하는 프로세스.
*vite는 dev- esm / prod - Rollup을 builder로 사용합니다.
 

번들링 최적화하기

  1. vite에서 splitVendorChunkPlugin을 import합니다. (vite 공식 문서를 참고했습니다.)
    1. manualChunks을 사용하려면 splitVendorChunkPlugin을 import 해줘야합니다.
notion image
import { defineConfig, type PluginOption, splitVendorChunkPlugin } from 'vite';
 
  1. rollupOptions의 output필드에 manualChunks 함수를 사용해 chunk크기가 큰 @sentry 를 기존 node_modules를 하나의 vendor.js chunk로 만드는 과정에서 분리해 보겠습니다. 이 방법을 적용하면 sentry는 별도의 한 chunk 파일로 생성됩니다. 위 옵션 적용 시, manualChunks는 객체 형태가 아닌 함수 형태로 작성해야 합니다!
notion image
  • rollupOptions는 Rollup 플러그인 옵션을 구성할 수 있게 해주는 Vite 옵션입니다.
    • 내부의 output 옵션은 Rollup 출력 옵션을 구성합니다.
  • manualChunks 함수는 코드 분할(code splitting)수동으로 제어할 수 있게 해줍니다.
    • 이 함수는 모듈 ID를 받아 청크(chunk) 이름을 반환합니다.
예를 들어, node_modules/react/index.js의 경우 청크 이름은 react가 됩니다.
함수는 모듈 ID가 @sentry 를 포함하는 경우에만 작동합니다. 이렇게 하면 @sentry 를 포함한 파일들이 별도의 청크로 분리되어 vendor.js 청크 크기를 줄여 초기 로드 시간을 개선할 수 있습니다.
manualChunks에서 파라미터로 받는 id값을 콘솔로 찍으면 무엇이 나오나?
notion image
 
vendor.js 청크 크기 변화
  • 870KB → 390KB
 
*기존 vite build시 기존에 적용되는 chunk 전략은? node_modules에 있는 외부 라이브러리는 별도의 vendor chunk로 묶는다. 위 옵션을 통해 일부 라이브러리만 빼서 다른 청크로 생성할 수 있다. (수동으로 코드 스플리팅이 가능해짐)