Vue 앱에 Sentry 통합하기: 설치, 설정 및 고급 기능 가이드

Sentry는 Vue 애플리케이션에서 오류와 성능 이슈를 실시간으로 감지하고 보고하는 강력한 도구입니다. 본 문서에서는 최신 버전의 Sentry(v21.8.x)를 기준으로 Vue 프로젝트에 Sentry를 효과적으로 통합하는 방법을 단계별로 설명합니다.

시작하기

Sentry SDK는 자동으로 예외와 오류를 캡처하여 개발자가 문제를 신속하게 파악할 수 있도록 지원합니다.

설치

프로젝트 루트 디렉터리에서 다음 명령어를 사용해 필요한 패키지를 설치하세요:

# npm 사용
npm install --save @sentry/vue @sentry/tracing

# yarn 사용
yarn add @sentry/vue @sentry/tracing

기본 설정

애플리케이션 초기화 시점에 Sentry를 구성해야 합니다. 아래 예제는 Vue 2와 Vue 3 환경에서 각각 어떻게 적용하는지를 보여줍니다.

Vue 2

import Vue from 'vue';
import Router from 'vue-router';
import * as Sentry from '@sentry/vue';
import { Integrations } from '@sentry/tracing';

Vue.use(Router);

const router = new Router({
  // 라우팅 설정
});

Sentry.init({
  Vue,
  dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0',
  integrations: [
    new Integrations.BrowserTracing({
      routingInstrumentation: Sentry.vueRouterInstrumentation(router),
      tracingOrigins: ['localhost', 'my-site-url.com', /^\//],
    }),
  ],
  tracesSampleRate: 1.0, // 운영 환경에서는 낮은 값으로 조정 권장
});

new Vue({
  router,
  render: h => h(App),
}).$mount('#app');

Vue 3

import { createApp } from 'vue';
import { createRouter } from 'vue-router';
import * as Sentry from '@sentry/vue';
import { Integrations } from '@sentry/tracing';

const app = createApp({});
const router = createRouter({});

Sentry.init({
  app,
  dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0',
  integrations: [
    new Integrations.BrowserTracing({
      routingInstrumentation: Sentry.vueRouterInstrumentation(router),
      tracingOrigins: ['localhost', 'my-site-url.com', /^\//],
    }),
  ],
  tracesSampleRate: 1.0,
});

app.use(router);
app.mount('#app');

다중 앱 인스턴스 (Vue 3)

하나의 Sentry 인스턴스로 여러 Vue 앱을 동시에 모니터링할 수 있습니다:

const appOne = createApp(AppA);
const appTwo = createApp(AppB);

Sentry.init({
  app: [appOne, appTwo],
});

수동 초기화

특정 앱만 선택적으로 Sentry를 연결하고자 할 때 사용합니다:

const app = createApp(App);
Sentry.init({ app });

const miscApp = createApp(MiscApp);
miscApp.mixin(Sentry.createTracingMixins({ trackComponents: true }));
Sentry.attachErrorHandler(miscApp, { logErrors: true });

검증 테스트

설정 후 오류가 정상적으로 전송되는지 확인하세요. 아래 코드를 컴포넌트에 추가하고 버튼을 클릭해보세요:

<template>
  <button @click="triggerError">오류 발생</button>
</template>

<script>
export default {
  methods: {
    triggerError() {
      throw new Error('테스트 오류: Sentry 작동 확인');
    }
  }
}
</script>

핵심 설정 옵션

Sentry는 다양한 설정 옵션을 제공하여 데이터 수집 방식을 세밀하게 제어할 수 있습니다.

공통 옵션

  • dsn: Sentry 프로젝트 식별 정보. 환경 변수 SENTRY_DSN에서도 읽을 수 있음.
  • debug: 디버그 모드 활성화 여부. 기본값은 false.
  • release: 배포 버전명. CI/CD 파이프라인과 연동해 자동 설정 가능.
  • environment: 현재 환경 (예: staging, production).
  • sampleRate: 오류 이벤트 샘플링 비율 (0.0 ~ 1.0). 기본값은 1.0.
  • tracesSampleRate: 트랜잭션 추적 샘플링 비율.
  • maxBreadcrumbs: 저장할 브레드크럼 최대 개수. 기본값은 100.
  • attachStacktrace: 메시지에 스택 트레이스 포함 여부.

훅 기반 설정

컴포넌트 생명주기 이벤트를 추적할 수 있습니다:

Sentry.init({
  app,
  dsn: '...',
  trackComponents: true,
  hooks: ['mount', 'update', 'destroy'],
  timeout: 3000,
});

이벤트 필터링

불필요한 오류를 제외하거나 특정 조건에 따라 데이터를 조작할 수 있습니다.

beforeSend 사용

이벤트 전송 직전에 커스터마이징할 수 있습니다:

Sentry.init({
  beforeSend(event, hint) {
    const error = hint.originalException;
    if (error && error.message.includes('database')) {
      event.fingerprint = ['db-connection-error'];
    }
    return event;
  }
});

도메인 기반 필터링

특정 출처의 오류만 허용하거나 차단합니다:

Sentry.init({
  allowUrls: [/https?:\/\/(www\.)?my-domain\.com/],
  denyUrls: [/graph\.facebook\.com/, /extensions\//]
});

소스맵(Source Maps) 통합

압축된 코드에서도 원본 소스 위치를 정확히 파악하기 위해 소스맵을 업로드해야 합니다.

Webpack 플러그인 사용

const SentryWebpackPlugin = require('@sentry/webpack-plugin');

module.exports = {
  devtool: 'source-map',
  plugins: [
    new SentryWebpackPlugin({
      authToken: process.env.SENTRY_AUTH_TOKEN,
      org: 'your-org',
      project: 'your-project',
      release: process.env.SENTRY_RELEASE,
      include: './dist',
      ignore: ['node_modules']
    })
  ]
};

수동 업로드 (sentry-cli)

  1. 릴리스 생성: sentry-cli releases new "v1.0.0"
  2. 아티팩트 업로드: sentry-cli releases files v1.0.0 upload-sourcemaps ./dist
  3. 완료 처리: sentry-cli releases finalize v1.0.0

성능 추적 및 리소스 관리

트랜잭션 샘플링

과도한 데이터 전송을 방지하기 위해 동적 샘플링을 구현할 수 있습니다:

Sentry.init({
  tracesSampler(context) {
    if (context.transactionContext.name.startsWith('/admin')) {
      return 0.5; // 관리자 경로는 절반만 추적
    } else if (context.transactionContext.op === 'pageload') {
      return 0.1; // 페이지 로드는 10%만 추적
    }
    return 0.01;
  }
});

세션 추적

사용자 세션 상태를 기록하여 충돌률 등을 분석할 수 있습니다:

Sentry.init({
  autoSessionTracking: true,
  initialScope: {
    user: { id: '123', email: 'user@example.com' }
  }
});

고급 기능

rrweb을 이용한 세션 재생

사용자 행동을 녹화하여 문제 재현이 용이합니다:

npm install --save @sentry/rrweb rrweb
import * as Sentry from '@sentry/browser';
import SentryRRWeb from '@sentry/rrweb';

Sentry.init({
  integrations: [new SentryRRWeb()],
  tracesSampleRate: 0.2
});

광고 차단기 우회

클라이언트 측에서 요청이 차단되는 경우, 백엔드를 통해 프록시 요청을 보냅니다:

Sentry.init({
  dsn: 'https://examplePublicKey@o0.ingest.sentry.io/0',
  tunnel: '/sentry-tunnel'
});

서버 측에서 /sentry-tunnel 엔드포인트를 구현하여 실제 Sentry API로 포워딩해야 합니다.

문제 해결 팁

  • CORS 문제: 외부 도메인에서 로드하는 스크립트에는 crossorigin="anonymous" 속성을 추가하고 서버에 Access-Control-Allow-Origin: * 헤더를 설정하세요.
  • 소스맵 검증: sourcemaps.io를 사용해 로컬에서 소스맵 변환 결과를 미리 확인하세요.
  • 브라우저 호환성: IE11 이하 지원을 위해서는 Promise, Object.assign 등의 폴리필이 필요합니다.

태그: vue Sentry Error Monitoring Source Maps Performance Tracking

7월 18일 07:44에 게시됨