Skip to content

Commit

Permalink
ref: Overhaul console integration (#525)
Browse files Browse the repository at this point in the history
Our console integration was designed to work on the same page with the
Spotlight UI. It was using a naive filtering method to avoid infinite
loops from Spotlight debug mode logger itself. Moreover, it was not
taking the `sidecarURL` option, was defaulting to `localhost:8969` as
the sidecar URL. This patch overhauls the two, leveraging the fact that
they are on the same page. This means switching to the local event-based
message passing between the UI and the console integration, removing the
need for `fetch` calls and passing around the sidecarURL option. It also
overhauls the Spotlight logger to always try to use an unmodified
console implementation, removing the need for hacky filtering on the
console integration side.

ref #521.
  • Loading branch information
BYK authored Sep 13, 2024
1 parent 42022e5 commit 149e95b
Show file tree
Hide file tree
Showing 9 changed files with 193 additions and 123 deletions.
5 changes: 5 additions & 0 deletions .changeset/proud-days-relate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@spotlightjs/overlay': patch
---

Overhaul console integration for more performance and stability
6 changes: 5 additions & 1 deletion demos/sveltekit/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import { defineConfig } from 'vitest/config';
import spotlight from '@spotlightjs/spotlight/vite-plugin';

export default defineConfig({
plugins: [sveltekit(), sentrySvelteKit({ autoUploadSourceMaps: false }), spotlight()],
plugins: [
sveltekit(),
sentrySvelteKit({ autoUploadSourceMaps: false }),
spotlight({ integrationNames: ['sentry', 'console'], debug: true })
],
test: {
include: ['src/**/*.{test,spec}.{js,ts}']
}
Expand Down
30 changes: 15 additions & 15 deletions packages/overlay/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,42 +27,42 @@
"require": "./dist/sentry-spotlight.umd.cjs"
}
},
"dependencies": {},
"devDependencies": {
"@fontsource/raleway": "^5.0.8",
"@sentry/types": "^8.0.0-alpha.7",
"@sentry/utils": "^8.0.0-alpha.7",
"@spotlightjs/tsconfig": "workspace:*",
"@spotlightjs/sidecar": "workspace:*",
"@spotlightjs/tsconfig": "workspace:*",
"@types/beautify": "^0.0.3",
"@types/react": "^18.2.37",
"@types/react-dom": "^18.2.15",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"@vitejs/plugin-react": "^4.0.3",
"@vitest/coverage-v8": "^0.34.6",
"autoprefixer": "^10.4.15",
"beautify": "^0.0.8",
"dayjs": "^1.11.9",
"eslint": "^8.45.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"typescript": "^5.0.2",
"vite": "^4.5.3",
"vite-plugin-dts": "^3.5.2",
"vite-plugin-svgr": "^3.2.0",
"vitest": "^0.34.6",
"@fontsource/raleway": "^5.0.8",
"autoprefixer": "^10.4.15",
"dayjs": "^1.11.9",
"happy-dom": "^15.7.4",
"magic-string": "^0.30.5",
"platformicons": "^5.8.3",
"postcss": "^8.4.28",
"react": "^18.2.0",
"react-diff-viewer-continued": "^3.4.0",
"react-dom": "^18.2.0",
"react-json-view": "^1.21.3",
"react-router-dom": "^6.18.0",
"sql-formatter": "^12.2.4",
"tailwindcss": "^3.3.3",
"typescript": "^5.0.2",
"usehooks-ts": "^2.9.1",
"magic-string": "^0.30.5",
"beautify": "^0.0.8",
"react-diff-viewer-continued": "^3.4.0",
"@types/beautify": "^0.0.3",
"react-json-view": "^1.21.3"
"vite": "^4.5.3",
"vite-plugin-dts": "^3.5.2",
"vite-plugin-svgr": "^3.2.0",
"vitest": "^0.34.6"
},
"volta": {
"extends": "../../package.json"
Expand Down
61 changes: 34 additions & 27 deletions packages/overlay/src/integrations/console/index.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,24 @@
import { trigger } from '../../lib/eventTarget';
import type { WindowWithSpotlight } from '../../types';
import type { Integration } from '../integration';
import ConsoleTab from './console-tab';
import { ConsoleMessage, Level } from './types';
import type { ConsoleMessage, Level } from './types';

const HEADER = 'application/x-spotlight-console';
const PORT = 8969;
const CONTENT_TYPE = 'application/x-spotlight-console';

/**
* This integration is meant to run on the same page where
* the Spotlight UI is running. For standalone UI cases such
* as the Electron app, we should publish a separate version
* that takes in the sidecar URL.
* @returns Integration Console integration for Spotlight
*/
export default function consoleIntegration() {
const pageloadId = window.crypto.randomUUID();

return {
name: 'console',
forwardedContentType: [HEADER],
forwardedContentType: [CONTENT_TYPE],
tabs: ({ processedEvents }) => [
{
id: 'console',
Expand All @@ -37,34 +45,33 @@ export default function consoleIntegration() {
}

function instrumentConsole(level: Level, pageloadId: string) {
const originalConsoleLog = window.console[level];
const windowWithSpotlight = window as WindowWithSpotlight;
if (!windowWithSpotlight.__spotlight) {
windowWithSpotlight.__spotlight = {};
}
if (!windowWithSpotlight.__spotlight.console) {
windowWithSpotlight.__spotlight.console = {};
}
const originalConsole = windowWithSpotlight.__spotlight.console;
if (!originalConsole[level]) {
originalConsole[level] = window.console[level];
}
const originalConsoleMethod = originalConsole[level];

window.console[level] = (...args: unknown[]) => {
const serializedArgs = argsToString(args);
// Super dumb way to avoid endless loops (we're gonna regret that)
if (serializedArgs.find(a => a.toLowerCase().includes('spotlight'))) {
return originalConsoleLog(...args);
}

try {
void fetch(`http://localhost:${PORT}/stream`, {
method: 'POST',
body: JSON.stringify({
type: level,
args: serializedArgs,
msg: serializedArgs.join(' '),
sessionId: pageloadId,
} satisfies ConsoleMessage),
headers: {
'Content-Type': HEADER,
},
mode: 'cors',
}).catch(() => {});
} catch {
// ignore failed fetch requests
}
trigger('event', {
contentType: CONTENT_TYPE,
data: JSON.stringify({
type: level,
args: serializedArgs,
msg: serializedArgs.join(' '),
sessionId: pageloadId,
} satisfies ConsoleMessage),
});

return originalConsoleLog(...args);
return originalConsoleMethod.call(window, ...args);
};
}

Expand Down
40 changes: 31 additions & 9 deletions packages/overlay/src/lib/logger.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,43 @@
let loggerActive = false;
import type { WindowWithSpotlight } from '../types';

export const SPOTLIGHT_PREFIX = '🔎 [Spotlight]';

const windowWithSpotlight = window as WindowWithSpotlight;
if (!windowWithSpotlight.__spotlight) {
windowWithSpotlight.__spotlight = {};
}
if (!windowWithSpotlight.__spotlight.console) {
windowWithSpotlight.__spotlight.console = {};
}

if (!windowWithSpotlight.__spotlight.console.log) {
windowWithSpotlight.__spotlight.console.log = window.console.log;
}

if (!windowWithSpotlight.__spotlight.console.warn) {
windowWithSpotlight.__spotlight.console.warn = window.console.warn;
}

const original = windowWithSpotlight.__spotlight.console;

const noop = (..._args: unknown[]) => {}; // eslint-disable-line @typescript-eslint/no-unused-vars
let _log = noop;
let _warn = noop;

export function activateLogger() {
loggerActive = true;
_log = (...args: unknown[]) => original.log.call(window, SPOTLIGHT_PREFIX, ...args);
_warn = (...args: unknown[]) => original.warn.call(window, SPOTLIGHT_PREFIX, ...args);
}

export function deactivateLogger() {
loggerActive = false;
_log = noop;
_warn = noop;
}

export function log(...args: unknown[]) {
if (loggerActive) {
console.log('🔎 [Spotlight]', ...args);
}
_log(...args);
}

export function warn(...args: unknown[]) {
if (loggerActive) {
console.warn('🔎 [Spotlight]', ...args);
}
_warn(...args);
}
1 change: 1 addition & 0 deletions packages/overlay/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,5 +123,6 @@ export type WindowWithSpotlight = Window & {
__spotlight?: {
eventTarget?: EventTarget;
initOptions?: SpotlightOverlayOptions;
console?: Record<string, (...args: unknown[]) => void>;
};
};
4 changes: 3 additions & 1 deletion packages/overlay/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ export default defineConfig({
},
rollupOptions: {
treeshake: 'smallest',
output: { footer: 'window.Spotlight && Spotlight.init()' },
output: {
footer: '(function(S){S && S.init({integrations: [S.sentry(), S.console()]})}(window.Spotlight))',
},
},
sourcemap: true,
},
Expand Down
1 change: 1 addition & 0 deletions packages/overlay/vitest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { defineConfig } from 'vitest/config';
export default defineConfig({
// plugins: [tsconfigPaths()],
test: {
environment: 'happy-dom',
coverage: {
provider: 'v8',
reporter: ['json'],
Expand Down
Loading

0 comments on commit 149e95b

Please sign in to comment.