Skip to content

Commit 21c85ef

Browse files
vzaidmanfacebook-github-bot
authored andcommitted
batch debug logging for cdp messages (facebook#49726)
Summary: Pull Request resolved: facebook#49726 The `InspectorProxy` debug logging became incredibly spammy making it almost unuseful unless the output is manipulated so this commit batches all these cdp messages and only desplays how many were received in the span of 5s. If no messages are received, the throttle is not triggered. To get the actual CDP messages logged, we still log these to `Metro:InspectorProxyCDPMessages`. Changelog: [General][Internal] batch debug logging for cdp messages Reviewed By: robhogan Differential Revision: D70324724 fbshipit-source-id: a269302f52e18af6c4be651758c042596abdbad8
1 parent 42a7c62 commit 21c85ef

File tree

4 files changed

+123
-14
lines changed

4 files changed

+123
-14
lines changed

flow-typed/npm/debug_v2.x.x.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,18 @@
1111
// https://github.com/visionmedia/debug
1212
// https://www.npmjs.com/package/debug
1313

14+
interface DebugFN {
15+
(...args: Array<mixed>): void;
16+
enable(match: string): void;
17+
disable(): void;
18+
enabled: () => boolean;
19+
}
20+
1421
declare module 'debug' {
1522
declare module.exports: {
16-
(namespace: string): (...Array<mixed>) => void,
23+
(namespace: string): DebugFN,
1724
enable(match: string): void,
1825
disable(): void,
26+
enabled: () => boolean,
1927
};
2028
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict-local
8+
* @format
9+
* @oncall react_native
10+
*/
11+
12+
// $FlowFixMe[cannot-resolve-module] libdef missing in RN OSS
13+
import type {Timeout} from 'timers';
14+
15+
// $FlowFixMe[cannot-resolve-module] libdef missing in RN OSS
16+
import {setTimeout} from 'timers';
17+
import util from 'util';
18+
19+
const debug = require('debug')('Metro:InspectorProxy');
20+
const debugCDPMessages = require('debug')('Metro:InspectorProxyCDPMessages');
21+
22+
const CDP_MESSAGES_BATCH_DEBUGGING_THROTTLE_MS = 5000;
23+
24+
export type CDPMessageDestination =
25+
| 'DebuggerToProxy'
26+
| 'ProxyToDebugger'
27+
| 'DeviceToProxy'
28+
| 'ProxyToDevice';
29+
30+
function getCDPLogPrefix(destination: CDPMessageDestination): string {
31+
return util.format(
32+
'[(Debugger) %s (Proxy) %s (Device)]',
33+
destination === 'DebuggerToProxy'
34+
? '->'
35+
: destination === 'ProxyToDebugger'
36+
? '<-'
37+
: ' ',
38+
destination === 'ProxyToDevice'
39+
? '->'
40+
: destination === 'DeviceToProxy'
41+
? '<-'
42+
: ' ',
43+
);
44+
}
45+
46+
export default class CDPMessagesLogging {
47+
#cdpMessagesLoggingBatchingFn: {
48+
[CDPMessageDestination]: () => void,
49+
} = {
50+
DebuggerToProxy: () => {},
51+
ProxyToDebugger: () => {},
52+
DeviceToProxy: () => {},
53+
ProxyToDevice: () => {},
54+
};
55+
56+
constructor() {
57+
if (debug.enabled) {
58+
this.#initializeThrottledCDPMessageLogging();
59+
}
60+
}
61+
62+
#initializeThrottledCDPMessageLogging(): void {
63+
const batchingCounters: {[CDPMessageDestination]: number} = {
64+
DebuggerToProxy: 0,
65+
ProxyToDebugger: 0,
66+
DeviceToProxy: 0,
67+
ProxyToDevice: 0,
68+
};
69+
70+
Object.keys(batchingCounters).forEach(destination => {
71+
let timeout: Timeout | null = null;
72+
73+
this.#cdpMessagesLoggingBatchingFn[destination] = () => {
74+
if (timeout == null) {
75+
timeout = setTimeout<$ReadOnlyArray<CDPMessageDestination>>(() => {
76+
debug(
77+
'%s %s CDP messages received in the last %ss.',
78+
getCDPLogPrefix(destination),
79+
String(batchingCounters[destination]).padStart(5),
80+
CDP_MESSAGES_BATCH_DEBUGGING_THROTTLE_MS / 1000,
81+
);
82+
batchingCounters[destination] = 0;
83+
timeout = null;
84+
}, CDP_MESSAGES_BATCH_DEBUGGING_THROTTLE_MS).unref();
85+
}
86+
batchingCounters[destination]++;
87+
};
88+
});
89+
}
90+
91+
log(destination: CDPMessageDestination, message: string) {
92+
if (debugCDPMessages.enabled) {
93+
debugCDPMessages('%s message: %s', getCDPLogPrefix(destination), message);
94+
}
95+
if (debug.enabled) {
96+
this.#cdpMessagesLoggingBatchingFn[destination]();
97+
}
98+
}
99+
}

packages/dev-middleware/src/inspector-proxy/Device.js

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import type {
2727
TargetCapabilityFlags,
2828
} from './types';
2929

30+
import CDPMessagesLogging from './CDPMessagesLogging';
3031
import DeviceEventReporter from './DeviceEventReporter';
3132
import * as fs from 'fs';
3233
import invariant from 'invariant';
@@ -129,6 +130,8 @@ export default class Device {
129130
// A base HTTP(S) URL to the server, relative to this server.
130131
#serverRelativeBaseUrl: URL;
131132

133+
#cdpMessagesLogging: CDPMessagesLogging;
134+
132135
constructor(deviceOptions: DeviceOptions) {
133136
this.#dangerouslyConstruct(deviceOptions);
134137
}
@@ -145,6 +148,7 @@ export default class Device {
145148
deviceRelativeBaseUrl,
146149
isProfilingBuild,
147150
}: DeviceOptions) {
151+
this.#cdpMessagesLogging = new CDPMessagesLogging();
148152
this.#id = id;
149153
this.#name = name;
150154
this.#app = app;
@@ -173,14 +177,11 @@ export default class Device {
173177
if (parsedMessage.event === 'getPages') {
174178
// There's a 'getPages' message every second, so only show them if they change
175179
if (message !== this.#lastGetPagesMessage) {
176-
debug(
177-
'(Debugger) (Proxy) <- (Device), getPages ping has changed: ' +
178-
message,
179-
);
180+
debug('Device getPages ping has changed: %s', message);
180181
this.#lastGetPagesMessage = message;
181182
}
182183
} else {
183-
debug('(Debugger) (Proxy) <- (Device): ' + message);
184+
this.#cdpMessagesLogging.log('DeviceToProxy', message);
184185
}
185186
await this.#handleMessageFromDevice(parsedMessage);
186187
})
@@ -343,7 +344,7 @@ export default class Device {
343344
sendMessage: message => {
344345
try {
345346
const payload = JSON.stringify(message);
346-
debug('(Debugger) <- (Proxy) (Device): ' + payload);
347+
this.#cdpMessagesLogging.log('ProxyToDebugger', payload);
347348
socket.send(payload);
348349
} catch {}
349350
},
@@ -361,7 +362,7 @@ export default class Device {
361362
wrappedEvent: JSON.stringify(message),
362363
},
363364
});
364-
debug('(Debugger) -> (Proxy) (Device): ' + payload);
365+
this.#cdpMessagesLogging.log('DebuggerToProxy', payload);
365366
this.#deviceSocket.send(payload);
366367
} catch {}
367368
},
@@ -382,7 +383,7 @@ export default class Device {
382383

383384
// $FlowFixMe[incompatible-call]
384385
socket.on('message', (message: string) => {
385-
debug('(Debugger) -> (Proxy) (Device): ' + message);
386+
this.#cdpMessagesLogging.log('DebuggerToProxy', message);
386387
const debuggerRequest = JSON.parse(message);
387388
this.#deviceEventReporter?.logRequest(debuggerRequest, 'debugger', {
388389
pageId: this.#debuggerConnection?.pageId ?? null,
@@ -427,11 +428,12 @@ export default class Device {
427428
}
428429
});
429430

431+
const cdpMessagesLogging = this.#cdpMessagesLogging;
430432
// $FlowFixMe[method-unbinding]
431433
const sendFunc = socket.send;
432434
// $FlowFixMe[cannot-write]
433435
socket.send = function (message: string) {
434-
debug('(Debugger) <- (Proxy) (Device): ' + message);
436+
cdpMessagesLogging.log('ProxyToDebugger', message);
435437
return sendFunc.call(socket, message);
436438
};
437439
}
@@ -609,7 +611,7 @@ export default class Device {
609611
try {
610612
const messageToSend = JSON.stringify(message);
611613
if (message.event !== 'getPages') {
612-
debug('(Debugger) (Proxy) -> (Device): %s', messageToSend);
614+
this.#cdpMessagesLogging.log('ProxyToDevice', messageToSend);
613615
}
614616
this.#deviceSocket.send(messageToSend);
615617
} catch (error) {}

packages/dev-middleware/src/inspector-proxy/InspectorProxy.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -552,12 +552,12 @@ export default class InspectorProxy implements InspectorProxyQueries {
552552
const isIdle = this.#isIdle();
553553

554554
debug(
555-
"%s heartbeat ping-pong for app='%s' on device='%s' with idle='%s' took %dms",
556-
socketName,
555+
"[heartbeat ping-pong] [%s] %sms for app='%s' on device='%s' with idle='%s'",
556+
socketName.padStart(7).padEnd(8),
557+
String(roundtripDuration).padStart(5),
557558
debuggerSessionIDs.appId,
558559
debuggerSessionIDs.deviceName,
559560
isIdle ? 'true' : 'false',
560-
roundtripDuration,
561561
);
562562

563563
this.#eventReporter?.logEvent({

0 commit comments

Comments
 (0)