mirror of
https://github.com/hasura/graphql-engine.git
synced 2024-12-15 17:31:56 +03:00
console: Add Sentry
PR-URL: https://github.com/hasura/graphql-engine-mono/pull/5699 Co-authored-by: Rishichandra Wawhal <27274869+wawhal@users.noreply.github.com> Co-authored-by: Daniel Harvey <4729125+danieljharvey@users.noreply.github.com> GitOrigin-RevId: 00f2c5d25012b21f4e8763ef578598a3a11896e4
This commit is contained in:
parent
913f3f12e4
commit
a0f4f00bfd
5
console/cypress/global.d.ts
vendored
5
console/cypress/global.d.ts
vendored
@ -18,6 +18,11 @@ interface Env {
|
|||||||
serverVersion: string;
|
serverVersion: string;
|
||||||
telemetryTopic: string;
|
telemetryTopic: string;
|
||||||
urlPrefix: string;
|
urlPrefix: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Corresponds to the HASURA_CONSOLE_SENTRY_DSN environment variable
|
||||||
|
*/
|
||||||
|
consoleSentryDsn: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Window {
|
interface Window {
|
||||||
|
@ -11,7 +11,7 @@ export {
|
|||||||
export { fetchConsoleNotifications } from '../src/components/Main/Actions';
|
export { fetchConsoleNotifications } from '../src/components/Main/Actions';
|
||||||
export { default as NotificationSection } from '../src/components/Main/NotificationSection';
|
export { default as NotificationSection } from '../src/components/Main/NotificationSection';
|
||||||
export { default as Onboarding } from '../src/components/Common/Onboarding';
|
export { default as Onboarding } from '../src/components/Common/Onboarding';
|
||||||
export { analyticsToolsUtils } from '../src/features/AnalyticsToolsUtils';
|
export { tracingTools } from '../src/features/TracingTools';
|
||||||
export { OnboardingWizard } from '../src/features/OnboardingWizard';
|
export { OnboardingWizard } from '../src/features/OnboardingWizard';
|
||||||
export { makeGrowthExperimentsClient } from '../src/features/GrowthExperiments';
|
export { makeGrowthExperimentsClient } from '../src/features/GrowthExperiments';
|
||||||
export { default as PageNotFound } from '../src/components/Error/PageNotFound';
|
export { default as PageNotFound } from '../src/components/Error/PageNotFound';
|
||||||
|
251
console/package-lock.json
generated
251
console/package-lock.json
generated
@ -21,6 +21,8 @@
|
|||||||
"@radix-ui/react-tabs": "^1.0.0",
|
"@radix-ui/react-tabs": "^1.0.0",
|
||||||
"@radix-ui/react-tooltip": "^1.0.0",
|
"@radix-ui/react-tooltip": "^1.0.0",
|
||||||
"@reduxjs/toolkit": "^1.5.1",
|
"@reduxjs/toolkit": "^1.5.1",
|
||||||
|
"@sentry/react": "7.11.1",
|
||||||
|
"@sentry/tracing": "7.11.1",
|
||||||
"@types/lodash.get": "^4.4.6",
|
"@types/lodash.get": "^4.4.6",
|
||||||
"@xstate/react": "^2.0.0",
|
"@xstate/react": "^2.0.0",
|
||||||
"ace-builds": "^1.4.11",
|
"ace-builds": "^1.4.11",
|
||||||
@ -5507,6 +5509,129 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@sentry/browser": {
|
||||||
|
"version": "7.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.11.1.tgz",
|
||||||
|
"integrity": "sha512-k2XHuzPfnm8VJPK5eWd1+Y5VCgN42sLveb8Qxc3prb5PSL416NWMLZaoB7RMIhy430fKrSFiosnm6QDk2M6pbA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@sentry/core": "7.11.1",
|
||||||
|
"@sentry/types": "7.11.1",
|
||||||
|
"@sentry/utils": "7.11.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/browser/node_modules/tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/core": {
|
||||||
|
"version": "7.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.11.1.tgz",
|
||||||
|
"integrity": "sha512-kaDSZ6VNuO4ZZdqUOOX6XM6x+kjo2bMnDQ3IJG51FPvVjr8lXYhXj1Ccxcot3pBYAIWPPby2+vNDOXllmXqoBA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@sentry/hub": "7.11.1",
|
||||||
|
"@sentry/types": "7.11.1",
|
||||||
|
"@sentry/utils": "7.11.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/core/node_modules/tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/hub": {
|
||||||
|
"version": "7.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-7.11.1.tgz",
|
||||||
|
"integrity": "sha512-M6ClgdXdptS0lUBKB5KpXXe2qMQhsoiEN2pEGRI6+auqhfHCUQB1ZXsfjiOYexKC9fwx7TyFyZ9Jcaf2DTxEhw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@sentry/types": "7.11.1",
|
||||||
|
"@sentry/utils": "7.11.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/hub/node_modules/tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/react": {
|
||||||
|
"version": "7.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/react/-/react-7.11.1.tgz",
|
||||||
|
"integrity": "sha512-kp/vBgwNrlFEtW3e6DY9T4s3di9peL66n5UIY5n6dYkiN7A7D6/Kz1WJ/ZCL82DvaCMEY577wNyr2C+442l7fw==",
|
||||||
|
"dependencies": {
|
||||||
|
"@sentry/browser": "7.11.1",
|
||||||
|
"@sentry/types": "7.11.1",
|
||||||
|
"@sentry/utils": "7.11.1",
|
||||||
|
"hoist-non-react-statics": "^3.3.2",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "15.x || 16.x || 17.x || 18.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/react/node_modules/tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/tracing": {
|
||||||
|
"version": "7.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.11.1.tgz",
|
||||||
|
"integrity": "sha512-ilgnHfpdYUWKG/5yAXIfIbPVsCfrC4ONFBR/wN25/hdAyVfXMa3AJx7NCCXxZBOPDWH3hMW8rl4La5yuDbXofg==",
|
||||||
|
"dependencies": {
|
||||||
|
"@sentry/hub": "7.11.1",
|
||||||
|
"@sentry/types": "7.11.1",
|
||||||
|
"@sentry/utils": "7.11.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/tracing/node_modules/tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/types": {
|
||||||
|
"version": "7.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.11.1.tgz",
|
||||||
|
"integrity": "sha512-gIEhOPxC2cjrxQ0+K2SFJ1P6e/an5osSxVc9OOtekN28eHtVsXFCLB8XVWeNQnS7N2VkrVrkqORMBz1kvIcvVQ==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/utils": {
|
||||||
|
"version": "7.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.11.1.tgz",
|
||||||
|
"integrity": "sha512-tRVXNT5O9ilkV31pyHeTqA1PcPQfMV/2OR6yUYM4ah+QVISovC0f0ybhByuH5nYg6x/Gsnx1o7pc8L1GE3+O7A==",
|
||||||
|
"dependencies": {
|
||||||
|
"@sentry/types": "7.11.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@sentry/utils/node_modules/tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
},
|
||||||
"node_modules/@sinonjs/commons": {
|
"node_modules/@sinonjs/commons": {
|
||||||
"version": "1.8.3",
|
"version": "1.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
|
||||||
@ -6022,6 +6147,21 @@
|
|||||||
"lodash": "^4.17.15"
|
"lodash": "^4.17.15"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@storybook/addon-interactions/node_modules/fork-ts-checker-webpack-plugin/node_modules/semver": {
|
||||||
|
"version": "7.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz",
|
||||||
|
"integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==",
|
||||||
|
"extraneous": true,
|
||||||
|
"dependencies": {
|
||||||
|
"lru-cache": "^6.0.0"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@storybook/addon-links": {
|
"node_modules/@storybook/addon-links": {
|
||||||
"version": "6.5.10",
|
"version": "6.5.10",
|
||||||
"resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-6.5.10.tgz",
|
"resolved": "https://registry.npmjs.org/@storybook/addon-links/-/addon-links-6.5.10.tgz",
|
||||||
@ -45705,6 +45845,117 @@
|
|||||||
"any-observable": "^0.3.0"
|
"any-observable": "^0.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@sentry/browser": {
|
||||||
|
"version": "7.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.11.1.tgz",
|
||||||
|
"integrity": "sha512-k2XHuzPfnm8VJPK5eWd1+Y5VCgN42sLveb8Qxc3prb5PSL416NWMLZaoB7RMIhy430fKrSFiosnm6QDk2M6pbA==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/core": "7.11.1",
|
||||||
|
"@sentry/types": "7.11.1",
|
||||||
|
"@sentry/utils": "7.11.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@sentry/core": {
|
||||||
|
"version": "7.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.11.1.tgz",
|
||||||
|
"integrity": "sha512-kaDSZ6VNuO4ZZdqUOOX6XM6x+kjo2bMnDQ3IJG51FPvVjr8lXYhXj1Ccxcot3pBYAIWPPby2+vNDOXllmXqoBA==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/hub": "7.11.1",
|
||||||
|
"@sentry/types": "7.11.1",
|
||||||
|
"@sentry/utils": "7.11.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@sentry/hub": {
|
||||||
|
"version": "7.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-7.11.1.tgz",
|
||||||
|
"integrity": "sha512-M6ClgdXdptS0lUBKB5KpXXe2qMQhsoiEN2pEGRI6+auqhfHCUQB1ZXsfjiOYexKC9fwx7TyFyZ9Jcaf2DTxEhw==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/types": "7.11.1",
|
||||||
|
"@sentry/utils": "7.11.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@sentry/react": {
|
||||||
|
"version": "7.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/react/-/react-7.11.1.tgz",
|
||||||
|
"integrity": "sha512-kp/vBgwNrlFEtW3e6DY9T4s3di9peL66n5UIY5n6dYkiN7A7D6/Kz1WJ/ZCL82DvaCMEY577wNyr2C+442l7fw==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/browser": "7.11.1",
|
||||||
|
"@sentry/types": "7.11.1",
|
||||||
|
"@sentry/utils": "7.11.1",
|
||||||
|
"hoist-non-react-statics": "^3.3.2",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@sentry/tracing": {
|
||||||
|
"version": "7.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.11.1.tgz",
|
||||||
|
"integrity": "sha512-ilgnHfpdYUWKG/5yAXIfIbPVsCfrC4ONFBR/wN25/hdAyVfXMa3AJx7NCCXxZBOPDWH3hMW8rl4La5yuDbXofg==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/hub": "7.11.1",
|
||||||
|
"@sentry/types": "7.11.1",
|
||||||
|
"@sentry/utils": "7.11.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@sentry/types": {
|
||||||
|
"version": "7.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.11.1.tgz",
|
||||||
|
"integrity": "sha512-gIEhOPxC2cjrxQ0+K2SFJ1P6e/an5osSxVc9OOtekN28eHtVsXFCLB8XVWeNQnS7N2VkrVrkqORMBz1kvIcvVQ=="
|
||||||
|
},
|
||||||
|
"@sentry/utils": {
|
||||||
|
"version": "7.11.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.11.1.tgz",
|
||||||
|
"integrity": "sha512-tRVXNT5O9ilkV31pyHeTqA1PcPQfMV/2OR6yUYM4ah+QVISovC0f0ybhByuH5nYg6x/Gsnx1o7pc8L1GE3+O7A==",
|
||||||
|
"requires": {
|
||||||
|
"@sentry/types": "7.11.1",
|
||||||
|
"tslib": "^1.9.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": {
|
||||||
|
"version": "1.14.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
|
||||||
|
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"@sinonjs/commons": {
|
"@sinonjs/commons": {
|
||||||
"version": "1.8.3",
|
"version": "1.8.3",
|
||||||
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
|
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz",
|
||||||
|
@ -89,6 +89,8 @@
|
|||||||
"@radix-ui/react-tabs": "^1.0.0",
|
"@radix-ui/react-tabs": "^1.0.0",
|
||||||
"@radix-ui/react-tooltip": "^1.0.0",
|
"@radix-ui/react-tooltip": "^1.0.0",
|
||||||
"@reduxjs/toolkit": "^1.5.1",
|
"@reduxjs/toolkit": "^1.5.1",
|
||||||
|
"@sentry/react": "7.11.1",
|
||||||
|
"@sentry/tracing": "7.11.1",
|
||||||
"@types/lodash.get": "^4.4.6",
|
"@types/lodash.get": "^4.4.6",
|
||||||
"@xstate/react": "^2.0.0",
|
"@xstate/react": "^2.0.0",
|
||||||
"ace-builds": "^1.4.11",
|
"ace-builds": "^1.4.11",
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
/* eslint no-underscore-dangle: 0 */
|
/* eslint no-underscore-dangle: 0 */
|
||||||
import { SERVER_CONSOLE_MODE } from './constants';
|
|
||||||
import { getFeaturesCompatibility } from './helpers/versionUtils';
|
import { getFeaturesCompatibility } from './helpers/versionUtils';
|
||||||
import { stripTrailingSlash } from './components/Common/utils/urlUtils';
|
|
||||||
|
import { sentry } from './features/TracingTools/sentry';
|
||||||
import { isEmpty } from './components/Common/utils/jsUtils';
|
import { isEmpty } from './components/Common/utils/jsUtils';
|
||||||
|
import { stripTrailingSlash } from './components/Common/utils/urlUtils';
|
||||||
|
|
||||||
|
import { SERVER_CONSOLE_MODE } from './constants';
|
||||||
|
|
||||||
type ConsoleType = 'oss' | 'cloud' | 'pro' | 'pro-lite';
|
type ConsoleType = 'oss' | 'cloud' | 'pro' | 'pro-lite';
|
||||||
|
|
||||||
@ -18,6 +21,7 @@ type OSSServerEnv = {
|
|||||||
serverVersion: string; // e.g. "v2.7.0"
|
serverVersion: string; // e.g. "v2.7.0"
|
||||||
urlPrefix: string; // e.g. "/console"
|
urlPrefix: string; // e.g. "/console"
|
||||||
cdnAssets: boolean;
|
cdnAssets: boolean;
|
||||||
|
consoleSentryDsn?: string; // Corresponds to the HASURA_CONSOLE_SENTRY_DSN environment variable
|
||||||
};
|
};
|
||||||
|
|
||||||
type ProServerEnv = {
|
type ProServerEnv = {
|
||||||
@ -30,6 +34,7 @@ type ProServerEnv = {
|
|||||||
isAdminSecretSet: boolean;
|
isAdminSecretSet: boolean;
|
||||||
serverVersion: string;
|
serverVersion: string;
|
||||||
urlPrefix: string;
|
urlPrefix: string;
|
||||||
|
consoleSentryDsn?: string; // Corresponds to the HASURA_CONSOLE_SENTRY_DSN environment variable
|
||||||
};
|
};
|
||||||
|
|
||||||
type ProLiteServerEnv = {
|
type ProLiteServerEnv = {
|
||||||
@ -42,6 +47,7 @@ type ProLiteServerEnv = {
|
|||||||
isAdminSecretSet: boolean;
|
isAdminSecretSet: boolean;
|
||||||
serverVersion: string;
|
serverVersion: string;
|
||||||
urlPrefix: string;
|
urlPrefix: string;
|
||||||
|
consoleSentryDsn?: string; // Corresponds to the HASURA_CONSOLE_SENTRY_DSN environment variable
|
||||||
};
|
};
|
||||||
|
|
||||||
type CloudUserRole = 'owner' | 'user';
|
type CloudUserRole = 'owner' | 'user';
|
||||||
@ -64,6 +70,8 @@ type CloudServerEnv = {
|
|||||||
tenantID: UUID;
|
tenantID: UUID;
|
||||||
urlPrefix: string;
|
urlPrefix: string;
|
||||||
userRole: CloudUserRole;
|
userRole: CloudUserRole;
|
||||||
|
userId?: string;
|
||||||
|
consoleSentryDsn?: string; // Corresponds to the HASURA_CONSOLE_SENTRY_DSN environment variable
|
||||||
};
|
};
|
||||||
|
|
||||||
type OSSCliEnv = {
|
type OSSCliEnv = {
|
||||||
@ -78,6 +86,7 @@ type OSSCliEnv = {
|
|||||||
enableTelemetry: boolean;
|
enableTelemetry: boolean;
|
||||||
serverVersion: string;
|
serverVersion: string;
|
||||||
urlPrefix: string;
|
urlPrefix: string;
|
||||||
|
consoleSentryDsn?: string; // Corresponds to the HASURA_CONSOLE_SENTRY_DSN environment variable
|
||||||
};
|
};
|
||||||
|
|
||||||
export type CloudCliEnv = {
|
export type CloudCliEnv = {
|
||||||
@ -100,6 +109,7 @@ export type CloudCliEnv = {
|
|||||||
pro: true;
|
pro: true;
|
||||||
projectId: UUID;
|
projectId: UUID;
|
||||||
isAdminSecretSet: boolean;
|
isAdminSecretSet: boolean;
|
||||||
|
consoleSentryDsn?: string; // Corresponds to the HASURA_CONSOLE_SENTRY_DSN environment variable
|
||||||
};
|
};
|
||||||
|
|
||||||
type ProCliEnv = CloudCliEnv;
|
type ProCliEnv = CloudCliEnv;
|
||||||
@ -124,6 +134,9 @@ export type EnvVars = {
|
|||||||
eeMode?: string;
|
eeMode?: string;
|
||||||
consoleId?: string;
|
consoleId?: string;
|
||||||
userRole?: string;
|
userRole?: string;
|
||||||
|
userId?: string;
|
||||||
|
cdnAssets?: boolean;
|
||||||
|
consoleSentryDsn?: string; // Corresponds to the HASURA_CONSOLE_SENTRY_DSN environment variable
|
||||||
} & (
|
} & (
|
||||||
| OSSServerEnv
|
| OSSServerEnv
|
||||||
| CloudServerEnv
|
| CloudServerEnv
|
||||||
@ -138,6 +151,11 @@ export type EnvVars = {
|
|||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
__env: EnvVars;
|
__env: EnvVars;
|
||||||
|
/**
|
||||||
|
* Consuming Heap is allowed only through the TracingTools/heap module, never directly.
|
||||||
|
* @deprecated (when marked as deprecated, the IDE shows it as strikethrough'ed, helping the
|
||||||
|
* developers realize that they should not use it)
|
||||||
|
*/
|
||||||
heap?: {
|
heap?: {
|
||||||
addUserProperties: (properties: Record<string, string>) => void;
|
addUserProperties: (properties: Record<string, string>) => void;
|
||||||
};
|
};
|
||||||
@ -154,6 +172,7 @@ const globals = {
|
|||||||
apiPort: window.__env?.apiPort,
|
apiPort: window.__env?.apiPort,
|
||||||
dataApiUrl: stripTrailingSlash(window.__env?.dataApiUrl || ''), // overridden below if server mode
|
dataApiUrl: stripTrailingSlash(window.__env?.dataApiUrl || ''), // overridden below if server mode
|
||||||
urlPrefix: stripTrailingSlash(window.__env?.urlPrefix || '/'), // overridden below if server mode in production
|
urlPrefix: stripTrailingSlash(window.__env?.urlPrefix || '/'), // overridden below if server mode in production
|
||||||
|
consoleSentryDsn: sentry.parseSentryDsn(window.__env?.consoleSentryDsn),
|
||||||
adminSecret: window.__env?.adminSecret || null, // gets updated after login/logout in server mode
|
adminSecret: window.__env?.adminSecret || null, // gets updated after login/logout in server mode
|
||||||
isAdminSecretSet:
|
isAdminSecretSet:
|
||||||
window.__env?.isAdminSecretSet ||
|
window.__env?.isAdminSecretSet ||
|
||||||
@ -178,6 +197,7 @@ const globals = {
|
|||||||
cloudDataApiUrl: `${window.location?.protocol}//data.${window.__env?.cloudRootDomain}`,
|
cloudDataApiUrl: `${window.location?.protocol}//data.${window.__env?.cloudRootDomain}`,
|
||||||
luxDataHost: window.__env?.luxDataHost,
|
luxDataHost: window.__env?.luxDataHost,
|
||||||
userRole: window.__env?.userRole || undefined,
|
userRole: window.__env?.userRole || undefined,
|
||||||
|
userId: window.__env?.userId || undefined,
|
||||||
consoleType: window.__env?.consoleType || '',
|
consoleType: window.__env?.consoleType || '',
|
||||||
eeMode: window.__env?.eeMode === 'true',
|
eeMode: window.__env?.eeMode === 'true',
|
||||||
};
|
};
|
||||||
|
@ -4,20 +4,22 @@
|
|||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
import { useBasename } from 'history';
|
||||||
import { Provider } from 'react-redux';
|
import { Provider } from 'react-redux';
|
||||||
|
|
||||||
import { Router, browserHistory } from 'react-router';
|
import { Router, browserHistory } from 'react-router';
|
||||||
import { syncHistoryWithStore } from 'react-router-redux';
|
import { syncHistoryWithStore } from 'react-router-redux';
|
||||||
import { useBasename } from 'history';
|
|
||||||
import { ReactQueryProvider } from './lib/reactQuery';
|
|
||||||
import './theme/tailwind.css';
|
import './theme/tailwind.css';
|
||||||
import './theme/legacy-boostrap.css';
|
import './theme/legacy-boostrap.css';
|
||||||
|
|
||||||
import getRoutes from './routes';
|
import { tracingTools } from './features/TracingTools';
|
||||||
|
import { ReactQueryProvider } from './lib/reactQuery';
|
||||||
|
|
||||||
import globals from './Globals';
|
import globals from './Globals';
|
||||||
import { store } from './store';
|
import { store } from './store';
|
||||||
|
import getRoutes from './routes';
|
||||||
|
|
||||||
|
tracingTools.sentry.startTracing(globals, window.__env);
|
||||||
|
|
||||||
const hashLinkScroll = () => {
|
const hashLinkScroll = () => {
|
||||||
const { hash } = window.location;
|
const { hash } = window.location;
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
import { heap } from './heap';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Common utils for analytics tools, could be extended to export functions for other tools like Sentry, etc.
|
|
||||||
*/
|
|
||||||
export const analyticsToolsUtils = {
|
|
||||||
heap,
|
|
||||||
};
|
|
@ -1,6 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* A heap object that attempts to mirror the actual heap API, while handling the nullability check
|
* A heap object that attempts to mirror the actual heap API, while handling the nullability check.
|
||||||
* Currently only implements `addUserProperties`. More functions: identify, track etc can be added
|
|
||||||
*/
|
*/
|
||||||
export const heap = {
|
export const heap = {
|
||||||
addUserProperties: (props: Record<string, string>) => {
|
addUserProperties: (props: Record<string, string>) => {
|
10
console/src/features/TracingTools/index.ts
Normal file
10
console/src/features/TracingTools/index.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { heap } from './heap';
|
||||||
|
import { sentry } from './sentry';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Common utils for tracing tools.
|
||||||
|
*/
|
||||||
|
export const tracingTools = {
|
||||||
|
heap,
|
||||||
|
sentry,
|
||||||
|
};
|
@ -0,0 +1,16 @@
|
|||||||
|
import { getSentryEnvironment } from './getSentryEnvironment';
|
||||||
|
|
||||||
|
describe('getSentryEnvironment', () => {
|
||||||
|
it.each`
|
||||||
|
hostname | expectedEnvironment
|
||||||
|
${'localhost'} | ${'local'}
|
||||||
|
${'stagingHostname'} | ${'stagingHostname'}
|
||||||
|
${'unmanagedHostname'} | ${'unmanagedHostname'}
|
||||||
|
${'hge-mono-pr-3792.herokuapp.com'} | ${'hge-mono-pr.herokuapp.com'}
|
||||||
|
`(
|
||||||
|
`When invoked with '$hostname', then should return '$expectedEnvironment'`,
|
||||||
|
({ hostname, expectedEnvironment }) => {
|
||||||
|
expect(getSentryEnvironment(hostname)).toEqual(expectedEnvironment);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
@ -0,0 +1,17 @@
|
|||||||
|
export function getSentryEnvironment(windowLocationHostname: string) {
|
||||||
|
if (windowLocationHostname === 'localhost') {
|
||||||
|
return 'local';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (windowLocationHostname.startsWith('hge-mono-pr')) {
|
||||||
|
// Allow grouping all the PRs under the same environment in Sentry
|
||||||
|
return 'hge-mono-pr.herokuapp.com';
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Please note that returning the hostname allows
|
||||||
|
1. Not to expose the staging URL in the OSS repo
|
||||||
|
2. Easily detect unmanaged hosts in Sentry
|
||||||
|
*/
|
||||||
|
return windowLocationHostname;
|
||||||
|
}
|
104
console/src/features/TracingTools/sentry/core/getSentryTags.ts
Normal file
104
console/src/features/TracingTools/sentry/core/getSentryTags.ts
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import type { EnvVars } from '../../../../Globals';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the tags to be used in Sentry.
|
||||||
|
*
|
||||||
|
* ATTENTION: To avoid leaking sensitive data, it's better to whitelist vars instead of
|
||||||
|
* blacklisting them. It would be easier to filter out the adminSecret and tracking whatever
|
||||||
|
* else, but what happens if in the future some more secret-like vars will be added? They would
|
||||||
|
* accidentally be sent to Sentry, something that we should avoid.
|
||||||
|
*/
|
||||||
|
export function getSentryTags(envVars: EnvVars) {
|
||||||
|
if (envVars.consoleMode === 'cli') {
|
||||||
|
if ('pro' in envVars) {
|
||||||
|
return {
|
||||||
|
pro: envVars.pro,
|
||||||
|
apiHost: envVars.apiHost,
|
||||||
|
apiPort: envVars.apiPort,
|
||||||
|
cliUUID: envVars.cliUUID,
|
||||||
|
urlPrefix: envVars.urlPrefix,
|
||||||
|
projectId: envVars.projectId,
|
||||||
|
assetsPath: envVars.assetsPath,
|
||||||
|
dataApiUrl: envVars.dataApiUrl,
|
||||||
|
consoleMode: envVars.consoleMode,
|
||||||
|
adminSecret: envVars.adminSecret,
|
||||||
|
consolePath: envVars.consolePath,
|
||||||
|
serverVersion: envVars.serverVersion,
|
||||||
|
enableTelemetry: envVars.enableTelemetry,
|
||||||
|
isAdminSecretSet: envVars.isAdminSecretSet,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
apiHost: envVars.apiHost,
|
||||||
|
apiPort: envVars.apiPort,
|
||||||
|
cliUUID: envVars.cliUUID,
|
||||||
|
urlPrefix: envVars.urlPrefix,
|
||||||
|
assetsPath: envVars.assetsPath,
|
||||||
|
dataApiUrl: envVars.dataApiUrl,
|
||||||
|
consoleMode: envVars.consoleMode,
|
||||||
|
consolePath: envVars.consolePath,
|
||||||
|
serverVersion: envVars.serverVersion,
|
||||||
|
enableTelemetry: envVars.enableTelemetry,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (envVars.consoleType) {
|
||||||
|
case 'oss':
|
||||||
|
return {
|
||||||
|
urlPrefix: envVars.urlPrefix,
|
||||||
|
cdnAssets: envVars.cdnAssets,
|
||||||
|
assetsPath: envVars.assetsPath,
|
||||||
|
consoleMode: envVars.consoleMode,
|
||||||
|
consoleType: envVars.consoleType,
|
||||||
|
consolePath: envVars.consolePath,
|
||||||
|
serverVersion: envVars.serverVersion,
|
||||||
|
enableTelemetry: envVars.enableTelemetry,
|
||||||
|
isAdminSecretSet: envVars.isAdminSecretSet,
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'pro':
|
||||||
|
return {
|
||||||
|
consoleId: envVars.consoleId,
|
||||||
|
urlPrefix: envVars.urlPrefix,
|
||||||
|
assetsPath: envVars.assetsPath,
|
||||||
|
consoleType: envVars.consoleType,
|
||||||
|
consoleMode: envVars.consoleMode,
|
||||||
|
consolePath: envVars.consolePath,
|
||||||
|
serverVersion: envVars.serverVersion,
|
||||||
|
enableTelemetry: envVars.enableTelemetry,
|
||||||
|
isAdminSecretSet: envVars.isAdminSecretSet,
|
||||||
|
};
|
||||||
|
|
||||||
|
case 'cloud':
|
||||||
|
return {
|
||||||
|
eeMode: envVars.eeMode,
|
||||||
|
tenantID: envVars.tenantID,
|
||||||
|
userRole: envVars.userRole,
|
||||||
|
consoleId: envVars.consoleId,
|
||||||
|
projectID: envVars.projectID,
|
||||||
|
urlPrefix: envVars.urlPrefix,
|
||||||
|
assetsPath: envVars.assetsPath,
|
||||||
|
dataApiUrl: envVars.dataApiUrl,
|
||||||
|
consoleMode: envVars.consoleMode,
|
||||||
|
consoleType: envVars.consoleType,
|
||||||
|
consolePath: envVars.consolePath,
|
||||||
|
luxDataHost: envVars.luxDataHost,
|
||||||
|
serverVersion: envVars.serverVersion,
|
||||||
|
cloudRootDomain: envVars.cloudRootDomain,
|
||||||
|
isAdminSecretSet: envVars.isAdminSecretSet,
|
||||||
|
herokuOAuthClientId: envVars.herokuOAuthClientId,
|
||||||
|
};
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.warn('Unknown Console version');
|
||||||
|
|
||||||
|
return {
|
||||||
|
// This is a fallback it should never happen. If it happens, the above cases should be extended.
|
||||||
|
unknownConsole: true,
|
||||||
|
|
||||||
|
consoleMode: envVars.consoleMode,
|
||||||
|
consoleType: envVars.consoleType,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
import * as Sentry from '@sentry/react';
|
||||||
|
|
||||||
|
export function isSentryAlreadyStarted() {
|
||||||
|
// See https://github.com/getsentry/sentry-go/issues/9#issuecomment-619615289
|
||||||
|
const tracingAlreadyStarted = !!Sentry.getCurrentHub().getClient();
|
||||||
|
|
||||||
|
return tracingAlreadyStarted;
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
export function logSentryEnabled(environment: string) {
|
||||||
|
console.group();
|
||||||
|
console.log(
|
||||||
|
'%c Sentry Tracing Enabled ',
|
||||||
|
'background: #A0D7D1; color: black; display: block;'
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
`%c Sentry Environment: ${environment} `,
|
||||||
|
'background: #A0D7D1; color: black; display: block;'
|
||||||
|
);
|
||||||
|
console.groupEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function logSentryDisabled() {
|
||||||
|
// Agree with https://github.com/hasura/graphql-engine-mono/pull/5699#issuecomment-1234205492
|
||||||
|
// we are not going to log anything to the user until we have a user-facing doc that speaks about
|
||||||
|
// Sentry
|
||||||
|
// TODO: log the missing/invalid status
|
||||||
|
return;
|
||||||
|
|
||||||
|
console.group();
|
||||||
|
console.log(
|
||||||
|
'%c Sentry Tracing Disabled ',
|
||||||
|
'background: #A0D7D1; color: black; display: block;'
|
||||||
|
);
|
||||||
|
console.log(
|
||||||
|
'%c Provide HASURA_CONSOLE_SENTRY_DSN env variable to enable it ',
|
||||||
|
'background: #A0D7D1; color: black; display: block;'
|
||||||
|
);
|
||||||
|
console.groupEnd();
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
import { parseSentryDsn } from './parseSentryDsn';
|
||||||
|
|
||||||
|
describe('parseSentryDsn', () => {
|
||||||
|
it.each`
|
||||||
|
value | expected
|
||||||
|
${''} | ${{ status: 'missing' }}
|
||||||
|
${null} | ${{ status: 'missing' }}
|
||||||
|
${undefined} | ${{ status: 'missing' }}
|
||||||
|
${0} | ${{ status: 'invalid', value: 0 }}
|
||||||
|
${1} | ${{ status: 'invalid', value: 1 }}
|
||||||
|
${{}} | ${{ status: 'invalid', value: {} }}
|
||||||
|
${[]} | ${{ status: 'invalid', value: [] }}
|
||||||
|
${true} | ${{ status: 'invalid', value: true }}
|
||||||
|
${false} | ${{ status: 'invalid', value: false }}
|
||||||
|
${'https://sentry.io'} | ${{ status: 'invalid', value: 'https://sentry.io' }}
|
||||||
|
${'https://ingest.sentry.io'} | ${{ status: 'invalid', value: 'https://ingest.sentry.io' }}
|
||||||
|
${'https://ingest.sentry.io'} | ${{ status: 'invalid', value: 'https://ingest.sentry.io' }}
|
||||||
|
${'https://foo.ingest.sentry.io'} | ${{ status: 'invalid', value: 'https://foo.ingest.sentry.io' }}
|
||||||
|
${'https://foo.ingest.sentry.io/'} | ${{ status: 'invalid', value: 'https://foo.ingest.sentry.io/' }}
|
||||||
|
${'https://.ingest.sentry.io/bar'} | ${{ status: 'invalid', value: 'https://.ingest.sentry.io/bar' }}
|
||||||
|
${'http://foo.ingest.sentry.io/bar'} | ${{ status: 'invalid', value: 'http://foo.ingest.sentry.io/bar' }}
|
||||||
|
${'https://foo.ingest.sentry.io/bar'} | ${{ status: 'valid', value: 'https://foo.ingest.sentry.io/bar' }}
|
||||||
|
`(
|
||||||
|
`When invoked with '$value', then should return '$expected'`,
|
||||||
|
({ value, expected }) => {
|
||||||
|
expect(parseSentryDsn(value)).toEqual(expected);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
@ -0,0 +1,38 @@
|
|||||||
|
import type { SentryDsn } from '../types';
|
||||||
|
|
||||||
|
type ParseSentryDsnResult =
|
||||||
|
| { status: 'missing' }
|
||||||
|
| { status: 'invalid'; value: unknown }
|
||||||
|
| { status: 'valid'; value: SentryDsn };
|
||||||
|
|
||||||
|
export function parseSentryDsn(value: unknown): ParseSentryDsnResult {
|
||||||
|
if (value === '' || value === undefined || value === null) {
|
||||||
|
return { status: 'missing' };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value !== 'string') {
|
||||||
|
return { status: 'invalid', value };
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isSentryDsn(value)) {
|
||||||
|
return { status: 'invalid', value };
|
||||||
|
}
|
||||||
|
|
||||||
|
return { status: 'valid', value };
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSentryDsn(url: unknown): url is SentryDsn {
|
||||||
|
if (typeof url !== 'string') return false;
|
||||||
|
|
||||||
|
if (!url.startsWith('https://')) return false;
|
||||||
|
|
||||||
|
if (!url.includes('.ingest.sentry.io/')) return false;
|
||||||
|
|
||||||
|
const missSentryProjectId = url.endsWith('.ingest.sentry.io/');
|
||||||
|
if (missSentryProjectId) return false;
|
||||||
|
|
||||||
|
const missSentryPublicKey = url.includes('https://.ingest.sentry.io');
|
||||||
|
if (missSentryPublicKey) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
import type { EnvVars } from '@/Globals';
|
||||||
|
|
||||||
|
import * as Sentry from '@sentry/react';
|
||||||
|
import { BrowserTracing } from '@sentry/tracing';
|
||||||
|
|
||||||
|
import globals from '@/Globals';
|
||||||
|
import { getSentryTags } from './getSentryTags';
|
||||||
|
import { getSentryEnvironment } from './getSentryEnvironment';
|
||||||
|
import { isSentryAlreadyStarted } from './isSentryAlreadyStarted';
|
||||||
|
import { logSentryEnabled, logSentryDisabled } from './logSentryInfo';
|
||||||
|
|
||||||
|
type Globals = typeof globals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start Sentry idempotently.
|
||||||
|
*
|
||||||
|
* Please note that Sentry automatically tracks also the React errors, there is no need to manually track them
|
||||||
|
* from the various React error boundaries.
|
||||||
|
*
|
||||||
|
* ATTENTION: This function expects the `window.__envVars` because I think
|
||||||
|
* using the server-driven vars instead of the client-parsed ones (since they could
|
||||||
|
* differ in some details) as tags would be better.
|
||||||
|
*/
|
||||||
|
export function startTracing(globalVars: Globals, envVars: EnvVars) {
|
||||||
|
if (isSentryAlreadyStarted()) return 'enabled';
|
||||||
|
|
||||||
|
const consoleSentryDsn = globalVars.consoleSentryDsn;
|
||||||
|
if (
|
||||||
|
consoleSentryDsn.status === 'missing' ||
|
||||||
|
consoleSentryDsn.status === 'invalid'
|
||||||
|
) {
|
||||||
|
logSentryDisabled();
|
||||||
|
return 'disabled';
|
||||||
|
}
|
||||||
|
|
||||||
|
const tags = getSentryTags(envVars);
|
||||||
|
const environment = getSentryEnvironment(window.location.hostname);
|
||||||
|
|
||||||
|
logSentryEnabled(environment);
|
||||||
|
|
||||||
|
Sentry.init({
|
||||||
|
dsn: consoleSentryDsn.value,
|
||||||
|
tracesSampleRate: 1.0,
|
||||||
|
integrations: [
|
||||||
|
new BrowserTracing(),
|
||||||
|
|
||||||
|
new Sentry.Integrations.Breadcrumbs({
|
||||||
|
// Disable tracking console.logs
|
||||||
|
console: false,
|
||||||
|
|
||||||
|
// Disable tracking clicks
|
||||||
|
dom: false,
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
|
||||||
|
// Allow grouping logs by environment
|
||||||
|
environment,
|
||||||
|
release: tags.serverVersion,
|
||||||
|
initialScope: {
|
||||||
|
tags,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Sentry.setUser({
|
||||||
|
id: globalVars.userId,
|
||||||
|
ip_address: '{{auto}}',
|
||||||
|
});
|
||||||
|
|
||||||
|
return 'enabled';
|
||||||
|
}
|
1
console/src/features/TracingTools/sentry/index.ts
Normal file
1
console/src/features/TracingTools/sentry/index.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export { sentry } from './sentry';
|
10
console/src/features/TracingTools/sentry/sentry.ts
Normal file
10
console/src/features/TracingTools/sentry/sentry.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { startTracing } from './core/startTracing';
|
||||||
|
import { parseSentryDsn } from './core/parseSentryDsn';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A sentry object that attempts to mirror the actual sentry API.
|
||||||
|
*/
|
||||||
|
export const sentry = {
|
||||||
|
startTracing,
|
||||||
|
parseSentryDsn,
|
||||||
|
};
|
6
console/src/features/TracingTools/sentry/types.ts
Normal file
6
console/src/features/TracingTools/sentry/types.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
type SentryPublicKey = string;
|
||||||
|
type SentryProjectId = string;
|
||||||
|
|
||||||
|
// see https://docs.sentry.io/product/sentry-basics/dsn-explainer/
|
||||||
|
export type SentryDsn =
|
||||||
|
`https://${SentryPublicKey}.ingest.sentry.io/${SentryProjectId}`;
|
@ -16,6 +16,7 @@ const serverEnvVars = `
|
|||||||
projectID: '${process.env.HASURA_CLOUD_PROJECT_ID || ''}',
|
projectID: '${process.env.HASURA_CLOUD_PROJECT_ID || ''}',
|
||||||
cloudRootDomain: '${process.env.HASURA_CLOUD_ROOT_DOMAIN}',
|
cloudRootDomain: '${process.env.HASURA_CLOUD_ROOT_DOMAIN}',
|
||||||
consoleType: '${process.env.HASURA_CONSOLE_TYPE}',
|
consoleType: '${process.env.HASURA_CONSOLE_TYPE}',
|
||||||
|
consoleSentryDsn: '${process.env.HASURA_CONSOLE_SENTRY_DSN}'
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const cliEnvVars = `
|
const cliEnvVars = `
|
||||||
@ -33,7 +34,8 @@ const cliEnvVars = `
|
|||||||
herokuOAuthClientId: '${process.env.HEROKU_OAUTH_CLIENT_ID || ''}',
|
herokuOAuthClientId: '${process.env.HEROKU_OAUTH_CLIENT_ID || ''}',
|
||||||
tenantID: '${process.env.HASURA_CLOUD_TENANT_ID || ''}',
|
tenantID: '${process.env.HASURA_CLOUD_TENANT_ID || ''}',
|
||||||
projectID: '${process.env.HASURA_CLOUD_PROJECT_ID || ''}',
|
projectID: '${process.env.HASURA_CLOUD_PROJECT_ID || ''}',
|
||||||
cloudRootDomain: '${process.env.HASURA_CLOUD_ROOT_DOMAIN}'
|
cloudRootDomain: '${process.env.HASURA_CLOUD_ROOT_DOMAIN}',
|
||||||
|
consoleSentryDsn: '${process.env.HASURA_CONSOLE_SENTRY_DSN}'
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const envVars = process.env.CONSOLE_MODE === 'cli' ? cliEnvVars : serverEnvVars;
|
const envVars = process.env.CONSOLE_MODE === 'cli' ? cliEnvVars : serverEnvVars;
|
||||||
|
@ -1207,7 +1207,8 @@ mkConsoleHTML path authMode enableTelemetry consoleAssetsDir =
|
|||||||
"enableTelemetry" A..= boolToText enableTelemetry,
|
"enableTelemetry" A..= boolToText enableTelemetry,
|
||||||
"cdnAssets" A..= boolToText (isNothing consoleAssetsDir),
|
"cdnAssets" A..= boolToText (isNothing consoleAssetsDir),
|
||||||
"assetsVersion" A..= consoleAssetsVersion,
|
"assetsVersion" A..= consoleAssetsVersion,
|
||||||
"serverVersion" A..= currentVersion
|
"serverVersion" A..= currentVersion,
|
||||||
|
"consoleSentryDsn" A..= ("" :: Text)
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
consolePath = case path of
|
consolePath = case path of
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
cdnAssets: {{cdnAssets}},
|
cdnAssets: {{cdnAssets}},
|
||||||
serverVersion: "{{serverVersion}}",
|
serverVersion: "{{serverVersion}}",
|
||||||
consoleType: "oss",
|
consoleType: "oss",
|
||||||
|
consoleSentryDsn: "{{consoleSentryDsn}}"
|
||||||
};
|
};
|
||||||
window.__env.versionedAssetsPath = window.__env.assetsPath;
|
window.__env.versionedAssetsPath = window.__env.assetsPath;
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
Reference in New Issue
Block a user