최근 입사를 하게 된 후 나에게 하나의 업무가 주어졌다.
바로 에러 모니터링을 위해 Sentry를 도입하는것이였다!
여러 자료를 찾아보고 어떻게 센트리를 도입했는지 적어보겠다.
현재 웹에서 발생하는 모든에러가 Setnry에 잡히고 있었다.
특히 개발환경 및 로컬환경에서의 에러도 잡히고 있었고 디버깅할 필요도 없는 에러 이벤트들도 Sentry에 잡히고 있는 중이였다
또한 에러 이벤트를 계속 Sentry에 적재중이라 비용이 증가하는 중이였다.
따라서 여러가지를 생각해보았다!
여러가지를 생각해보았고 제일 적합한 방법으로는 프로덕션 환경과 개발환경에서만 에러를 수집하고 Status code에 따라 수집하기로 하였다!
이제 코드로 들어가보자!
![]()
import * as Sentry from "@sentry/nextjs";
import Constant from "./src/global/constants/Constant";
Sentry.init({
dsn: Constant.sentryDsn,
// 성능 모니터링 데이터의 샘플링 비율을 정의합니다.
tracesSampleRate: 1,
// 설정 중에 도움이 되는 정보를 콘솔에 출력 (true로 설정시)
debug: false,
// 에러 발생 시 세션 리플레이를 캡처할 비율을 설정합니다.
replaysOnErrorSampleRate: 1.0,
// 에러와 관계없이 세션 리플레이를 캡처할 비율을 설정합니다.
replaysSessionSampleRate: 0.1,
// Sentry와 함께 사용할 추가 기능이나 통합을 설정
integrations: [
Sentry.browserTracingIntegration(),
],
tracePropagationTargets: [
process.env.NEXT_PUBLIC_DOMAIN as string,
process.env.NEXT_PUBLIC_API_BASE_URL as string,
process.env.NEXT_PUBLIC_FILE_API_URL as string,
],
ignoreErrors: [/AxiosError/i],
beforeSend(event, _) {
if (window.location.hostname === "localhost") {
return null;
}
return event;
},
});
혹시 모를 브라우저 환경에서의 에러도 잡기위해 browserTracingIntegration 옵션도 사용해주었다.
그리고 어느 도메인과 어느 API에서 에러가 발생하는지 추적하기위해
tracePropagationTargets 옵션을 넣어주었다.
또한 beforeSend 옵션을 통해 로컬환경이면 event를 보내지 않도록 해주었다!
센트리를 공용으로 사용하기 위해 클래스로 정의해주었다.
import * as Sentry from "@sentry/nextjs";
class SentryHelper {
static handleNetworkError(error: any) {
const requestUrl = error.config?.url || "URL 정보 없음";
Sentry.withScope((scope) => {
scope.setLevel("error");
scope.setTag("error type", "Network Error");
scope.setContext("Axios Request", {
url: requestUrl,
method: error.config?.method,
headers: error.config?.headers,
data: error.config?.data,
});
Sentry.captureMessage(
`[Network Error] ${requestUrl} \n${error.message ?? `네트워크 오류`}`
);
});
}
static handleApiError(error: any) {
const isServerError = error.response.status >= 500;
const errorType = isServerError ? "Server Error" : "Api Error";
Sentry.withScope((scope) => {
scope.setLevel("error");
scope.setTag("error type", errorType);
Sentry.captureMessage(
`[${errorType}] ${error.config.url} \n${error.message}`
);
});
}
}
export default SentryHelper;
에러를 Scope 단위로 구분지어서 사용 할 수 있다.
Scope에 User의 정보를 넣어서 어떤 유저가 어떤 에러를 겪는지 확인할 수 있음 (setUser) 즉 데이터 재구성이 가능함!
태그와 레벨 정보를 같이 넣어 조금 더 파악하기 쉽게 할 수 있다.
apiClient.interceptors.response.use(
(response) => response,
(error) => {
// console.log(error);
if (!error.response) {
SentryHelper.handleNetworkError(error);
} else if (
error.response.status >= 400 &&
![401, 409].includes(error.response.status)
) {
SentryHelper.handleApiError(error);
}
return Promise.reject(error);
}
);
export default apiClient;
현재 회사에서는 axios 를 사용중이다.
그래서 axios interceptor 에 Sentry 코드를 넣어주었다.
400번대 에러의 경우 401과 409를 제외하고 모두 수집하도록 정해주었다.

센트리를 도입한것이 12월 초 이므로 에러 수집이 점차 감소했다!