커스텀 컨텍스트 활용
이벤트에 임의의 데이터를 첨부하여 디버깅 정보를 풍부하게 만들 수 있습니다. 컨텍스트는 이벤트 수명 주기 동안 공유되며, 이슈 상세 페이지에서 확인 가능합니다.
구조화된 컨텍스트
데이터 첨부 시 setContext 메서드를 활용하세요. 컨텍스트는 객체 형태로 전달하며, 고유한 이름을 지정해야 합니다:
Sentry.setContext("player_stats", {
nickname: "ShadowHunter",
level: 47,
combat_style: "ranged"
});
페이로드 크기 제한
전체 애플리케이션 상태나 대용량 바이너리를 컨텍스트에 포함하지 마세요. 413 Payload Too Large 오류가 발생하면 이벤트가 거부됩니다. keepalive: true 설정 시 요청이 무한 대기 상태에 빠질 수 있습니다.
직접 컨텍스트 전달
SDK 5.16.0부터 captureException과 captureMessage 호출 시 컨스트를 직접 제공할 수 있습니다. 기존 스코프 데이터와 병합되며, 콜백 방식으로 명시적으로 초기화할 수도 있습니다.
지원하는 컨텍스트 키: tags, extra, contexts, user, level, fingerprint
// 태그 포함하여 예외 캡처
Sentry.captureException(new Error("서버 응답 실패"), {
tags: {
module: "payment_gateway"
}
});
// 스코프 초기화 후 새로 설정
Sentry.captureException(new Error("완전 초기화"), scope => {
scope.clear();
scope.setTag("reset", "true");
return scope;
});
// Scope 인스턴스로 데이터 전달 (전역 스코프와 병합)
const isolatedScope = new Sentry.Scope();
isolatedScope.setTag("module", "payment_gateway");
Sentry.captureException(new Error("결제 처리 오류"), isolatedScope);
// Scope 인스턴스로 데이터 전달 (전역 설정 무시)
const overrideScope = new Sentry.Scope();
overrideScope.setTag("module", "payment_gateway");
Sentry.captureException(new Error("결제 처리 오류"), () => overrideScope);
컨텍스트 정리
컨텍스트는 현재 스코프에 유지되므로 작업 완료 시 정리해야 합니다. Sentry는 두 가지 스코프 유형을 제공합니다:
- 전역 스코프: 작업 종료 후에도 유지됨
- 사용자 정의 스코크: 개발자가 직접 관리
// 전역 설정 변경
Sentry.configureScope(scope => scope.setTag("env", "production"));
// 임시 스코프에서만 적용
Sentry.withScope(function(scope) {
scope.setUser(currentUser);
Sentry.captureException(err);
});
// 전역 데이터 제거
Sentry.configureScope(scope => scope.clear());
추가 데이터 (Deprecated)
setExtra를 통한 비구조화 데이터 첨부는 더 이상 권장되지 않습니다. 가능한 한 구조화된 컨텍스트로 마이그레이션하세요.
사용자 식별
사용자 정보는 Sentry 내 고유 식별자 역할을 합니다. 최소 하나의 필드가 필요합니다:
- id: 내부 사용자 식별자
- username: 표시용 사용자명
- email: Gravatar 표시 및 알림 기능 활용
- ip_address: 인증되지 않은 사용자의 대체 식별자.
"{{auto}}"설정 시 자동 추출
// 사용자 설정
Sentry.setUser({ email: "jane.smith@example.com" });
// 사용자 정보 제거
Sentry.configureScope(scope => scope.setUser(null));
트랜잭션 이름 설정
트랜잭션 이름은 성능 모니터링에서 이벤트 그룹화와 실패 지점 분석에 활용됩니다. 변수 값을 제외한 저카널리티 식별자를 권장합니다:
GET /api/v2/products/OrderDetailViewbilling.tasks.generate_monthly_invoices
Sentry.configureScope(scope => scope.setTransactionName("OrderDetailView"));
태그 커스터마이징
태그는 인덱싱 및 검색 가능한 키-값 쌍으로, 필터링과 분포 맵에 활용됩니다. 호스트명, 플랫폼 버전, 언어 설정 등에 적합합니다.
Sentry.setTag("region", "ap-northeast-2");
Sentry가 자동 설정하는 태그는 덮어쓰지 않는 것을 권장합니다.
첨부 파일
이벤트와 함께 로그 파일 등을 첨부하여 크래시 리포트를 강화할 수 있습니다.
첨부 파일 업로드
이벤트 프로세서를 생성하여 multipart form data로 첨부 엔드포인트에 업로드합니다:
function buildAttachmentEndpoint(dsn, eventId) {
const { host, path, projectId, port, protocol, user } = dsn;
const portSegment = port ? `:${port}` : '';
const pathSegment = path ? `/${path}` : '';
return `${protocol}://${host}${portSegment}${pathSegment}/api/${projectId}/events/${eventId}/attachments/?sentry_key=${user}&sentry_version=7&sentry_client=custom-javascript`;
}
Sentry.addGlobalEventProcessor((event) => {
try {
const client = Sentry.getCurrentHub().getClient();
const uploadUrl = buildAttachmentEndpoint(client.getDsn(), event.event_id);
const payload = new FormData();
payload.append(
'system-logs',
new Blob([JSON.stringify({ entries: ["디버그 시작", "연결 성공"] })], {
type: 'application/json',
}),
'debug_logs.json'
);
fetch(uploadUrl, {
method: 'POST',
body: payload,
}).catch((err) => {
console.error('첨부 업로드 실패:', err);
});
return event;
} catch (err) {
console.error('첨부 처리 오류:', err);
}
});
이벤트당 최대 100MB까지 첨부 가능하며, 30일 보관됩니다.
브레드크럼
이벤트 발생 전 단계를 추적하는 구조화된 로그입니다.
수동 브레드크럼
Sentry.addBreadcrumb({
category: "checkout",
message: "결제 수단 선택: " + paymentMethod,
level: Sentry.Severity.Info,
});
브레드크럼 커스터마이징
Sentry.init({
beforeBreadcrumb(breadcrumb, hint) {
return breadcrumb.category === "console.log" ? null : breadcrumb;
},
});
사용자 피드백
오류 발생 시 사용자로부터 추가 정보를 수집할 수 있습니다.
위젯 통합
<script
src="https://browser.sentry-cdn.com/6.0.1/bundle.min.js"
integrity="sha384-z2Rmh4rfoBkdxaENH00ggKo5Bx8b2SJs+MWQrjWx4DbET95Zr2mxV2Vet3CCj4iW"
crossorigin="anonymous"
></script>
<script>
Sentry.init({
dsn: "https://examplePublicKey@o0.ingest.sentry.io/0",
beforeSend(event, hint) {
if (event.exception) {
Sentry.showReportDialog({
eventId: event.event_id,
title: "문제가 발생했습니다",
subtitle: "개선을 위해 도움을 주세요",
labelName: "이름",
labelEmail: "이메일",
labelComments: "어떤 일이 있었나요?",
labelSubmit: "보내기"
});
}
return event;
},
});
</script>
스코프와 허브
이벤트 전송 시 SDK는 현재 스코프의 정보를 병합합니다.
스코프 설정
Sentry.configureScope(function(scope) {
scope.setTag("service", "api-gateway");
scope.setUser({
id: 42,
email: "jane.smith@example.com",
});
});
로컬 스코프
Sentry.withScope(function(scope) {
scope.setTag("temporary", "true");
scope.setLevel("warning");
Sentry.captureException(new Error("일시적 오류"));
});
// 태그가 적용되지 않음
Sentry.captureException(new Error("다른 오류"));