Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sentry for monitor #147

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ui/apps/dashboard/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ dist
!.yarn/sdks
!.yarn/versions


# Sentry Config File
.env.sentry-build-plugin
2 changes: 2 additions & 0 deletions ui/apps/dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"@karmada/dashboard": "link:",
"@karmada/i18n-tool": "link:",
"@monaco-editor/react": "^4.6.0",
"@sentry/react": "^8.33.1",
"@sentry/vite-plugin": "^2.22.5",
"@tanstack/react-query": "^5.59.8",
"@uidotdev/usehooks": "^2.4.1",
"antd": "^5.21.3",
Expand Down
7 changes: 7 additions & 0 deletions ui/apps/dashboard/src/components/error/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import i18nInstance from '@/utils/i18n';
import type { ResultProps } from 'antd';
import { Result } from 'antd';
import { useRouteError } from 'react-router-dom';
import * as Sentry from '@sentry/react';
import { useEffect } from 'react';

const ErrorBoundary = (props: ResultProps) => {
const error = useRouteError() as Error;
useEffect(() => {
Sentry.captureException(error);
}, [error]);
return (
<Result
style={{ marginTop: '50vh', transform: 'translateY(-50%)' }}
Expand Down
100 changes: 57 additions & 43 deletions ui/apps/dashboard/src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,71 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
import i18nInstance, {getLang} from '@/utils/i18n';
import {initReactI18next} from 'react-i18next';
import {loader} from '@monaco-editor/react';
import i18nInstance, { getLang } from '@/utils/i18n';
import { initReactI18next } from 'react-i18next';
import { loader } from '@monaco-editor/react';
import * as monaco from 'monaco-editor';
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
// https://github.com/remcohaszing/monaco-yaml/issues/150
import yamlWorker from '@/utils/workaround-yaml.worker?worker';
import enTexts from '../locales/en-US.json';
import zhTexts from '../locales/zh-CN.json';
import {initRoute} from '@/routes/route.tsx';
import { initRoute } from '@/routes/route.tsx';
import * as Sentry from '@sentry/react';

Sentry.init({
dsn: 'https://11deae085432e4e68dc5dccf6d79162b@o4508215039623168.ingest.us.sentry.io/4508215089496064',
integrations: [
Sentry.browserTracingIntegration(),
Sentry.replayIntegration(),
],
// Tracing
tracesSampleRate: 1.0, // Capture 100% of the transactions
// Set 'tracePropagationTargets' to control for which URLs distributed tracing should be enabled
tracePropagationTargets: ['localhost', /^https:\/\/yourserver\.io\/api/],
// Session Replay
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
});

window.MonacoEnvironment = {
getWorker(_, label) {
if (label === 'yaml') {
return new yamlWorker();
}
return new editorWorker();
},
getWorker(_, label) {
if (label === 'yaml') {
return new yamlWorker();
}
return new editorWorker();
},
};
loader.config({monaco});
loader.config({ monaco });

i18nInstance
.use(initReactI18next) // passes i18n down to react-i18next
.init({
debug: true,
lng: getLang(), // if you're using a language detector, do not define the lng option
fallbackLng: ['zh-CN'],
resources: {
zh: {
translation: zhTexts,
},
en: {
translation: enTexts,
},
},
interpolation: {
escapeValue: false, // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
},
saveMissing: true, // send not translated keys to endpoint,
react: {
useSuspense: false,
},
})
.then(() => {
initRoute();
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App/>
</React.StrictMode>,
);
})
.catch(() => {

})
.use(initReactI18next) // passes i18n down to react-i18next
.init({
debug: true,
lng: getLang(), // if you're using a language detector, do not define the lng option
fallbackLng: ['zh-CN'],
resources: {
zh: {
translation: zhTexts,
},
en: {
translation: enTexts,
},
},
interpolation: {
escapeValue: false, // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
},
saveMissing: true, // send not translated keys to endpoint,
react: {
useSuspense: false,
},
})
.then(() => {
initRoute();
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
);
})
.catch(() => {});
5 changes: 4 additions & 1 deletion ui/apps/dashboard/src/routes/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import { createBrowserRouter, RouterProvider } from 'react-router-dom';
import * as Sentry from '@sentry/react';

import { routes } from './route.tsx';
import { routerBase } from '@/services/base';

const router = createBrowserRouter(routes, {
const sentryCreateBrowserRouter =
Sentry.wrapCreateBrowserRouter(createBrowserRouter);
const router = sentryCreateBrowserRouter(routes, {
basename: routerBase,
});
export default function Router() {
Expand Down
13 changes: 11 additions & 2 deletions ui/apps/dashboard/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { defineConfig, loadEnv, Plugin } from 'vite';
import { defineConfig, Plugin } from 'vite';
import react from '@vitejs/plugin-react';
import svgr from 'vite-plugin-svgr';
import path from 'path';
import { dynamicBase } from 'vite-plugin-dynamic-base';
import { sentryVitePlugin } from '@sentry/vite-plugin';

const replacePathPrefixPlugin = (): Plugin => {
return {
Expand All @@ -18,9 +19,11 @@ const replacePathPrefixPlugin = (): Plugin => {

// https://vitejs.dev/config/
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '');
return {
base: process.env.NODE_ENV === 'development' ? '' : '/static',
build: {
sourcemap: true, // Source map generation must be turned on
},
plugins: [
react(),
svgr(),
Expand All @@ -29,6 +32,12 @@ export default defineConfig(({ mode }) => {
publicPath: 'window.__dynamic_base__',
transformIndexHtml: true,
}),
// Put the Sentry vite plugin after all other plugins
sentryVitePlugin({
authToken: process.env.SENTRY_AUTH_TOKEN,
org: 'karmada-community',
project: 'karmada-dashboard',
}),
],
resolve: {
alias: [{ find: '@', replacement: path.resolve(__dirname, 'src') }],
Expand Down
Loading