2023.12.20
GeunYeong Kim
어플리케이션 에러 트래킹, 성능 모니터링을 제공해주는 서비스
-> 자사 다른 서비스에서 이미 사용중이었기 때문에 현재 서비스에도 도입해보기로 결정했다.
npx @sentry/wizard@latest -i nextjs
import * as Sentry from '@sentry/nextjs';
Sentry.init({
dsn: process.env.NEXT_PUBLIC_SENTRY_KEY || undefined, // env로
tracesSampleRate: 1,
debug: false,
replaysOnErrorSampleRate: 1.0,
replaysSessionSampleRate: 0.1,
integrations: [
new Sentry.Replay({
maskAllText: true,
blockAllMedia: true,
}),
], // replay 관련 세팅. 나는 replay 적극 활용중이라 모두 true
});
By default, if your application throws an error during rendering, React will remove its UI from the screen. To prevent this, you can wrap a part of your UI into an error boundary. An error boundary is a special component that lets you display some fallback UI instead of the part that crashed—for example, an error message.
/* eslint-disable react/destructuring-assignment */
import React, { Component, ErrorInfo, ReactNode } from 'react';
interface Props {
children?: ReactNode;
}
interface State {
hasError: boolean;
}
// Next.js에서 사용해야 하기 때문에 class 컴포넌트로 만들었다.
class ErrorBoundary extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = { hasError: false };
}
static getDerivedStateFromError(error: State) {
return { hasError: true };
}
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
// 여기서 에러를 catch 한 뒤 Sentry로 보낸다.
if (process.env.NODE_ENV === 'production') {
Sentry.withScope((scope) => {
scope.setExtra('componentStack', errorInfo);
Sentry.captureException(error);
});
}
}
render() {
if (this.state.hasError) {
return (
// 에러 시 노출할 UI
);
}
// 에러가 없으면 children을 return 한다
return this.props.children;
}
}
export default ErrorBoundary;
...
<ErrorBoundary>
<Component {...pageProps} />
{mount && <SnackbarBasic />}
{mount && <ModalBasic />}
<ReactQueryDevtools initialIsOpen={false} />
</ErrorBoundary>
React Error Boundary for React
링크를 참조하면 쉽게 구현이 가능하다.
// Upload a larger set of source maps for prettier stack traces (increases build time)
widenClientFileUpload: false,
// Transpiles SDK to be compatible with IE11 (increases bundle size)
transpileClientSDK: false,
옵션 두 개를 off하니 용량이 많이 줄었다.
이전 267.45KB -> 변경 후 192.52 KB
config.plugins.push(
new webpack.DefinePlugin({
__SENTRY_DEBUG__: false, // 디버깅
__SENTRY_TRACING__: false, // 퍼포먼스 모니터링
__RRWEB_EXCLUDE_IFRAME__: true, // 리플레이
__RRWEB_EXCLUDE_SHADOW_DOM__: true, // 리플레이
__SENTRY_EXCLUDE_REPLAY_WORKER__: true, // 리플레이
}),
);
변경 전 192.52KB -> 변경 후 145.61KB