Skip to content

Commit 29eed22

Browse files
committed
config: sentry 설정 추가
성능 및 에러 모니터링을 위한 sentry를 추가했습니다.
1 parent 2cdd50d commit 29eed22

File tree

8 files changed

+1180
-43
lines changed

8 files changed

+1180
-43
lines changed

instrument.server.mjs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { nodeProfilingIntegration } from '@sentry/profiling-node';
2+
import * as Sentry from '@sentry/react-router';
3+
4+
Sentry.init({
5+
dsn: 'https://8343c6ee467e6f35f22c570a68cd2e6e@o4509544992407552.ingest.us.sentry.io/4509548888391680',
6+
sendDefaultPii: true,
7+
// Enable logs to be sent to Sentry
8+
_experiments: { enableLogs: true },
9+
10+
integrations: [nodeProfilingIntegration()],
11+
tracesSampleRate: 1.0, // Capture 100% of the transactions
12+
profilesSampleRate: 1.0, // profile every transaction
13+
});

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
"version": "0.0.0",
55
"type": "module",
66
"scripts": {
7-
"dev": "react-router dev",
8-
"build": "react-router build",
7+
"dev": "NODE_OPTIONS='--import ./instrument.server.mjs' react-router dev",
8+
"build": "NODE_OPTIONS='--import ./instrument.server.mjs' react-router-serve ./build/server/index.js",
99
"start": "react-router-serve ./build/server/index.js",
1010
"typecheck": "react-router typegen && tsc",
1111
"test": "vitest",
@@ -21,6 +21,8 @@
2121
"@react-router/fs-routes": "^7.5.3",
2222
"@react-router/node": "^7.5.3",
2323
"@react-router/serve": "^7.5.3",
24+
"@sentry/profiling-node": "^9.30.0",
25+
"@sentry/react-router": "^9.30.0",
2426
"@stomp/stompjs": "^7.1.1",
2527
"@xstate/react": "^5.0.4",
2628
"clsx": "^2.1.1",
@@ -66,8 +68,6 @@
6668
},
6769
"packageManager": "[email protected]+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
6870
"msw": {
69-
"workerDirectory": [
70-
"public"
71-
]
71+
"workerDirectory": ["public"]
7272
}
7373
}

react-router.config.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import type { Config } from '@react-router/dev/config';
2+
import { sentryOnBuildEnd } from '@sentry/react-router';
23

34
export default {
45
appDirectory: './src/app',
56
ssr: true,
7+
buildEnd: async ({ viteConfig, reactRouterConfig, buildManifest }) => {
8+
await sentryOnBuildEnd({viteConfig, reactRouterConfig, buildManifest});
9+
},
610
} satisfies Config;

src/app/entry.client.tsx

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,41 @@
1+
import * as Sentry from '@sentry/react-router';
12
/* v8 ignore start */
23
import { startTransition } from 'react';
34
import { hydrateRoot } from 'react-dom/client';
45
import { HydratedRouter } from 'react-router/dom';
56

7+
Sentry.init({
8+
dsn: 'https://8343c6ee467e6f35f22c570a68cd2e6e@o4509544992407552.ingest.us.sentry.io/4509548888391680',
9+
10+
sendDefaultPii: true,
11+
12+
integrations: [
13+
Sentry.reactRouterTracingIntegration(),
14+
Sentry.replayIntegration(),
15+
Sentry.feedbackIntegration({
16+
colorScheme: 'system',
17+
}),
18+
],
19+
20+
_experiments: { enableLogs: true },
21+
22+
tracesSampleRate: 1.0,
23+
24+
// Set `tracePropagationTargets` to declare which URL(s) should have trace propagation enabled
25+
tracePropagationTargets: [/^\//, /^https:\/\/investfuture\.my\/api/],
26+
// Capture Replay for 10% of all sessions,
27+
// plus 100% of sessions with an error
28+
replaysSessionSampleRate: 0.1,
29+
replaysOnErrorSampleRate: 1.0,
30+
});
31+
632
async function prepareApp() {
733
return Promise.resolve();
834
}
935

1036
prepareApp().then(() => {
1137
startTransition(() => {
12-
hydrateRoot(
13-
document,
14-
// <StrictMode>
15-
// </StrictMode>,
16-
<HydratedRouter />,
17-
);
38+
hydrateRoot(document, <HydratedRouter />);
1839
});
1940
});
2041

src/app/entry.server.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
import { PassThrough } from 'node:stream';
33

44
import { createReadableStreamFromReadable } from '@react-router/node';
5+
import {
6+
getMetaTagTransformer,
7+
wrapSentryHandleRequest,
8+
} from '@sentry/react-router';
59
import { isbot } from 'isbot';
610
import type { RenderToPipeableStreamOptions } from 'react-dom/server';
711
import { renderToPipeableStream } from 'react-dom/server';
@@ -10,7 +14,7 @@ import { ServerRouter } from 'react-router';
1014

1115
export const streamTimeout = 5_000;
1216

13-
export default function handleRequest(
17+
function handleRequest(
1418
request: Request,
1519
responseStatusCode: number,
1620
responseHeaders: Headers,
@@ -47,7 +51,7 @@ export default function handleRequest(
4751
}),
4852
);
4953

50-
pipe(body);
54+
pipe(getMetaTagTransformer(body));
5155
},
5256
onShellError(error: unknown) {
5357
reject(error);
@@ -71,4 +75,5 @@ export default function handleRequest(
7175
});
7276
}
7377

78+
export default wrapSentryHandleRequest(handleRequest);
7479
/* v8 ignore end */

src/app/root.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import * as Sentry from '@sentry/react-router';
2+
import { preload } from 'react-dom';
13
import {
24
Links,
35
Meta,
@@ -6,12 +8,11 @@ import {
68
ScrollRestoration,
79
isRouteErrorResponse,
810
} from 'react-router';
11+
import { Slide } from 'react-toastify';
912
import { ToastContainer } from 'react-toastify/unstyled';
10-
import type { Route } from './+types/root';
1113

1214
import './app.css';
13-
import { preload } from 'react-dom';
14-
import { Slide } from 'react-toastify';
15+
import type { Route } from './+types/root';
1516
import StompProvider from './provider/StompProvider';
1617
import UserIdProvider from './provider/UserInfoProvider';
1718

@@ -121,9 +122,12 @@ export function ErrorBoundary({ error }: Route.ErrorBoundaryProps) {
121122
error.status === 404
122123
? 'The requested page could not be found.'
123124
: error.statusText || details;
124-
} else if (import.meta.env.DEV && error && error instanceof Error) {
125-
details = error.message;
126-
stack = error.stack;
125+
} else if (error && error instanceof Error) {
126+
Sentry.captureException(error);
127+
if (import.meta.env.DEV) {
128+
details = error.message;
129+
stack = error.stack;
130+
}
127131
}
128132

129133
return (

vite.config.ts

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,38 @@
11
import { reactRouter } from '@react-router/dev/vite';
2+
import {
3+
type SentryReactRouterBuildOptions,
4+
sentryReactRouter,
5+
} from '@sentry/react-router';
26
import svgr from '@svgr/rollup';
37
import tailwindcss from '@tailwindcss/vite';
48
import { visualizer } from 'rollup-plugin-visualizer';
5-
import { type PluginOption, defineConfig } from 'vite';
9+
import { type PluginOption, defineConfig, loadEnv } from 'vite';
610
import tsconfigPaths from 'vite-tsconfig-paths';
711

8-
export default defineConfig({
9-
plugins: [
10-
svgr(),
11-
tailwindcss(),
12-
reactRouter(),
13-
tsconfigPaths(),
14-
visualizer() as PluginOption,
15-
],
16-
optimizeDeps: {
17-
exclude: ['@amcharts/amcharts5'],
18-
},
19-
build: {
20-
rollupOptions: {
21-
external: ['d3-geo,d3-selection,d3-transition'],
12+
export default defineConfig((config) => {
13+
const env = loadEnv(config.mode, process.cwd());
14+
const sentryConfig: SentryReactRouterBuildOptions = {
15+
org: env.VITE_SENTRY_ORG,
16+
project: env.VITE_SENTRY_PROJECT,
17+
authToken: env.VITE_SENTRY_AUTH_TOKEN,
18+
};
19+
20+
return {
21+
plugins: [
22+
svgr(),
23+
tailwindcss(),
24+
reactRouter(),
25+
tsconfigPaths(),
26+
visualizer() as PluginOption,
27+
sentryReactRouter(sentryConfig, config),
28+
],
29+
optimizeDeps: {
30+
exclude: ['@amcharts/amcharts5'],
31+
},
32+
build: {
33+
rollupOptions: {
34+
external: ['d3-geo,d3-selection,d3-transition'],
35+
},
2236
},
23-
},
37+
};
2438
});

0 commit comments

Comments
 (0)