Skip to content

Commit ba4553d

Browse files
dconeybechuanr
authored and
chuanr
committed
Firestore: Improve debug logging of GrpcConnection and WebChannelConnection (#7076)
1 parent f7cac56 commit ba4553d

File tree

5 files changed

+189
-38
lines changed

5 files changed

+189
-38
lines changed

.changeset/blue-eels-warn.md

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
'@firebase/firestore': patch
3+
'firebase': patch
4+
---
5+
6+
Improved debug logging of networking abstractions

packages/firestore/src/platform/browser/webchannel_connection.ts

+66-20
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ import {
4141
} from '../../remote/rpc_error';
4242
import { StreamBridge } from '../../remote/stream_bridge';
4343
import { fail, hardAssert } from '../../util/assert';
44+
import { generateUniqueDebugId } from '../../util/debug_uid';
4445
import { Code, FirestoreError } from '../../util/error';
4546
import { logDebug, logWarn } from '../../util/log';
4647
import { Rejecter, Resolver } from '../../util/promise';
4748
import { StringMap } from '../../util/types';
4849

49-
const LOG_TAG = 'Connection';
50+
const LOG_TAG = 'WebChannelConnection';
5051

5152
const RPC_STREAM_SERVICE = 'google.firestore.v1.Firestore';
5253

@@ -70,6 +71,7 @@ export class WebChannelConnection extends RestConnection {
7071
headers: StringMap,
7172
body: Req
7273
): Promise<Resp> {
74+
const streamId = generateUniqueDebugId();
7375
return new Promise((resolve: Resolver<Resp>, reject: Rejecter) => {
7476
const xhr = new XhrIo();
7577
xhr.setWithCredentials(true);
@@ -78,11 +80,15 @@ export class WebChannelConnection extends RestConnection {
7880
switch (xhr.getLastErrorCode()) {
7981
case ErrorCode.NO_ERROR:
8082
const json = xhr.getResponseJson() as Resp;
81-
logDebug(LOG_TAG, 'XHR received:', JSON.stringify(json));
83+
logDebug(
84+
LOG_TAG,
85+
`XHR for RPC '${rpcName}' ${streamId} received:`,
86+
JSON.stringify(json)
87+
);
8288
resolve(json);
8389
break;
8490
case ErrorCode.TIMEOUT:
85-
logDebug(LOG_TAG, 'RPC "' + rpcName + '" timed out');
91+
logDebug(LOG_TAG, `RPC '${rpcName}' ${streamId} timed out`);
8692
reject(
8793
new FirestoreError(Code.DEADLINE_EXCEEDED, 'Request time out')
8894
);
@@ -91,7 +97,7 @@ export class WebChannelConnection extends RestConnection {
9197
const status = xhr.getStatus();
9298
logDebug(
9399
LOG_TAG,
94-
'RPC "' + rpcName + '" failed with status:',
100+
`RPC '${rpcName}' ${streamId} failed with status:`,
95101
status,
96102
'response text:',
97103
xhr.getResponseText()
@@ -134,22 +140,21 @@ export class WebChannelConnection extends RestConnection {
134140
break;
135141
default:
136142
fail(
137-
'RPC "' +
138-
rpcName +
139-
'" failed with unanticipated ' +
140-
'webchannel error ' +
143+
`RPC '${rpcName}' ${streamId} ` +
144+
'failed with unanticipated webchannel error: ' +
141145
xhr.getLastErrorCode() +
142146
': ' +
143147
xhr.getLastError() +
144148
', giving up.'
145149
);
146150
}
147151
} finally {
148-
logDebug(LOG_TAG, 'RPC "' + rpcName + '" completed.');
152+
logDebug(LOG_TAG, `RPC '${rpcName}' ${streamId} completed.`);
149153
}
150154
});
151155

152156
const requestString = JSON.stringify(body);
157+
logDebug(LOG_TAG, `RPC '${rpcName}' ${streamId} sending request:`, body);
153158
xhr.send(url, 'POST', requestString, headers, XHR_TIMEOUT_SECS);
154159
});
155160
}
@@ -159,6 +164,7 @@ export class WebChannelConnection extends RestConnection {
159164
authToken: Token | null,
160165
appCheckToken: Token | null
161166
): Stream<Req, Resp> {
167+
const streamId = generateUniqueDebugId();
162168
const urlParts = [
163169
this.baseUrl,
164170
'/',
@@ -217,7 +223,11 @@ export class WebChannelConnection extends RestConnection {
217223
request.encodeInitMessageHeaders = true;
218224

219225
const url = urlParts.join('');
220-
logDebug(LOG_TAG, 'Creating WebChannel: ' + url, request);
226+
logDebug(
227+
LOG_TAG,
228+
`Creating RPC '${rpcName}' stream ${streamId}: ${url}`,
229+
request
230+
);
221231
const channel = webchannelTransport.createWebChannel(url, request);
222232

223233
// WebChannel supports sending the first message with the handshake - saving
@@ -236,14 +246,26 @@ export class WebChannelConnection extends RestConnection {
236246
sendFn: (msg: Req) => {
237247
if (!closed) {
238248
if (!opened) {
239-
logDebug(LOG_TAG, 'Opening WebChannel transport.');
249+
logDebug(
250+
LOG_TAG,
251+
`Opening RPC '${rpcName}' stream ${streamId} transport.`
252+
);
240253
channel.open();
241254
opened = true;
242255
}
243-
logDebug(LOG_TAG, 'WebChannel sending:', msg);
256+
logDebug(
257+
LOG_TAG,
258+
`RPC '${rpcName}' stream ${streamId} sending:`,
259+
msg
260+
);
244261
channel.send(msg);
245262
} else {
246-
logDebug(LOG_TAG, 'Not sending because WebChannel is closed:', msg);
263+
logDebug(
264+
LOG_TAG,
265+
`Not sending because RPC '${rpcName}' stream ${streamId} ` +
266+
'is closed:',
267+
msg
268+
);
247269
}
248270
},
249271
closeFn: () => channel.close()
@@ -273,22 +295,32 @@ export class WebChannelConnection extends RestConnection {
273295

274296
unguardedEventListen(channel, WebChannel.EventType.OPEN, () => {
275297
if (!closed) {
276-
logDebug(LOG_TAG, 'WebChannel transport opened.');
298+
logDebug(
299+
LOG_TAG,
300+
`RPC '${rpcName}' stream ${streamId} transport opened.`
301+
);
277302
}
278303
});
279304

280305
unguardedEventListen(channel, WebChannel.EventType.CLOSE, () => {
281306
if (!closed) {
282307
closed = true;
283-
logDebug(LOG_TAG, 'WebChannel transport closed');
308+
logDebug(
309+
LOG_TAG,
310+
`RPC '${rpcName}' stream ${streamId} transport closed`
311+
);
284312
streamBridge.callOnClose();
285313
}
286314
});
287315

288316
unguardedEventListen<Error>(channel, WebChannel.EventType.ERROR, err => {
289317
if (!closed) {
290318
closed = true;
291-
logWarn(LOG_TAG, 'WebChannel transport errored:', err);
319+
logWarn(
320+
LOG_TAG,
321+
`RPC '${rpcName}' stream ${streamId} transport errored:`,
322+
err
323+
);
292324
streamBridge.callOnClose(
293325
new FirestoreError(
294326
Code.UNAVAILABLE,
@@ -322,7 +354,11 @@ export class WebChannelConnection extends RestConnection {
322354
msgDataOrError.error ||
323355
(msgDataOrError as WebChannelError[])[0]?.error;
324356
if (error) {
325-
logDebug(LOG_TAG, 'WebChannel received error:', error);
357+
logDebug(
358+
LOG_TAG,
359+
`RPC '${rpcName}' stream ${streamId} received error:`,
360+
error
361+
);
326362
// error.status will be a string like 'OK' or 'NOT_FOUND'.
327363
const status: string = error.status;
328364
let code = mapCodeFromRpcStatus(status);
@@ -340,7 +376,11 @@ export class WebChannelConnection extends RestConnection {
340376
streamBridge.callOnClose(new FirestoreError(code, message));
341377
channel.close();
342378
} else {
343-
logDebug(LOG_TAG, 'WebChannel received:', msgData);
379+
logDebug(
380+
LOG_TAG,
381+
`RPC '${rpcName}' stream ${streamId} received:`,
382+
msgData
383+
);
344384
streamBridge.callOnMessage(msgData);
345385
}
346386
}
@@ -349,9 +389,15 @@ export class WebChannelConnection extends RestConnection {
349389

350390
unguardedEventListen<StatEvent>(requestStats, Event.STAT_EVENT, event => {
351391
if (event.stat === Stat.PROXY) {
352-
logDebug(LOG_TAG, 'Detected buffering proxy');
392+
logDebug(
393+
LOG_TAG,
394+
`RPC '${rpcName}' stream ${streamId} detected buffering proxy`
395+
);
353396
} else if (event.stat === Stat.NOPROXY) {
354-
logDebug(LOG_TAG, 'Detected no buffering proxy');
397+
logDebug(
398+
LOG_TAG,
399+
`RPC '${rpcName}' stream ${streamId} detected no buffering proxy`
400+
);
355401
}
356402
});
357403

0 commit comments

Comments
 (0)