From 0d6a1f98a6804612d0ccf41be663c690c7dba347 Mon Sep 17 00:00:00 2001 From: "wl990@naver.com" Date: Sun, 6 Apr 2025 01:06:26 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat=20:=20Sentry=20SDK=20=EC=84=A4?= =?UTF-8?q?=EC=B9=98,=20sentry.ts=ED=8C=8C=EC=9D=BC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 + pnpm-lock.yaml | 113 ++++++++++++++++++++++++++++++++++++++++++- src/Sentry/sentry.ts | 9 ++++ 3 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 src/Sentry/sentry.ts diff --git a/package.json b/package.json index 25f66ab..11dfa02 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ "@egjs/react-infinitegrid": "^4.12.0", "@mui/icons-material": "^6.4.4", "@mui/material": "^6.4.4", + "@sentry/react": "^9.11.0", + "@sentry/tracing": "^7.120.3", "@tailwindcss/vite": "^4.0.6", "@tanstack/react-query": "^5.66.0", "axios": "^1.7.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8689848..0f97393 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -17,6 +17,12 @@ importers: '@mui/material': specifier: ^6.4.4 version: 6.4.4(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react@18.3.1))(@types/react@19.0.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@sentry/react': + specifier: ^9.11.0 + version: 9.11.0(react@18.3.1) + '@sentry/tracing': + specifier: ^7.120.3 + version: 7.120.3 '@tailwindcss/vite': specifier: ^4.0.6 version: 4.0.6(vite@6.1.0(jiti@2.4.2)(lightningcss@1.29.1)) @@ -708,6 +714,56 @@ packages: '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + '@sentry-internal/browser-utils@9.11.0': + resolution: {integrity: sha512-XS71kRf7lw5St/Jc9G2Viy1cKgqGoPHqUAykXEtFt38JVXdf1TY/dSbKv/PAgNqMvC1xvdTsN0HF/81o7DNUEA==} + engines: {node: '>=18'} + + '@sentry-internal/feedback@9.11.0': + resolution: {integrity: sha512-50KiRmrF1Ldr+KoRawqcCYVk7TAVP8K/I81Jk9YWwlp1+Pu1ArpYDmTNCLXTgoyiyO38aHefKGZJX6AKFuSsUQ==} + engines: {node: '>=18'} + + '@sentry-internal/replay-canvas@9.11.0': + resolution: {integrity: sha512-ZcRg8TWfF0ucjK2i+4TY/blRNJ7YKrgMpx19pFj6eCOJ1K8geSkAFPIfDHcQEwIU1ZTN+HiCwx0JvTI9YZxjfg==} + engines: {node: '>=18'} + + '@sentry-internal/replay@9.11.0': + resolution: {integrity: sha512-0k24h58O/2VQw1dwT/zQiWvUzLNQxpxbrVN/MYPT7czSEhI+1bX8fxMHXZORl2JqhetImMXzxH3XkuHQPEqQMg==} + engines: {node: '>=18'} + + '@sentry-internal/tracing@7.120.3': + resolution: {integrity: sha512-Ausx+Jw1pAMbIBHStoQ6ZqDZR60PsCByvHdw/jdH9AqPrNE9xlBSf9EwcycvmrzwyKspSLaB52grlje2cRIUMg==} + engines: {node: '>=8'} + + '@sentry/browser@9.11.0': + resolution: {integrity: sha512-DSDj8wQJoiLqqOcntl+7phjd8l8KN9A0vaV7mZNHWbrHU3MVwXqTyLyERRLC6wi0t7F5kqczqa3xLmKjK/fMZg==} + engines: {node: '>=18'} + + '@sentry/core@7.120.3': + resolution: {integrity: sha512-vyy11fCGpkGK3qI5DSXOjgIboBZTriw0YDx/0KyX5CjIjDDNgp5AGgpgFkfZyiYiaU2Ww3iFuKo4wHmBusz1uA==} + engines: {node: '>=8'} + + '@sentry/core@9.11.0': + resolution: {integrity: sha512-qfb4ahGZubbrNh1MnbEqyHFp87rIwQIZapyQLCaYpudXrP1biEpLOV3mMDvDJWCdX460hoOwQ3SkwipV3We/7w==} + engines: {node: '>=18'} + + '@sentry/react@9.11.0': + resolution: {integrity: sha512-sH/3KnDsLxBFRoxPyIpab7OewkfStdZQQwgpfv8R0yDKpGg4lU7KdTccryFvWL123UpHC7ydPWjdcfC8YV/EPQ==} + engines: {node: '>=18'} + peerDependencies: + react: ^16.14.0 || 17.x || 18.x || 19.x + + '@sentry/tracing@7.120.3': + resolution: {integrity: sha512-B7bqyYFgHuab1Pn7w5KXsZP/nfFo4VDBDdSXDSWYk5+TYJ3IDruO3eJFhOrircfsz4YwazWm9kbeZhkpsHDyHg==} + engines: {node: '>=8'} + + '@sentry/types@7.120.3': + resolution: {integrity: sha512-C4z+3kGWNFJ303FC+FxAd4KkHvxpNFYAFN8iMIgBwJdpIl25KZ8Q/VdGn0MLLUEHNLvjob0+wvwlcRBBNLXOow==} + engines: {node: '>=8'} + + '@sentry/utils@7.120.3': + resolution: {integrity: sha512-UDAOQJtJDxZHQ5Nm1olycBIsz2wdGX8SdzyGVHmD8EOQYAeDZQyIlQYohDe9nazdIOQLZCIc3fU0G9gqVLkaGQ==} + engines: {node: '>=8'} + '@svgr/babel-plugin-add-jsx-attribute@8.0.0': resolution: {integrity: sha512-b9MIk7yhdS1pMCZM8VeNfUlSKVRhsHZNMl5O9SfaX0l0t5wjdgu4IDzGB8bpnGBBOjGST3rRFVsaaEtI4W6f7g==} engines: {node: '>=14'} @@ -2946,6 +3002,62 @@ snapshots: '@rtsao/scc@1.1.0': {} + '@sentry-internal/browser-utils@9.11.0': + dependencies: + '@sentry/core': 9.11.0 + + '@sentry-internal/feedback@9.11.0': + dependencies: + '@sentry/core': 9.11.0 + + '@sentry-internal/replay-canvas@9.11.0': + dependencies: + '@sentry-internal/replay': 9.11.0 + '@sentry/core': 9.11.0 + + '@sentry-internal/replay@9.11.0': + dependencies: + '@sentry-internal/browser-utils': 9.11.0 + '@sentry/core': 9.11.0 + + '@sentry-internal/tracing@7.120.3': + dependencies: + '@sentry/core': 7.120.3 + '@sentry/types': 7.120.3 + '@sentry/utils': 7.120.3 + + '@sentry/browser@9.11.0': + dependencies: + '@sentry-internal/browser-utils': 9.11.0 + '@sentry-internal/feedback': 9.11.0 + '@sentry-internal/replay': 9.11.0 + '@sentry-internal/replay-canvas': 9.11.0 + '@sentry/core': 9.11.0 + + '@sentry/core@7.120.3': + dependencies: + '@sentry/types': 7.120.3 + '@sentry/utils': 7.120.3 + + '@sentry/core@9.11.0': {} + + '@sentry/react@9.11.0(react@18.3.1)': + dependencies: + '@sentry/browser': 9.11.0 + '@sentry/core': 9.11.0 + hoist-non-react-statics: 3.3.2 + react: 18.3.1 + + '@sentry/tracing@7.120.3': + dependencies: + '@sentry-internal/tracing': 7.120.3 + + '@sentry/types@7.120.3': {} + + '@sentry/utils@7.120.3': + dependencies: + '@sentry/types': 7.120.3 + '@svgr/babel-plugin-add-jsx-attribute@8.0.0(@babel/core@7.26.9)': dependencies: '@babel/core': 7.26.9 @@ -3910,7 +4022,6 @@ snapshots: hoist-non-react-statics@3.3.2: dependencies: react-is: 16.13.1 - optional: true ignore@5.3.2: {} diff --git a/src/Sentry/sentry.ts b/src/Sentry/sentry.ts new file mode 100644 index 0000000..1350997 --- /dev/null +++ b/src/Sentry/sentry.ts @@ -0,0 +1,9 @@ +import * as Sentry from '@sentry/react'; + +Sentry.init({ + dsn: 'https://29d2c788d61a2d1e6647da9f16c01def@o4509101248413697.ingest.us.sentry.io/4509101251100672', + integrations: [Sentry.browserTracingIntegration()], + tracesSampleRate: 1.0, + // tracePropagationTargets: ["localhost", '백엔드 도메인 주소'] + // tracePropagationTargets는 프론트엔드와 백엔드의 퍼포먼스 추적을 연결할때 사용하는 속성으로 백엔드도 Sentry를 사용해야 서로 연결 가능하다. +}); From f2b924092a9a9c145dd163b2aaa83ccaf12c2004 Mon Sep 17 00:00:00 2001 From: wldnjs990 Date: Mon, 7 Apr 2025 12:05:59 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat=20:=20Axios=20=EC=9D=B8=ED=84=B0?= =?UTF-8?q?=EC=85=89=ED=8A=B8=EC=97=90=20=EC=84=BC=ED=8A=B8=EB=A6=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20+=20=EC=84=BC=ED=8A=B8=EB=A6=AC=20email,?= =?UTF-8?q?=20username=20=ED=95=84=ED=84=B0=EB=A7=81=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Sentry/instrument.ts | 33 ++++++++++++++++++++++++++++++ src/Sentry/sentry.ts | 9 -------- src/apis/client.ts | 8 ++++++++ src/main.tsx | 2 ++ src/pages/Auth/index.tsx | 2 ++ src/pages/Write/CategorySelect.tsx | 3 --- src/stores/authStore.ts | 4 ++++ 7 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 src/Sentry/instrument.ts delete mode 100644 src/Sentry/sentry.ts diff --git a/src/Sentry/instrument.ts b/src/Sentry/instrument.ts new file mode 100644 index 0000000..fc057da --- /dev/null +++ b/src/Sentry/instrument.ts @@ -0,0 +1,33 @@ +import useAuthStore from '@/stores/authStore'; +import * as Sentry from '@sentry/react'; + +Sentry.init({ + dsn: 'https://29d2c788d61a2d1e6647da9f16c01def@o4509101248413697.ingest.us.sentry.io/4509101251100672', + integrations: [ + Sentry.browserTracingIntegration(), + Sentry.replayIntegration({ + // 모든 텍스트, input 마스킹을 뺄 수 있지만 보안상으로 위험할 수 있으니 특정 클래스나 속성이 있는 요소에 마스킹을 걸 수 있는 mask 속성을 같이 활용하자! + // 제일 베스트는 전체를 마스킹 처리 하고 보여줄 몇몇 공간만 unmask속성으로 클래스를 따로 지정해줘 마스킹을 풀어주는게 베스트! + maskAllText: false, + maskAllInputs: false, + + // mask 속성으로 마스킹 할 부분에만 클래스 부여해서 마스킹 하기(아래 코드처럼 input에 type이 password인 경우만 마스킹 걸 수도 있음) + mask: ['.secret', 'input[type="password"]'], + }), + ], + tracesSampleRate: 1.0, + replaysSessionSampleRate: 1.0, + replaysOnErrorSampleRate: 1.0, + // tracePropagationTargets: ["localhost", '백엔드 도메인 주소'] + // tracePropagationTargets는 프론트엔드와 백엔드의 퍼포먼스 추적을 연결할때 사용하는 속성으로 백엔드도 Sentry를 사용해야 서로 연결 가능하다. +}); + +// 오류가 발생한 유저의 username(36.5에선 zipcode가 닉네임임), email 등을 추가해서 사이트에서 오류 필터링이 가능하다. +// 이외에도 id 등의 필터링 속성이 있지만 현재 백엔드 로직상 로그인시에 유저 id에 대한 정보를 안 받아오기 때문에 추가를 못한다... 나중에 요청 드려봐야할듯 + +Sentry.setUser({ + username: useAuthStore.getState().zipCode, + email: useAuthStore.getState().email, +}); + +export default Sentry; diff --git a/src/Sentry/sentry.ts b/src/Sentry/sentry.ts deleted file mode 100644 index 1350997..0000000 --- a/src/Sentry/sentry.ts +++ /dev/null @@ -1,9 +0,0 @@ -import * as Sentry from '@sentry/react'; - -Sentry.init({ - dsn: 'https://29d2c788d61a2d1e6647da9f16c01def@o4509101248413697.ingest.us.sentry.io/4509101251100672', - integrations: [Sentry.browserTracingIntegration()], - tracesSampleRate: 1.0, - // tracePropagationTargets: ["localhost", '백엔드 도메인 주소'] - // tracePropagationTargets는 프론트엔드와 백엔드의 퍼포먼스 추적을 연결할때 사용하는 속성으로 백엔드도 Sentry를 사용해야 서로 연결 가능하다. -}); diff --git a/src/apis/client.ts b/src/apis/client.ts index 69fe0dd..bcd976e 100644 --- a/src/apis/client.ts +++ b/src/apis/client.ts @@ -1,6 +1,8 @@ import axios from 'axios'; import useAuthStore from '@/stores/authStore'; +import Sentry from '@/Sentry/instrument'; +import useToastStore from '@/stores/toastStore'; const client = axios.create({ baseURL: import.meta.env.VITE_API_URL, @@ -23,6 +25,11 @@ client.interceptors.response.use( async (error) => { const logout = useAuthStore.getState().logout; const isLoggedIn = useAuthStore.getState().isLoggedIn; + Sentry.captureException(error); + useToastStore.getState().setToastActive({ + title: '서버에 오류가 발생했습니다.', + toastType: 'Error', + }); const originalRequest = error.config; @@ -42,6 +49,7 @@ client.interceptors.response.use( originalRequest.headers.Authorization = `Bearer ${newToken}`; return client(originalRequest); } catch (e) { + // 센트리 에러 전송 return Promise.reject(e); } } diff --git a/src/main.tsx b/src/main.tsx index e5b67d3..0d24847 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -6,6 +6,8 @@ import { BrowserRouter } from 'react-router'; import App from './App'; import './styles/index.css'; +import './Sentry/instrument'; + const queryClient = new QueryClient(); queryClient.setDefaultOptions({ queries: { diff --git a/src/pages/Auth/index.tsx b/src/pages/Auth/index.tsx index 7e928f3..b211bd8 100644 --- a/src/pages/Auth/index.tsx +++ b/src/pages/Auth/index.tsx @@ -13,6 +13,7 @@ const AuthCallbackPage = () => { const logout = useAuthStore((state) => state.logout); const setAccessToken = useAuthStore((state) => state.setAccessToken); const setZipCode = useAuthStore((state) => state.setZipCode); + const setEmail = useAuthStore((state) => state.setEmail); const setIsAdmin = useAuthStore((state) => state.setIsAdmin); const navigate = useNavigate(); let accessToken = ''; @@ -42,6 +43,7 @@ const AuthCallbackPage = () => { const zipCodeResponse = await getMydata(); if (!zipCodeResponse) throw new Error('Error fetching user data'); setZipCode(zipCodeResponse.data.data.zipCode); + setEmail(zipCodeResponse.data.data.email); } break; diff --git a/src/pages/Write/CategorySelect.tsx b/src/pages/Write/CategorySelect.tsx index fd9e86b..9f72a83 100644 --- a/src/pages/Write/CategorySelect.tsx +++ b/src/pages/Write/CategorySelect.tsx @@ -30,11 +30,8 @@ export default function CategorySelect({ setSend(true); setToastActive({ title: '편지 전송을 완료했습니다.', toastType: 'Success' }); } else if (res?.status === 400) { - // 일단 에러 발생하면 무조건 검열단어라고 토스트를 띄웠는데 후에 에러 처리 수정해야함 setToastActive({ title: '편지에 검열 단어가 포함되어있습니다.', toastType: 'Error' }); setStep('edit'); - } else { - setToastActive({ title: '편지 전송과정에 오류가 발생했습니다.', toastType: 'Error' }); } }; diff --git a/src/stores/authStore.ts b/src/stores/authStore.ts index 9b5530a..7fff431 100644 --- a/src/stores/authStore.ts +++ b/src/stores/authStore.ts @@ -6,11 +6,13 @@ import { getNewToken } from '@/apis/auth'; interface AuthStore { isLoggedIn: boolean; zipCode: string; + email: string; accessToken: string; isAdmin: boolean; login: () => void; logout: () => Promise; setZipCode: (zipCode: string) => void; + setEmail: (email: string) => void; setAccessToken: (accessToken: string) => void; setIsAdmin: () => void; isRefreshing: boolean; @@ -24,6 +26,7 @@ const useAuthStore = create( isLoggedIn: false, accessToken: '', zipCode: '', + email: '', isAdmin: false, login: () => set({ isLoggedIn: true }), logout: async () => { @@ -42,6 +45,7 @@ const useAuthStore = create( // } }, setZipCode: (zipCode) => set({ zipCode: zipCode }), + setEmail: (email) => set({ email: email }), setAccessToken: (accessToken) => set({ accessToken: accessToken }), setIsAdmin: () => set({ isAdmin: true }), isRefreshing: false, From d18a8a506383dd540e4bbc3b04ada4fd3649c9fc Mon Sep 17 00:00:00 2001 From: wldnjs990 Date: Sat, 12 Apr 2025 16:21:04 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat=20:=20Webp=20=EC=A0=84=EC=9A=A9=20img?= =?UTF-8?q?=20=ED=83=9C=EA=B7=B8=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20?= =?UTF-8?q?=EC=A0=9C=EC=9E=91=20&=20=EC=9E=84=EC=8B=9C=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/WebpImage.tsx | 34 ++++++++++++++++++++++++++++++++++ src/pages/Landing/index.tsx | 11 ++++++++++- 2 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 src/components/WebpImage.tsx diff --git a/src/components/WebpImage.tsx b/src/components/WebpImage.tsx new file mode 100644 index 0000000..ce19f24 --- /dev/null +++ b/src/components/WebpImage.tsx @@ -0,0 +1,34 @@ +import { useEffect, useState } from 'react'; + +function checkWebpSupport() { + return new Promise((resolve) => { + const webp = new Image(); + // 이미지 로드에 따른 이벤트핸들러 부여 + webp.onload = () => resolve(webp.width > 0 && webp.height > 0); + webp.onerror = () => resolve(false); + // 이미지 로드 시도 + webp.src = + 'data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAwA0JaQAA3AA/vuUAAA='; + }); +} + +export default function WebpImage({ + src, + alt = '', + className = '', +}: { + src: string; + alt: string; + className: string; +}) { + const [imageSrc, setImageSrc] = useState(src); + + useEffect(() => { + checkWebpSupport().then((isSupported) => { + console.log(isSupported); + setImageSrc(isSupported ? src : src.replace(/\.\w+$/, '.png')); + }); + }, [src]); + + return {alt}; +} diff --git a/src/pages/Landing/index.tsx b/src/pages/Landing/index.tsx index 91ceb6a..5a2dfa1 100644 --- a/src/pages/Landing/index.tsx +++ b/src/pages/Landing/index.tsx @@ -8,6 +8,7 @@ import useAuthStore from '@/stores/authStore'; import useThemeStore from '@/stores/themeStore'; import { STYLE_CLASS } from './constants'; +import WebpImage from '@/components/WebpImage'; const Landing = () => { const [step, setStep] = useState(0); @@ -23,7 +24,7 @@ const Landing = () => { return (
setStep((prev) => prev + 1)}> - 서비스 소개 이미지 { STYLE_CLASS[step].imagePosition, )} /> + {/* 서비스 소개 이미지 */}
Date: Tue, 3 Jun 2025 20:19:55 +0900 Subject: [PATCH 4/6] =?UTF-8?q?feat=20:=20webp=EC=9D=B4=EB=AF=B8=EC=A7=80?= =?UTF-8?q?=20=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=EC=9D=BC=EB=B6=80=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/ResultLetter.tsx | 5 ++++- src/components/WebpImage.tsx | 2 +- src/pages/Write/components/ThemeOption.tsx | 11 ++++++++++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/src/components/ResultLetter.tsx b/src/components/ResultLetter.tsx index c150e45..8db0a2e 100644 --- a/src/components/ResultLetter.tsx +++ b/src/components/ResultLetter.tsx @@ -1,6 +1,7 @@ import { CATEGORYS } from '../pages/Write/constants'; import LetterWrapper from './LetterWrapper'; +import WebpImage from './WebpImage'; export default function ResultLetter({ categoryName = 'CONSOLATION', @@ -24,7 +25,9 @@ export default function ResultLetter({ 따숨이님께 {title} - 우표 + + + {/* 우표 */}
{today} diff --git a/src/components/WebpImage.tsx b/src/components/WebpImage.tsx index ce19f24..daff2ce 100644 --- a/src/components/WebpImage.tsx +++ b/src/components/WebpImage.tsx @@ -19,7 +19,7 @@ export default function WebpImage({ }: { src: string; alt: string; - className: string; + className?: string; }) { const [imageSrc, setImageSrc] = useState(src); diff --git a/src/pages/Write/components/ThemeOption.tsx b/src/pages/Write/components/ThemeOption.tsx index 96e7f79..1de7953 100644 --- a/src/pages/Write/components/ThemeOption.tsx +++ b/src/pages/Write/components/ThemeOption.tsx @@ -3,6 +3,7 @@ import { twMerge } from 'tailwind-merge'; import useWrite from '@/stores/writeStore'; import { CATEGORY_LIST } from '../constants'; +import WebpImage from '@/components/WebpImage'; export default function ThemeOption() { const letterRequest = useWrite((state) => state.letterRequest); @@ -20,7 +21,7 @@ export default function ThemeOption() { aria-label="편지 테마 설정하기" > {target.name} - 테마 이미지 + {/* 테마 이미지 */} ); })} From 285ec590b56131068f967bfbad1df72c96f504ac Mon Sep 17 00:00:00 2001 From: wldnjs990 Date: Wed, 4 Jun 2025 14:01:46 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat=20:=20=EC=84=BC=ED=8A=B8=EB=A6=AC=20?= =?UTF-8?q?=EA=B0=90=EC=8B=9C=20=EC=A1=B0=EA=B1=B4=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Sentry/instrument.ts | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Sentry/instrument.ts b/src/Sentry/instrument.ts index fc057da..6522785 100644 --- a/src/Sentry/instrument.ts +++ b/src/Sentry/instrument.ts @@ -15,9 +15,20 @@ Sentry.init({ mask: ['.secret', 'input[type="password"]'], }), ], - tracesSampleRate: 1.0, - replaysSessionSampleRate: 1.0, - replaysOnErrorSampleRate: 1.0, + + // 아래 옵션은 사용자에게 발생하는 오류에 대해 모니터링 서비스를 선택하는 코드들임 + // 0~1의 수치는 사용자 발생 오류의 몇 %를 저장할것인지 정하는 값 + // 0.1당 10%임 + // 0.1이니깐 사용자 100명중 10명의 오류 세션을 저장하는 형태() + tracesSampleRate: 0.1, + // tracesSampleRate는 사용자가 이용하는 서비스의 성능을 기록하는 속성 + replaysOnErrorSampleRate: 0.1, + // replaysOnErrorSampleRate는 세션을 버퍼라는 휘발성 메모리 공간에 보관해두다가 오류가 발생한 시점에 세션만 저장하는 속성 + + // replaysSessionSampleRate: 0.1, + // replaysSessionSampleRate는 사용자의 서비스 이용 처음부터 끝까지 모든 세션을 저장해두는 속성 + // 오류가 없어도 서비스 이용 사항을 세부적으로 추적 가능하지만 비용이 어마무시해서(0.1이 에러샘플녹화 1보다 더 많이 듬) 실배포에선 돈 진짜 많으면 켜두자 + // tracePropagationTargets: ["localhost", '백엔드 도메인 주소'] // tracePropagationTargets는 프론트엔드와 백엔드의 퍼포먼스 추적을 연결할때 사용하는 속성으로 백엔드도 Sentry를 사용해야 서로 연결 가능하다. }); From c7c604093b707b967f675c7d2e47eda5b64976f3 Mon Sep 17 00:00:00 2001 From: wldnjs990 Date: Wed, 4 Jun 2025 14:20:09 +0900 Subject: [PATCH 6/6] =?UTF-8?q?fix=20:=20=EC=84=BC=ED=8A=B8=EB=A6=AC=20?= =?UTF-8?q?=ED=82=A4=20env=EB=A1=9C=20=EB=B3=B4=EA=B4=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Sentry/instrument.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Sentry/instrument.ts b/src/Sentry/instrument.ts index 6522785..8c14e4b 100644 --- a/src/Sentry/instrument.ts +++ b/src/Sentry/instrument.ts @@ -2,7 +2,7 @@ import useAuthStore from '@/stores/authStore'; import * as Sentry from '@sentry/react'; Sentry.init({ - dsn: 'https://29d2c788d61a2d1e6647da9f16c01def@o4509101248413697.ingest.us.sentry.io/4509101251100672', + dsn: import.meta.env.VITE_SENTRY_URL, integrations: [ Sentry.browserTracingIntegration(), Sentry.replayIntegration({