Skip to Content
로깅

로깅

얼마집 프론트엔드는 Datadog(이벤트/RUM)과 Sentry(에러 트래킹) 두 가지 모니터링 도구를 사용합니다.

핵심 원칙

앱에서는 @datadog/browser-rum, @datadog/browser-logs, @sentry/nextjs 패키지를 직접 호출하지 말고, 반드시 logger 패키지를 통해 로깅하세요.

logger 패키지는 두 도구의 초기화·사용자 컨텍스트 설정·호출 방식을 통일된 인터페이스로 추상화합니다. 직접 호출 시 초기화 순서 문제, 사용자 컨텍스트 누락, 서버/클라이언트 환경 혼용 등의 문제가 발생할 수 있습니다.

초기화

Sentry — initSentry

sentry.client.config.ts, sentry.server.config.ts, sentry.edge.config.ts에서 호출합니다. 이 파일들은 Next.js/Sentry가 앱 부트스트랩 전에 자동으로 로드하는 약속된 파일입니다.

// sentry.client.config.ts / sentry.server.config.ts / sentry.edge.config.ts import {initSentry} from '@howmuchhome-web/logger/sentry'; initSentry();

initSentryNEXT_PUBLIC_ENV === 'production'일 때만 실제로 초기화합니다.

initSentry는 브라우저 전용 패키지를 포함하지 않도록 서브패스(/sentry)로 분리되어 있습니다. 메인 패키지(@howmuchhome-web/logger)가 아닌 서브패스에서 import해야 합니다.

Datadog RUM + 사용자 컨텍스트 — LoggerProvider

앱 루트에 LoggerProvider를 마운트합니다. 내부적으로 다음을 모두 처리합니다.

  • Datadog RUM 초기화 (datadogRum.init)
  • Datadog RUM 사용자 컨텍스트 설정 (datadogRum.setUser)
  • Sentry 사용자 컨텍스트 설정 (Sentry.setUser)
  • OpenTelemetry span 속성 기록 (서버)
// app/layout.tsx (Server Component) import {LoggerProvider} from '@howmuchhome-web/logger'; export default async function RootLayout({children}) { const user = await getCurrentUser(); return ( <html> <body> <LoggerProvider user={user}> {children} </LoggerProvider> </body> </html> ); }

usernull이면 anonymous-{timestamp}-{random} 형식의 익명 ID가 자동으로 생성됩니다.

서비스 이름을 변경해야 하는 경우 service prop을 전달합니다 (기본값: 'howmuchhome-web').

<LoggerProvider user={user} service="howmuchhome-web-admin"> {children} </LoggerProvider>

로그 기록 — Logger

일반 로그 (Datadog)

클라이언트 사이드에서 커스텀 로그를 Datadog Browser Logs로 전송합니다.

import Logger from '@howmuchhome-web/logger'; // 기본 로그 (type 기본값: 'info') Logger.log('사용자가 매물 상세 페이지를 조회했습니다.'); // 로그 레벨 및 컨텍스트 지정 Logger.log('검색 결과가 없습니다.', { type: 'warn', context: { keyword: '강남구', resultCount: 0 }, });
type설명
'ok'정상 완료
'info'일반 정보 (기본값)
'warn'경고
'error'에러
'debug'디버그

사용자 행동 추적 (Datadog RUM)

Datadog RUM에 커스텀 액션을 기록합니다.

// 버튼 클릭, 폼 제출 등 사용자 인터랙션 추적 Logger.addAction('매물_찜하기', { propertyId: '123', source: 'detail_page' }); Logger.addAction('검색_실행', { keyword: '강남구', filters: { minPrice: 5000 } });

뷰 전환 추적 (Datadog RUM)

SPA에서 URL 변경과 무관하게 논리적 뷰 전환을 추적할 때 사용합니다.

Logger.startView('매물_상세'); Logger.startView('청약_신청_퍼널');

에러 캡처 (Sentry)

에러를 Sentry로 전송합니다. 서버/클라이언트 양쪽에서 모두 사용할 수 있습니다.

import Logger from '@howmuchhome-web/logger'; import {ErrorLevel} from '@howmuchhome-web/error'; try { await submitApplication(data); } catch (error) { Logger.captureError(error as Error, { transactionName: '청약_신청', level: ErrorLevel.ERROR, tags: { feature: 'application', step: 'submit' }, extra: { applicationId: data.id }, }); }

level 옵션 (ErrorLevel)

설명
ErrorLevel.FATAL치명적 오류
ErrorLevel.ERROR일반 오류 (기본값)
ErrorLevel.WARNING경고 수준
ErrorLevel.INFO정보성 이벤트
ErrorLevel.IGNORESentry 전송 생략

ErrorLevel.IGNORE를 지정하면 Sentry에 전송되지 않습니다. 예상 가능한 에러(사용자 취소 등)에 활용하세요.

fingerprint 옵션

동일한 에러를 하나의 Sentry 이슈로 그룹핑할 때 사용합니다.

Logger.captureError(error, { fingerprint: ['payment-timeout'], });

API 에러 처리와의 관계

API 요청 에러는 @howmuchhome-web/api 패키지의 fetcher가 자동으로 Sentry에 전송합니다. @SilentErrorCodeList 데코레이터로 특정 에러 코드를 전송에서 제외할 수 있습니다. 별도로 Logger.captureError()를 호출할 필요가 없습니다.

직접 Logger.captureError()를 사용하는 경우:

  • API 이외의 비즈니스 로직 에러
  • 외부 SDK 에러
  • 클라이언트 사이드에서만 발생하는 예외

패키지 레퍼런스

자세한 API는 @howmuchhome-web/logger를 참고하세요.

Last updated on