Skip to content

Commit d5f3e74

Browse files
committed
Enable request debugging on example-node.
1 parent 80a40f3 commit d5f3e74

File tree

2 files changed

+159
-1
lines changed

2 files changed

+159
-1
lines changed
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
import * as diagnostics_channel from 'node:diagnostics_channel';
2+
import type { DiagnosticsChannel } from 'undici';
3+
4+
/**
5+
* Enable Undici diagnostics channel instrumentation for detailed connection and request logging.
6+
*
7+
* This includes fetch requests and websocket connections.
8+
*
9+
* Usage: enableUncidiDiagnostics();
10+
*/
11+
export function enableUncidiDiagnostics() {
12+
new UndiciDiagnostics().enable();
13+
}
14+
15+
class UndiciDiagnostics {
16+
private requestCounter: number = 0;
17+
private activeRequests: WeakMap<any, number> = new WeakMap();
18+
19+
enable() {
20+
// Available events are documented here:
21+
// https://github.com/nodejs/undici/blob/main/docs/docs/api/DiagnosticsChannel.md
22+
23+
diagnostics_channel.subscribe('undici:request:create', (message: DiagnosticsChannel.RequestCreateMessage) => {
24+
const requestId = ++this.requestCounter;
25+
const request = message.request;
26+
this.activeRequests.set(message.request, requestId);
27+
28+
console.log(`🔄 [DIAG-${requestId}] REQUEST CREATE:`, {
29+
host: request.origin,
30+
path: request.path,
31+
method: request.method,
32+
headers: formatHeaders(request.headers),
33+
contentType: (request as any).contentType,
34+
contentLength: (request as any).contentLength
35+
});
36+
});
37+
38+
diagnostics_channel.subscribe('undici:request:bodySent', (message: DiagnosticsChannel.RequestBodySentMessage) => {
39+
const requestId = this.activeRequests.get(message.request);
40+
console.log(`📤 [DIAG-${requestId}] REQUEST BODY SENT`);
41+
});
42+
43+
diagnostics_channel.subscribe('undici:request:headers', (message: DiagnosticsChannel.RequestHeadersMessage) => {
44+
const requestId = this.activeRequests.get(message.request);
45+
console.log(`📥 [DIAG-${requestId}] RESPONSE HEADERS:`, {
46+
statusCode: message.response.statusCode,
47+
statusText: message.response.statusText,
48+
headers: formatHeaders(message.response.headers)
49+
});
50+
});
51+
52+
diagnostics_channel.subscribe('undici:request:trailers', (message: DiagnosticsChannel.RequestTrailersMessage) => {
53+
const requestId = this.activeRequests.get(message.request);
54+
console.log(`🏁 [DIAG-${requestId}] REQUEST TRAILERS:`, {
55+
trailers: message.trailers
56+
});
57+
});
58+
59+
diagnostics_channel.subscribe('undici:request:error', (message: DiagnosticsChannel.RequestErrorMessage) => {
60+
const requestId = this.activeRequests.get(message.request);
61+
console.log(`❌ [DIAG-${requestId}] REQUEST ERROR:`, {
62+
error: message.error
63+
});
64+
65+
// Clean up tracking
66+
this.activeRequests.delete(message.request);
67+
});
68+
69+
// Client connection events
70+
diagnostics_channel.subscribe(
71+
'undici:client:sendHeaders',
72+
(message: DiagnosticsChannel.ClientSendHeadersMessage) => {
73+
console.log(`📡 [DIAG] CLIENT SEND HEADERS:`, {
74+
headers: formatHeaders(message.headers)
75+
});
76+
}
77+
);
78+
79+
diagnostics_channel.subscribe(
80+
'undici:client:beforeConnect',
81+
(message: DiagnosticsChannel.ClientBeforeConnectMessage) => {
82+
console.log(`🔌 [DIAG] CLIENT BEFORE CONNECT:`, {
83+
connectParams: message.connectParams
84+
});
85+
}
86+
);
87+
88+
diagnostics_channel.subscribe('undici:client:connected', (message: DiagnosticsChannel.ClientConnectedMessage) => {
89+
console.log(`✅ [DIAG] CLIENT CONNECTED:`, {
90+
connectParams: message.connectParams,
91+
connector: message.connector?.name,
92+
socket: {
93+
localAddress: message.socket?.localAddress,
94+
localPort: message.socket?.localPort,
95+
remoteAddress: message.socket?.remoteAddress,
96+
remotePort: message.socket?.remotePort
97+
}
98+
});
99+
});
100+
101+
diagnostics_channel.subscribe(
102+
'undici:client:connectError',
103+
(message: DiagnosticsChannel.ClientConnectErrorMessage) => {
104+
console.log(`❌ [DIAG] CLIENT CONNECT ERROR:`, {
105+
connectParams: message.connectParams,
106+
error: message.error
107+
});
108+
}
109+
);
110+
111+
// WebSocket events
112+
diagnostics_channel.subscribe('undici:websocket:open', (message: any) => {
113+
console.log(`🌐 [DIAG] WEBSOCKET OPEN:`, {
114+
address: message.address,
115+
protocol: message.protocol,
116+
extensions: message.extensions
117+
});
118+
});
119+
120+
diagnostics_channel.subscribe('undici:websocket:close', (message: any) => {
121+
console.log(`🌐 [DIAG] WEBSOCKET CLOSE:`, {
122+
websocket: message.websocket?.url,
123+
code: message.code,
124+
reason: message.reason
125+
});
126+
});
127+
128+
diagnostics_channel.subscribe('undici:websocket:socket_error', (message: any) => {
129+
console.log(`❌ [DIAG] WEBSOCKET SOCKET ERROR:`, {
130+
websocket: message.websocket?.url,
131+
error: message.error
132+
});
133+
});
134+
}
135+
}
136+
137+
function formatHeaders(headers: any[] | string | undefined) {
138+
if (typeof headers === 'string') {
139+
return headers;
140+
}
141+
142+
return headers?.map((header) => {
143+
if (typeof header == 'string') {
144+
return header;
145+
} else if (Buffer.isBuffer(header)) {
146+
return header.toString('utf-8');
147+
} else {
148+
return header;
149+
}
150+
});
151+
}

demos/example-node/src/main.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,18 @@ import repl_factory from 'node:repl';
44
import { createBaseLogger, createLogger, PowerSyncDatabase, SyncStreamConnectionMethod } from '@powersync/node';
55
import { exit } from 'node:process';
66
import { AppSchema, DemoConnector } from './powersync.js';
7+
import { enableUncidiDiagnostics } from './UndiciDiagnostics.js';
78

89
const main = async () => {
910
const baseLogger = createBaseLogger();
1011
const logger = createLogger('PowerSyncDemo');
11-
baseLogger.useDefaults({ defaultLevel: logger.WARN });
12+
const debug = process.env.POWERSYNC_DEBUG == '1';
13+
baseLogger.useDefaults({ defaultLevel: debug ? logger.TRACE : logger.WARN });
14+
15+
// Enable detailed request/response logging for debugging purposes.
16+
if (debug) {
17+
enableUncidiDiagnostics();
18+
}
1219

1320
if (!('BACKEND' in process.env) || !('SYNC_SERVICE' in process.env)) {
1421
console.warn(

0 commit comments

Comments
 (0)