1
0
mirror of https://github.com/lensapp/lens.git synced 2025-05-20 05:10:56 +00:00

remove sentry

Signed-off-by: Jim Ehrismann <jehrismann@mirantis.com>
This commit is contained in:
Jim Ehrismann 2021-09-15 15:26:10 -04:00
parent 068c78d48d
commit f5d08b7557
10 changed files with 72 additions and 269 deletions

View File

@ -183,8 +183,6 @@
"@hapi/call": "^8.0.1", "@hapi/call": "^8.0.1",
"@hapi/subtext": "^7.0.3", "@hapi/subtext": "^7.0.3",
"@kubernetes/client-node": "^0.15.1", "@kubernetes/client-node": "^0.15.1",
"@sentry/electron": "^2.5.0",
"@sentry/integrations": "^6.10.0",
"abort-controller": "^3.0.0", "abort-controller": "^3.0.0",
"array-move": "^3.0.1", "array-move": "^3.0.1",
"auto-bind": "^4.0.0", "auto-bind": "^4.0.0",
@ -258,8 +256,6 @@
"@material-ui/icons": "^4.11.2", "@material-ui/icons": "^4.11.2",
"@material-ui/lab": "^4.0.0-alpha.60", "@material-ui/lab": "^4.0.0-alpha.60",
"@pmmmwh/react-refresh-webpack-plugin": "^0.4.3", "@pmmmwh/react-refresh-webpack-plugin": "^0.4.3",
"@sentry/react": "^6.8.0",
"@sentry/types": "^6.8.0",
"@testing-library/dom": "^8.2.0", "@testing-library/dom": "^8.2.0",
"@testing-library/jest-dom": "^5.14.1", "@testing-library/jest-dom": "^5.14.1",
"@testing-library/react": "^11.2.6", "@testing-library/react": "^11.2.6",

View File

@ -1,22 +0,0 @@
/**
* Copyright (c) 2021 OpenLens Authors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
export * from "./sentry";

View File

@ -1,76 +0,0 @@
/**
* Copyright (c) 2021 OpenLens Authors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import Transport from "winston-transport";
import { LEVEL } from "triple-beam";
import { Severity } from "@sentry/browser";
import * as Sentry from "@sentry/electron";
const SENTRY_LEVELS_MAP = {
silly: Severity.Debug,
verbose: Severity.Debug,
debug: Severity.Debug,
info: Severity.Info,
warn: Severity.Warning,
error: Severity.Error,
};
const WINSTON_CMP: Record<WinstonLevel, Set<WinstonLevel>> = {
silly: new Set(["silly", "verbose", "debug", "info", "warn", "error"]),
verbose: new Set(["verbose", "debug", "info", "warn", "error"]),
debug: new Set(["debug", "info", "warn", "error"]),
info: new Set(["info", "warn", "error"]),
warn: new Set(["warn", "error"]),
error: new Set(["error"]),
};
export type WinstonLevel = keyof typeof SENTRY_LEVELS_MAP;
export class SentryTransport extends Transport {
logLevels: Set<WinstonLevel>;
constructor(minWinstonLevel: WinstonLevel) {
super();
this.logLevels = WINSTON_CMP[minWinstonLevel];
}
log(info: any, next: () => void) {
setImmediate(() => {
this.emit("logged", info);
});
const { message, level: _, tags, user, ...extra } = info;
const winstonLevel: WinstonLevel = info[LEVEL];
const level = SENTRY_LEVELS_MAP[winstonLevel];
try {
if (this.logLevels.has(winstonLevel)) {
Sentry.captureMessage(message, {
level,
tags,
extra,
});
}
} finally {
next();
}
}
}

View File

@ -1,78 +0,0 @@
/**
* Copyright (c) 2021 OpenLens Authors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import { Dedupe, Offline } from "@sentry/integrations";
import * as Sentry from "@sentry/electron";
import { sentryDsn, isProduction } from "./vars";
import { UserStore } from "./user-store";
import { inspect } from "util";
/**
* "Translate" 'browser' to 'main' as Lens developer more familiar with the term 'main'
*/
function mapProcessName(processType: string) {
if (processType === "browser") {
return "main";
}
return processType;
}
/**
* Initialize Sentry for the current process so to send errors for debugging.
*/
export function SentryInit() {
const processName = mapProcessName(process.type);
Sentry.init({
beforeSend: (event) => {
// default to false, in case instance of UserStore is not created (yet)
const allowErrorReporting = UserStore.getInstance(false)?.allowErrorReporting ?? false;
if (allowErrorReporting) {
return event;
}
/**
* Directly write to stdout so that no other integrations capture this and create an infinite loop
*/
process.stdout.write(`🔒 [SENTRY-BEFORE-SEND-HOOK]: allowErrorReporting: ${allowErrorReporting}. Sentry event is caught but not sent to server.`);
process.stdout.write("🔒 [SENTRY-BEFORE-SEND-HOOK]: === START OF SENTRY EVENT ===");
process.stdout.write(inspect(event, false, null, true));
process.stdout.write("🔒 [SENTRY-BEFORE-SEND-HOOK]: === END OF SENTRY EVENT ===");
// if return null, the event won't be sent
// ref https://github.com/getsentry/sentry-javascript/issues/2039
return null;
},
dsn: sentryDsn,
integrations: [
new Dedupe(),
new Offline(),
],
initialScope: {
tags: {
"process": processName,
}
},
environment: isProduction ? "production" : "development",
});
}

View File

@ -74,5 +74,3 @@ export const supportUrl = "https://docs.k8slens.dev/latest/support/" as string;
export const appSemVer = new SemVer(packageInfo.version); export const appSemVer = new SemVer(packageInfo.version);
export const docsUrl = "https://docs.k8slens.dev/main/" as string; export const docsUrl = "https://docs.k8slens.dev/main/" as string;
export const sentryDsn = packageInfo.config?.sentryDsn ?? "";

View File

@ -58,7 +58,6 @@ import { UserStore } from "../common/user-store";
import { WeblinkStore } from "../common/weblink-store"; import { WeblinkStore } from "../common/weblink-store";
import { ExtensionsStore } from "../extensions/extensions-store"; import { ExtensionsStore } from "../extensions/extensions-store";
import { FilesystemProvisionerStore } from "./extension-filesystem"; import { FilesystemProvisionerStore } from "./extension-filesystem";
import { SentryInit } from "../common/sentry";
import { ensureDir } from "fs-extra"; import { ensureDir } from "fs-extra";
import { Router } from "./router"; import { Router } from "./router";
import { initMenu } from "./menu"; import { initMenu } from "./menu";
@ -71,7 +70,6 @@ const onQuitCleanup = disposer();
const workingDir = path.join(app.getPath("appData"), appName); const workingDir = path.join(app.getPath("appData"), appName);
SentryInit();
app.setName(appName); app.setName(appName);
logger.info(`📟 Setting ${productName} as protocol client for lens://`); logger.info(`📟 Setting ${productName} as protocol client for lens://`);

View File

@ -48,7 +48,6 @@ import { WeblinkStore } from "../common/weblink-store";
import { ExtensionsStore } from "../extensions/extensions-store"; import { ExtensionsStore } from "../extensions/extensions-store";
import { FilesystemProvisionerStore } from "../main/extension-filesystem"; import { FilesystemProvisionerStore } from "../main/extension-filesystem";
import { ThemeStore } from "./theme.store"; import { ThemeStore } from "./theme.store";
import { SentryInit } from "../common/sentry";
import { TerminalStore } from "./components/dock/terminal.store"; import { TerminalStore } from "./components/dock/terminal.store";
import cloudsMidnight from "./monaco-themes/Clouds Midnight.json"; import cloudsMidnight from "./monaco-themes/Clouds Midnight.json";
@ -92,8 +91,6 @@ export async function bootstrap(App: AppComponent) {
UserStore.createInstance(); UserStore.createInstance();
SentryInit();
// ClusterStore depends on: UserStore // ClusterStore depends on: UserStore
const cs = ClusterStore.createInstance(); const cs = ClusterStore.createInstance();

View File

@ -51,7 +51,6 @@ import { Editor } from "./editor";
import { LensProxy } from "./proxy"; import { LensProxy } from "./proxy";
import { Telemetry } from "./telemetry"; import { Telemetry } from "./telemetry";
import { Extensions } from "./extensions"; import { Extensions } from "./extensions";
import { sentryDsn } from "../../../common/vars";
@observer @observer
export class Preferences extends React.Component { export class Preferences extends React.Component {
@ -75,7 +74,7 @@ export class Preferences extends React.Component {
<Tab value={proxyURL()} label="Proxy" data-testid="proxy-tab" active={isActive(proxyRoute)}/> <Tab value={proxyURL()} label="Proxy" data-testid="proxy-tab" active={isActive(proxyRoute)}/>
<Tab value={kubernetesURL()} label="Kubernetes" data-testid="kubernetes-tab" active={isActive(kubernetesRoute)}/> <Tab value={kubernetesURL()} label="Kubernetes" data-testid="kubernetes-tab" active={isActive(kubernetesRoute)}/>
<Tab value={editorURL()} label="Editor" data-testid="editor-tab" active={isActive(editorRoute)}/> <Tab value={editorURL()} label="Editor" data-testid="editor-tab" active={isActive(editorRoute)}/>
{(telemetryExtensions.length > 0 || !!sentryDsn) && {telemetryExtensions.length > 0 &&
<Tab value={telemetryURL()} label="Telemetry" data-testid="telemetry-tab" active={isActive(telemetryRoute)}/> <Tab value={telemetryURL()} label="Telemetry" data-testid="telemetry-tab" active={isActive(telemetryRoute)}/>
} }
{extensions.filter(e => !e.showInPreferencesTab).length > 0 && {extensions.filter(e => !e.showInPreferencesTab).length > 0 &&

View File

@ -20,11 +20,7 @@
*/ */
import { observer } from "mobx-react"; import { observer } from "mobx-react";
import React from "react"; import React from "react";
import { UserStore } from "../../../common/user-store";
import { sentryDsn } from "../../../common/vars";
import { AppPreferenceRegistry } from "../../../extensions/registries"; import { AppPreferenceRegistry } from "../../../extensions/registries";
import { Checkbox } from "../checkbox";
import { SubTitle } from "../layout/sub-title";
import { ExtensionSettings } from "./preferences"; import { ExtensionSettings } from "./preferences";
export const Telemetry = observer(() => { export const Telemetry = observer(() => {
@ -35,29 +31,6 @@ export const Telemetry = observer(() => {
<section id="telemetry"> <section id="telemetry">
<h2 data-testid="telemetry-header">Telemetry</h2> <h2 data-testid="telemetry-header">Telemetry</h2>
{telemetryExtensions.map((extension) => <ExtensionSettings key={extension.id} {...extension}/>)} {telemetryExtensions.map((extension) => <ExtensionSettings key={extension.id} {...extension}/>)}
{sentryDsn ? (
<React.Fragment key='sentry'>
<section id='sentry' className="small">
<SubTitle title='Automatic Error Reporting' />
<Checkbox
label="Allow automatic error reporting"
value={UserStore.getInstance().allowErrorReporting}
onChange={value => {
UserStore.getInstance().allowErrorReporting = value;
}}
/>
<div className="hint">
<span>
Automatic error reports provide vital information about issues and application crashes.
It is highly recommended to keep this feature enabled to ensure fast turnaround for issues you might encounter.
</span>
</div>
</section>
<hr className="small" />
</React.Fragment>) :
// we don't need to shows the checkbox at all if Sentry dsn is not a valid url
null
}
</section> </section>
); );
}); });

View File

@ -19,56 +19,74 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/ */
import "./error-boundary.scss"; import React, { ErrorInfo } from "react";
import { reaction } from "mobx";
import { disposeOnUnmount, observer } from "mobx-react";
import { Button } from "../button";
import { navigation } from "../../navigation";
import { issuesTrackerUrl, slackUrl } from "../../../common/vars";
import React from "react"; interface Props {
import { Button } from "../button"; }
import { navigation } from "../../navigation";
import { issuesTrackerUrl, slackUrl } from "../../../common/vars";
import * as Sentry from "@sentry/react";
import { observer } from "mobx-react";
@observer interface State {
export class ErrorBoundary extends React.Component { error?: Error;
render() { errorInfo?: ErrorInfo;
return ( }
<Sentry.ErrorBoundary
fallback={({ error, componentStack, resetError }) => {
const slackLink = <a href={slackUrl} rel="noreferrer" target="_blank">Slack</a>;
const githubLink = <a href={issuesTrackerUrl} rel="noreferrer" target="_blank">GitHub</a>;
const pageUrl = location.pathname;
return ( @observer
<div className="flex ErrorBoundary column gaps"> export class ErrorBoundary extends React.Component<Props, State> {
<h5> public state: State = {};
App crash at <span className="contrast">{pageUrl}</span>
</h5> @disposeOnUnmount
<p> resetOnNavigate = reaction(
To help us improve the product please report bugs to {slackLink} community or {githubLink} issues tracker. () => navigation.toString(),
</p> () => this.setState({ error: null, errorInfo: null })
<div className="wrapper"> );
<code className="block">
<p className="contrast">Component stack:</p> componentDidCatch(error: Error, errorInfo: ErrorInfo) {
{componentStack} this.setState({ error, errorInfo });
</code> }
<code className="box grow">
<p className="contrast">Error stack:</p> <br/> back = () => {
{error.stack} navigation.goBack();
</code> };
</div>
<Button render() {
className="box self-flex-start" const { error, errorInfo } = this.state;
primary label="Back"
onClick={() => { if (error) {
resetError(); const slackLink = <a href={slackUrl} rel="noreferrer" target="_blank">Slack</a>;
navigation.goBack(); const githubLink = <a href={issuesTrackerUrl} rel="noreferrer" target="_blank">Github</a>;
}} const pageUrl = location.pathname;
/>
</div> return (
); <div className="ErrorBoundary flex column gaps">
}}> <h5>
{this.props.children} App crash at <span className="contrast">{pageUrl}</span>
</Sentry.ErrorBoundary> </h5>
); <p>
} To help us improve the product please report bugs to {slackLink} community or {githubLink} issues tracker.
} </p>
<div className="wrapper">
<code className="block">
<p className="contrast">Component stack:</p>
{errorInfo.componentStack}
</code>
<code className="box grow">
<p className="contrast">Error stack:</p> <br/>
{error.stack}
</code>
</div>
<Button
className="box self-flex-start"
primary label="Back"
onClick={this.back}
/>
</div>
);
}
return this.props.children;
}
}