Skip to content

Commit

Permalink
[Devtools] add logs for profiler tab switch & settings change (#24966)
Browse files Browse the repository at this point in the history
* [devtools] add logs for profiler tab switch & settings change

* prettier

* remove unnecessary console.log

* better naming: logEvent -> loggerEvent

* use same object for event and metadata
  • Loading branch information
mondaychen committed Jul 25, 2022
1 parent b66936e commit 5f34b05
Show file tree
Hide file tree
Showing 8 changed files with 96 additions and 20 deletions.
28 changes: 24 additions & 4 deletions packages/react-devtools-shared/src/Logger.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import {enableLogger} from 'react-devtools-feature-flags';

export type LogEvent =
export type LoggerEvent =
| {|
+event_name: 'loaded-dev-tools',
|}
Expand All @@ -34,22 +34,42 @@ export type LogEvent =
|}
| {|
+event_name: 'select-element',
+metadata: {
+source: string,
},
|}
| {|
+event_name: 'inspect-element-button-clicked',
|}
| {|
+event_name: 'profiling-start',
+metadata: {
+current_tab: string,
},
|}
| {|
+event_name: 'profiler-tab-changed',
+metadata: {
+tabId: string,
},
|}
| {|
+event_name: 'settings-changed',
+metadata: {
+key: string,
+value: any,
...
},
|};

export type LogFunction = (LogEvent, ?Object) => void | Promise<void>;
export type LogFunction = LoggerEvent => void | Promise<void>;

let logFunctions: Array<LogFunction> = [];
export const logEvent: LogFunction =
enableLogger === true
? function logEvent(event: LogEvent, metadata: ?Object): void {
? function logEvent(event: LoggerEvent): void {
logFunctions.forEach(log => {
log(event, metadata);
log(event);
});
}
: function logEvent() {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,10 @@ export default function Element({data, index, style}: Props) {

const handleClick = ({metaKey}) => {
if (id !== null) {
logEvent({event_name: 'select-element'}, {source: 'click-element'});
logEvent({
event_name: 'select-element',
metadata: {source: 'click-element'},
});
dispatch({
type: 'SELECT_ELEMENT_BY_ID',
payload: metaKey ? null : id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,10 @@ function OwnerView({
} = useHighlightNativeElement();

const handleClick = useCallback(() => {
logEvent({event_name: 'select-element'}, {source: 'owner-view'});
logEvent({
event_name: 'select-element',
metadata: {source: 'owner-view'},
});
dispatch({
type: 'SELECT_ELEMENT_BY_ID',
payload: id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,10 @@ export default function Tree(props: Props) {
function handleStopInspectingNative(didSelectNode) {
if (didSelectNode && focusTargetRef.current !== null) {
focusTargetRef.current.focus();
logEvent({event_name: 'select-element'}, {source: 'inspector'});
logEvent({
event_name: 'select-element',
metadata: {source: 'inspector'},
});
}
}
bridge.addListener('stopInspectingNative', handleStopInspectingNative);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,10 +207,21 @@ function ProfilerContextController({children}: Props) {
const [selectedTabID, selectTab] = useLocalStorage<TabID>(
'React::DevTools::Profiler::defaultTab',
'flame-chart',
value => {
logEvent({
event_name: 'profiler-tab-changed',
metadata: {
tabId: value,
},
});
},
);

const startProfiling = useCallback(() => {
logEvent({event_name: 'profiling-start'}, {current_tab: selectedTabID});
logEvent({
event_name: 'profiling-start',
metadata: {current_tab: selectedTabID},
});
store.profilerStore.startProfiling();
}, [store, selectedTabID]);
const stopProfiling = useCallback(() => store.profilerStore.stopProfiling(), [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
} from 'react-devtools-shared/src/constants';
import {useLocalStorage} from '../hooks';
import {BridgeContext} from '../context';
import {logEvent} from 'react-devtools-shared/src/Logger';

import type {BrowserTheme} from '../DevTools';

Expand Down Expand Up @@ -68,6 +69,22 @@ type Context = {|
const SettingsContext = createContext<Context>(((null: any): Context));
SettingsContext.displayName = 'SettingsContext';

function useLocalStorageWithLog<T>(
key: string,
initialValue: T | (() => T),
): [T, (value: T | (() => T)) => void] {
return useLocalStorage<T>(key, initialValue, (v, k) => {
logEvent({
event_name: 'settings-changed',
metadata: {
source: 'localStorage setter',
key: k,
value: v,
},
});
});
}

type DocumentElements = Array<HTMLElement>;

type Props = {|
Expand All @@ -85,47 +102,56 @@ function SettingsContextController({
}: Props) {
const bridge = useContext(BridgeContext);

const [displayDensity, setDisplayDensity] = useLocalStorage<DisplayDensity>(
const [
displayDensity,
setDisplayDensity,
] = useLocalStorageWithLog<DisplayDensity>(
'React::DevTools::displayDensity',
'compact',
);
const [theme, setTheme] = useLocalStorage<Theme>(
const [theme, setTheme] = useLocalStorageWithLog<Theme>(
'React::DevTools::theme',
'auto',
);
const [
appendComponentStack,
setAppendComponentStack,
] = useLocalStorage<boolean>(LOCAL_STORAGE_SHOULD_PATCH_CONSOLE_KEY, true);
] = useLocalStorageWithLog<boolean>(
LOCAL_STORAGE_SHOULD_PATCH_CONSOLE_KEY,
true,
);
const [
breakOnConsoleErrors,
setBreakOnConsoleErrors,
] = useLocalStorage<boolean>(
] = useLocalStorageWithLog<boolean>(
LOCAL_STORAGE_SHOULD_BREAK_ON_CONSOLE_ERRORS,
false,
);
const [parseHookNames, setParseHookNames] = useLocalStorage<boolean>(
const [parseHookNames, setParseHookNames] = useLocalStorageWithLog<boolean>(
LOCAL_STORAGE_PARSE_HOOK_NAMES_KEY,
false,
);
const [
hideConsoleLogsInStrictMode,
sethideConsoleLogsInStrictMode,
] = useLocalStorage<boolean>(
] = useLocalStorageWithLog<boolean>(
LOCAL_STORAGE_HIDE_CONSOLE_LOGS_IN_STRICT_MODE,
false,
);
const [
showInlineWarningsAndErrors,
setShowInlineWarningsAndErrors,
] = useLocalStorage<boolean>(
] = useLocalStorageWithLog<boolean>(
LOCAL_STORAGE_SHOW_INLINE_WARNINGS_AND_ERRORS_KEY,
true,
);
const [
traceUpdatesEnabled,
setTraceUpdatesEnabled,
] = useLocalStorage<boolean>(LOCAL_STORAGE_TRACE_UPDATES_ENABLED_KEY, false);
] = useLocalStorageWithLog<boolean>(
LOCAL_STORAGE_TRACE_UPDATES_ENABLED_KEY,
false,
);

const documentElements = useMemo<DocumentElements>(() => {
const array: Array<HTMLElement> = [
Expand Down
5 changes: 5 additions & 0 deletions packages/react-devtools-shared/src/devtools/views/hooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ export function useIsOverflowing(
export function useLocalStorage<T>(
key: string,
initialValue: T | (() => T),
onValueSet?: (any, string) => void,
): [T, (value: T | (() => T)) => void] {
const getValueFromLocalStorage = useCallback(() => {
try {
Expand Down Expand Up @@ -173,6 +174,10 @@ export function useLocalStorage<T>(

// Notify listeners that this setting has changed.
window.dispatchEvent(new Event(key));

if (onValueSet != null) {
onValueSet(valueToStore, key);
}
} catch (error) {
console.log(error);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @flow strict-local
*/

import type {LogEvent} from 'react-devtools-shared/src/Logger';
import type {LoggerEvent} from 'react-devtools-shared/src/Logger';

import {registerEventLogger} from 'react-devtools-shared/src/Logger';
import {enableLogger} from 'react-devtools-feature-flags';
Expand All @@ -25,17 +25,22 @@ export function registerDevToolsEventLogger(
| LoggerContext
| ?(() => Promise<LoggerContext>),
): void {
async function logEvent(event: LogEvent, metadata: ?Object) {
async function logEvent(event: LoggerEvent) {
if (enableLogger) {
if (loggingIFrame != null) {
let metadata = null;
if (event.metadata != null) {
metadata = event.metadata;
delete event.metadata;
}
loggingIFrame.contentWindow.postMessage(
{
source: 'react-devtools-logging',
event: event,
context: {
surface,
version: process.env.DEVTOOLS_VERSION,
metadata: metadata != null ? JSON.stringify(metadata) : '',
metadata: metadata !== null ? JSON.stringify(metadata) : '',
...(fetchAdditionalContext != null
? await fetchAdditionalContext()
: {}),
Expand All @@ -56,7 +61,7 @@ export function registerDevToolsEventLogger(

loggingIFrame = iframe;
if (missedEvents.length > 0) {
missedEvents.forEach(logEvent);
missedEvents.forEach(event => logEvent(event));
missedEvents = [];
}
}
Expand Down

0 comments on commit 5f34b05

Please sign in to comment.