Skip to content

Commit 65dcd23

Browse files
pyphiliakim
andauthored
feat: add logs to pages (#1979)
Co-authored-by: kim <kim.phanhoang@epfl.ch>
1 parent 17ff722 commit 65dcd23

3 files changed

Lines changed: 46 additions & 20 deletions

File tree

src/services/item/plugins/page/WSDoc.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { captureException } from '@sentry/node';
12
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
23
// @ts-expect-error
34
import * as decoding from 'lib0/decoding';
@@ -15,6 +16,8 @@ import * as syncProtocol from 'y-protocols/sync';
1516
// @ts-expect-error
1617
import * as Y from 'yjs';
1718

19+
import { FastifyBaseLogger } from 'fastify';
20+
1821
import { MESSAGE_AWARENESS_CODE, MESSAGE_SYNC_CODE } from './constants';
1922
import { PageItemService } from './page.service';
2023

@@ -32,15 +35,22 @@ export class WSDoc extends Y.Doc {
3235
protected name: string;
3336
protected enableAwareness: boolean;
3437
protected pageItemService: PageItemService;
38+
protected logger: FastifyBaseLogger;
3539

36-
constructor(pageItemService: PageItemService, name: string, enableAwareness: boolean) {
40+
constructor(
41+
pageItemService: PageItemService,
42+
name: string,
43+
enableAwareness: boolean,
44+
logger: FastifyBaseLogger,
45+
) {
3746
super();
3847
this.name = name;
3948
this.conns = new Map();
4049
this.enableAwareness = enableAwareness;
4150
this.awareness = new awarenessProtocol.Awareness(this);
4251
this.awareness.setLocalState(null);
4352
this.pageItemService = pageItemService;
53+
this.logger = logger;
4454
}
4555

4656
protected broadcastUpdate(update: Uint8Array) {
@@ -57,6 +67,7 @@ export class WSDoc extends Y.Doc {
5767
* @param conn
5868
*/
5969
addConnection(conn: WebSocket) {
70+
this.logger.info('Page', this.name, ': add connection to reach', this.conns.size + 1);
6071
this.conns.set(conn, new Set());
6172
// listen and reply to events
6273
conn.on('message', (message: ArrayBuffer) => {
@@ -74,6 +85,7 @@ export class WSDoc extends Y.Doc {
7485
const messageType = decoding.readVarUint(decoder);
7586
switch (messageType) {
7687
case MESSAGE_SYNC_CODE:
88+
this.logger.debug(`Page ${this.name}: receive message`);
7789
encoding.writeVarUint(encoder, MESSAGE_SYNC_CODE);
7890
syncProtocol.readSyncMessage(decoder, encoder, this, conn);
7991

@@ -86,6 +98,7 @@ export class WSDoc extends Y.Doc {
8698
break;
8799
case MESSAGE_AWARENESS_CODE: {
88100
if (this.enableAwareness) {
101+
this.logger.debug(`Page ${this.name}: receive awareness`);
89102
awarenessProtocol.applyAwarenessUpdate(
90103
this.awareness,
91104
decoding.readVarUint8Array(decoder),
@@ -96,7 +109,9 @@ export class WSDoc extends Y.Doc {
96109
}
97110
}
98111
} catch (err) {
99-
console.error(err);
112+
this.logger.error(err);
113+
// send error to sentry
114+
captureException(err, { tags: { feature: 'page', pageId: this.name } });
100115
// close connection because receive message is unsupported
101116
this.closeConn(conn, 1003);
102117
}
@@ -117,7 +132,9 @@ export class WSDoc extends Y.Doc {
117132
err != null && this.closeConn(conn);
118133
});
119134
} catch (e) {
120-
console.error(e);
135+
this.logger.error(e);
136+
// send error to sentry
137+
captureException(e, { tags: { feature: 'page', pageId: this.name } });
121138
this.closeConn(conn);
122139
}
123140
}
@@ -127,7 +144,7 @@ export class WSDoc extends Y.Doc {
127144
* @param conn connection to close
128145
*/
129146
closeConn(conn: WebSocket, code = 1000, reason?: string) {
130-
console.debug('Page: close connection', code, reason);
147+
this.logger.info(`Page ${this.name}: close connection ${code} ${reason}`);
131148
if (this.conns.has(conn)) {
132149
const controlledIds: Set<number> = this.conns.get(conn)!;
133150
this.conns.delete(conn);

src/services/item/plugins/page/page.controller.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export const pageItemPlugin: FastifyPluginAsyncTypebox = async (fastify) => {
8181
},
8282
async (client, req) => {
8383
client.on('error', fastify.log.error);
84-
setupWSConnectionForRead(client, req.params.id, pageItemService);
84+
setupWSConnectionForRead(client, req.params.id, pageItemService, fastify.log);
8585
},
8686
);
8787

@@ -111,7 +111,7 @@ export const pageItemPlugin: FastifyPluginAsyncTypebox = async (fastify) => {
111111
},
112112
async (client, req) => {
113113
client.on('error', fastify.log.error);
114-
setupWSConnectionForWriters(client, req.params.id, pageItemService);
114+
setupWSConnectionForWriters(client, req.params.id, pageItemService, fastify.log);
115115
},
116116
);
117117
};

src/services/item/plugins/page/setupWSConnection.ts

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import * as syncProtocol from 'y-protocols/sync';
1717
// @ts-expect-error
1818
import * as Y from 'yjs';
1919

20+
import { FastifyBaseLogger } from 'fastify';
21+
2022
import { db } from '../../../../drizzle/db';
2123
import { WSDoc } from './WSDoc';
2224
import { MESSAGE_AWARENESS_CODE, MESSAGE_SYNC_CODE, PING_TIMEOUT } from './constants';
@@ -40,8 +42,8 @@ class WSSharedDoc extends WSDoc {
4042
return name + '_shared';
4143
}
4244

43-
constructor(pageItemService: PageItemService, name: string) {
44-
super(pageItemService, name, true);
45+
constructor(pageItemService: PageItemService, name: string, logger: FastifyBaseLogger) {
46+
super(pageItemService, name, true, logger);
4547

4648
const awarenessChangeHandler = (
4749
{
@@ -113,9 +115,9 @@ class WSSharedDoc extends WSDoc {
113115
this.pageItemService.storeUpdate(db, pageId, update);
114116
});
115117
} catch (e) {
116-
console.error('An error occured while binding the state:', e);
118+
this.logger.error(`Page ${pageId}: An error occured while binding the state: ${e}`);
117119
// send error to sentry
118-
captureException(e);
120+
captureException(e, { tags: { feature: 'page', pageId: this.name } });
119121

120122
this.conns.forEach((v, conn) => {
121123
// close connections for unexpected error
@@ -132,8 +134,8 @@ class WSSharedDoc extends WSDoc {
132134
class WSReadDoc extends WSDoc {
133135
private SYNC_ORIGIN = 'sync';
134136

135-
constructor(pageItemService: PageItemService, name: string) {
136-
super(pageItemService, name, false);
137+
constructor(pageItemService: PageItemService, name: string, logger: FastifyBaseLogger) {
138+
super(pageItemService, name, false, logger);
137139
this.bindState(name);
138140

139141
// send yjs doc updates to all connections
@@ -150,9 +152,9 @@ class WSReadDoc extends WSDoc {
150152
const persistedYdoc = await this.pageItemService.getById(db, pageId);
151153
Y.applyUpdate(this, Y.encodeStateAsUpdate(persistedYdoc), this.SYNC_ORIGIN);
152154
} catch (e) {
153-
console.error('An error occured while binding the state:', e);
155+
this.logger.error(`Page ${pageId}: An error occured while binding the state: ${e}`);
154156
// send error to sentry
155-
captureException(e);
157+
captureException(e, { tags: { feature: 'page', pageId: this.name } });
156158
this.conns.forEach((v, conn) => {
157159
// close connections for unexpected error
158160
this.closeConn(conn, 1011);
@@ -173,7 +175,7 @@ class WSReadDoc extends WSDoc {
173175
* @param conn websocket connection
174176
* @param doc yjs document
175177
*/
176-
function setupPingPong(conn: WebSocket, doc: WSDoc) {
178+
function setupPingPong(conn: WebSocket, doc: WSDoc, pageId: string, logger: FastifyBaseLogger) {
177179
// Check if connection is still alive
178180
let pongReceived = true;
179181
const pingInterval = setInterval(() => {
@@ -187,7 +189,7 @@ function setupPingPong(conn: WebSocket, doc: WSDoc) {
187189
try {
188190
conn.ping();
189191
} catch (e) {
190-
console.error(e);
192+
logger.error(`Page ${pageId}: ${e}`);
191193
doc.closeConn(conn);
192194
clearInterval(pingInterval);
193195
}
@@ -213,30 +215,34 @@ export const setupWSConnectionForWriters = (
213215
conn: WebSocket,
214216
pageId: string,
215217
pageItemService: PageItemService,
218+
logger: FastifyBaseLogger,
216219
) => {
217220
conn.binaryType = 'arraybuffer';
218221
// get doc, initialize if it does not exist yet
219222
const doc = map.setIfUndefined(docs, pageId, () => {
220-
const doc = new WSSharedDoc(pageItemService, pageId);
223+
logger.info(`Page ${pageId}: Initializing new doc`);
224+
const doc = new WSSharedDoc(pageItemService, pageId, logger);
221225

222226
docs.set(pageId, doc);
223227

224228
return doc;
225229
});
226230
doc.addConnection(conn);
227231

228-
setupPingPong(conn, doc);
232+
setupPingPong(conn, doc, pageId, logger);
229233

230234
// put the following in a variables in a block so the interval handlers don't keep in in
231235
// scope
232236
{
233237
// send sync step 1
238+
logger.info(`Page ${pageId}: send sync step 1 `);
234239
const encoder = encoding.createEncoder();
235240
encoding.writeVarUint(encoder, MESSAGE_SYNC_CODE);
236241
syncProtocol.writeSyncStep1(encoder, doc);
237242
doc.send(conn, encoding.toUint8Array(encoder));
238243

239244
// send init awareness
245+
logger.info(`Page ${pageId}: send init awareness`);
240246
const awarenessStates = doc.awareness.getStates();
241247
if (awarenessStates.size > 0) {
242248
const encoder = encoding.createEncoder();
@@ -259,23 +265,26 @@ export const setupWSConnectionForRead = (
259265
conn: WebSocket,
260266
pageId: string,
261267
pageItemService: PageItemService,
268+
logger: FastifyBaseLogger,
262269
) => {
263270
conn.binaryType = 'arraybuffer';
264271
// get doc, initialize if it does not exist yet
265272
const doc = map.setIfUndefined(readDocs, pageId, () => {
266-
const doc = new WSReadDoc(pageItemService, pageId);
273+
logger.info(`Page ${pageId}: Initializing new doc`);
274+
const doc = new WSReadDoc(pageItemService, pageId, logger);
267275
readDocs.set(pageId, doc);
268276

269277
return doc;
270278
});
271279
doc.addConnection(conn);
272280

273-
setupPingPong(conn, doc);
281+
setupPingPong(conn, doc, pageId, logger);
274282

275283
// put the following in a variables in a block so the interval handlers don't keep in in
276284
// scope
277285
{
278286
// send sync step 1
287+
logger.info(`Page ${pageId}: send sync step 1`);
279288
const encoder = encoding.createEncoder();
280289
encoding.writeVarUint(encoder, MESSAGE_SYNC_CODE);
281290
syncProtocol.writeSyncStep1(encoder, doc);

0 commit comments

Comments
 (0)