모노레포에서 에러 추적 다들 어떻게 사용하시나요?

현빈·2026년 1월 5일

기술더하기

목록 보기
5/8
post-thumbnail

Turborepo 같은 모노레포 환경에서 Sentry를 세팅하려고 하면 생각보다 머리가 아픕니다.

하지만 저는 기존에 세팅해둔 Shared Package 전략이 있어 한번 세팅을 해보려합니다. (이전 게시글 참고)

sentry 공식 홈페이지에서도 모노레포를 위한 문서가 딱히 없어 걱정반 설렘 반으로 작업을 시작했네요.

그 과정 바로 공유해 드릴게요.


왜 그냥 설치하지 않고 "패키지"로 만드나요?

Shared Package 전략글에 상세히 설명되어 있어 간단히 짚고만 가겠습니다.

보통은 npx @sentry/wizard를 각 앱에서 돌리지만, 모노레포에선 이게 기술 부채가 됩니다.

  • 중복 설정: beforeSend 로직이나 에러 마스킹 수정을 모든 앱에서 반복해야 합니다.
  • 버전 불일치: A 앱은 Sentry v7, B 앱은 Sentry v10을 쓰는 혼란이 생깁니다.
  • 파편화된 DSN: DSN 주소 하나 바뀌면 모든 .env를 뒤져야 하죠.

우리는 @repo/sentry라는 이름의 독립된 공간에서 이 모든 걸 관리할 겁니다.


Shared Package 구축하기

packages/sentry에 자리를 잡고, 모든 앱이 가져다 쓸 수 있는 "Sentry 컨트롤 타워"를 만듭니다.

통합 Entry Point 설계 (index.ts)

단순히 초기화만 하는 게 아니라, 서버/클라이언트/엣지 환경에 맞춰 최적화된 초기화 함수를 정의합니다.

센트리 옵션은 공식문서, 블로그 등 많은 곳에세 이미 정리되어 있기에 index.ts에 어떻게 합쳤는지만 보여드리겠습니다.

import * as Sentry from "@sentry/nextjs";

// 중앙에서 관리하는 DSN
const SENTRY_DSN = 'https://...'; 

export const initSentryClient = () => {
  Sentry.init({
    dsn: SENTRY_DSN,
    tracesSampleRate: 1.0,
    integrations: [Sentry.consoleLoggingIntegration({ levels: ["log", "warn", "error"] })],
    enableLogs: true,
  });
};

export const initSentryServer = () => {
  Sentry.init({
    dsn: SENTRY_DSN,
    tracesSampleRate: 1.0,
  });
};

// ...Edge 로직도 동일하게

next.config.js 옵션 공통화

빌드 시 소스맵 업로드나 터널링(광고 차단 우회) 설정도 패키지에서 미리 정의해 둡니다.

export const sentryConfigOptions = {
  org: "조직명",
  project: "프로젝트명",
  silent: !process.env.CI,
  tunnelRoute: "/monitoring",
};

앱에서 간단하게 적용하기

현재 저는 Next.js 15+ 버전을 사용중이기에 최신 규격에 맞게 instrumentation.ts를 활용했습니다.

instrumentation 훅은 아래와 같으니 참고해보세요.

서버와 클라이언트를 동시에 잡는 법

instrumentation.ts (Server)

import * as Sentry from '@repo/sentry';

export async function register() {
  if (process.env.NEXT_RUNTIME === 'nodejs') {
    const { initSentryServer } = await import('@repo/sentry');
    initSentryServer();
  }
}
export const onRequestError = Sentry.captureRequestError;

instrumentation-client.ts (Client)

import * as Sentry from '@repo/sentry';
Sentry.initSentryClient();
export const onRouterTransitionStart = Sentry.captureRouterTransitionStart;

여담

요번 작업에서 제 스스로 잘 도입했다 싶은 기능들을 아래에 정리하였으니 참고해보세요.

  1. Tunneling: "광고 차단기에 의해 로그가 유실되는 걸 막기 위해 Rewrites를 통해 터널링을 구축"
  2. Shared Package: "모노레포 환경에서 일관된 에러 트래킹을 위해 Sentry 설정을 공통 패키지화하여 DX를 개선"
  3. Source Maps: "CI/CD 단계에서 자동 소스맵 업로드, 배포 후에도 난독화된 코드 대신 원본 코드로 에러 분석"

마무리하며

Sentry는 단순히 에러를 쌓아두는 창고가 아닙니다. 잘 세팅된 Sentry는 개발자가 잠든 사이에도 서비스의 건강도를 체크해 주는 소중한 동료가 되죠.

오늘 정리해 드린 모노레포 Sentry 설정으로 여러분의 DX를 한 단계 높여보세요!

profile
FE = 현빈

0개의 댓글