From 9abf6fa31cd7ff4c6e54de75950620e203c59ebf Mon Sep 17 00:00:00 2001 From: Ruslan Lesiutin Date: Tue, 17 Oct 2023 15:23:53 +0100 Subject: [PATCH] feat[react-devtools-extensions/logging]: initialize session id on the client for logging (#27517) This code is executed once React DevTools panels are mounted, basically when user opens browser's DevTools. Based on this fact, session in this case is defined by browser's DevTools session, while they are open. A session can involve debugging multiple React pages. `crypto.randomUUID` is used to generate random user id. Corresponding logger config changes - [D50267871](https://www.internalfb.com/diff/D50267871). --- .../src/registerDevToolsEventLogger.js | 50 +++++++++---------- 1 file changed, 23 insertions(+), 27 deletions(-) diff --git a/packages/react-devtools-shared/src/registerDevToolsEventLogger.js b/packages/react-devtools-shared/src/registerDevToolsEventLogger.js index 45b978b48b..7b47f6c7af 100644 --- a/packages/react-devtools-shared/src/registerDevToolsEventLogger.js +++ b/packages/react-devtools-shared/src/registerDevToolsEventLogger.js @@ -12,7 +12,8 @@ import type {LoggerEvent} from 'react-devtools-shared/src/Logger'; import {registerEventLogger} from 'react-devtools-shared/src/Logger'; import {enableLogger} from 'react-devtools-feature-flags'; -let loggingIFrame = null; +let currentLoggingIFrame = null; +let currentSessionId = null; let missedEvents: Array = []; type LoggerContext = { @@ -21,32 +22,27 @@ type LoggerContext = { export function registerDevToolsEventLogger( surface: string, - fetchAdditionalContext: ?() => - | LoggerContext - | ?(() => Promise), + fetchAdditionalContext?: + | (() => LoggerContext) + | (() => Promise), ): void { async function logEvent(event: LoggerEvent) { if (enableLogger) { - if (loggingIFrame != null) { - let metadata = null; - if (event.metadata != null) { - metadata = event.metadata; - // $FlowFixMe[cannot-write]: metadata is not writable and nullable - // $FlowFixMe[prop-missing] - delete event.metadata; - } - loggingIFrame.contentWindow.postMessage( + if (currentLoggingIFrame != null && currentSessionId != null) { + const {metadata, ...eventWithoutMetadata} = event; + const additionalContext: LoggerContext | {} = + fetchAdditionalContext != null ? await fetchAdditionalContext() : {}; + + currentLoggingIFrame?.contentWindow?.postMessage( { source: 'react-devtools-logging', - event: event, + event: eventWithoutMetadata, context: { + ...additionalContext, + metadata: metadata != null ? JSON.stringify(metadata) : '', + session_id: currentSessionId, surface, version: process.env.DEVTOOLS_VERSION, - metadata: metadata !== null ? JSON.stringify(metadata) : '', - ...(fetchAdditionalContext != null - ? // $FlowFixMe[not-an-object] - await fetchAdditionalContext() - : {}), }, }, '*', @@ -58,11 +54,8 @@ export function registerDevToolsEventLogger( } function handleLoggingIFrameLoaded(iframe: HTMLIFrameElement) { - if (loggingIFrame != null) { - return; - } + currentLoggingIFrame = iframe; - loggingIFrame = iframe; if (missedEvents.length > 0) { missedEvents.forEach(event => logEvent(event)); missedEvents = []; @@ -74,18 +67,21 @@ export function registerDevToolsEventLogger( if (enableLogger) { const loggingUrl = process.env.LOGGING_URL; const body = document.body; + if ( typeof loggingUrl === 'string' && loggingUrl.length > 0 && - body != null + body != null && + currentLoggingIFrame == null ) { registerEventLogger(logEvent); + currentSessionId = window.crypto.randomUUID(); const iframe = document.createElement('iframe'); + + iframe.onload = () => handleLoggingIFrameLoaded(iframe); iframe.src = loggingUrl; - iframe.onload = function (...args) { - handleLoggingIFrameLoaded(iframe); - }; + body.appendChild(iframe); } }