@echoteam/signoz-react 1.2.1 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,6 +24,12 @@ Library React untuk monitoring dan tracing aplikasi menggunakan OpenTelemetry da
24
24
  - First Paint, First Contentful Paint
25
25
  - DOM Content Loaded, Load Complete
26
26
  - Resource timing
27
+ - **WebSocket Logging**: Otomatis track WebSocket connections dan messages
28
+ - Track connection open, close, error
29
+ - Log messages sent dan received
30
+ - Extract message type dan text dari JSON
31
+ - Connection duration tracking
32
+ - Data tersimpan di SignOz span attributes
27
33
  - **No Click Tracking**: User interaction (click events) tidak di-track untuk privacy dan performa
28
34
  - **Error Boundary**: Komponen React untuk menangkap dan melaporkan error dengan tracing
29
35
  - **Error Page**: Halaman error untuk React Router dengan integrasi tracing
@@ -66,10 +72,17 @@ REACT_APP_SIGNOZ_LOG_REQUEST_BODY=true
66
72
  REACT_APP_SIGNOZ_LOG_RESPONSE_BODY=true
67
73
  REACT_APP_SIGNOZ_MAX_BODY_LOG_SIZE=10000
68
74
 
69
- # Konfigurasi Tracking (opsional, default: true)
70
- REACT_APP_SIGNOZ_ENABLE_DOCUMENT_LOAD=true
71
- REACT_APP_SIGNOZ_ENABLE_ERROR_TRACKING=true
72
- REACT_APP_SIGNOZ_ENABLE_NAVIGATION_TRACKING=true
75
+ # Konfigurasi Tracking (opsional)
76
+ REACT_APP_SIGNOZ_ENABLE_DOCUMENT_LOAD=false # default: false
77
+ REACT_APP_SIGNOZ_ENABLE_ERROR_TRACKING=true # default: true
78
+ REACT_APP_SIGNOZ_ENABLE_NAVIGATION_TRACKING=false # default: false
79
+
80
+ # WebSocket Logging (opsional, default: false)
81
+ REACT_APP_SIGNOZ_ENABLE_WEBSOCKET_LOGGING=false
82
+ REACT_APP_SIGNOZ_LOG_WEBSOCKET_MESSAGES=false
83
+
84
+ # Console Logging (opsional, default: false)
85
+ REACT_APP_SIGNOZ_ENABLE_CONSOLE_LOG=false
73
86
  ```
74
87
 
75
88
  > **Catatan untuk REACT_APP_SIGNOZ_ALLOWED_ORIGINS:**
@@ -131,9 +144,14 @@ initializeSignOzTracing({
131
144
  logResponseBody: true, // Log response body (default: true)
132
145
  maxBodyLogSize: 10000, // Maksimal 10KB per log (default: 10000)
133
146
  // Konfigurasi tracking
134
- enableDocumentLoad: true, // Track page load performance (default: true)
147
+ enableDocumentLoad: false, // Track page load performance (default: false)
135
148
  enableErrorTracking: true, // Track unhandled errors (default: true)
136
- enableNavigationTracking: true // Track route changes (default: true)
149
+ enableNavigationTracking: false, // Track route changes (default: false)
150
+ // WebSocket logging (default: false)
151
+ enableWebSocketLogging: false, // Track WebSocket connections and messages
152
+ logWebSocketMessages: false, // Log WebSocket message content
153
+ // Console logging (default: false, hanya kirim ke SignOz tanpa console.log)
154
+ enableConsoleLog: false // Set true untuk enable console.log di browser
137
155
  });
138
156
  ```
139
157
 
@@ -171,10 +189,12 @@ Library ini secara otomatis melog semua HTTP request dan response yang dilakukan
171
189
  3. Pilih trace yang ingin dilihat
172
190
  4. Lihat span attributes:
173
191
  - `http.request.body`: Body dari request (untuk POST/PUT/PATCH)
174
- - `http.response.body`: Body dari response
192
+ - `response.data`: Body dari response
193
+ - `response.message`: Message dari response JSON (jika ada field `message`)
175
194
  - `http.url`: URL endpoint
176
195
  - `http.method`: HTTP method
177
196
  - `http.status_code`: Status code response
197
+ - `duration_ms`: Durasi request dalam milliseconds
178
198
  - `page.url`: URL halaman frontend yang melakukan request
179
199
  - `page.pathname`: Pathname halaman frontend
180
200
  - `page.search`: Query parameters halaman frontend
@@ -298,6 +318,64 @@ initializeSignOzTracing({
298
318
  });
299
319
  ```
300
320
 
321
+ ### WebSocket Logging
322
+
323
+ Library ini otomatis track semua WebSocket connections dan messages.
324
+
325
+ **Contoh Output di Console:**
326
+ ```
327
+ [SignOz] WebSocket Connected to wss://api.example.com/ws from page /dashboard [45ms]
328
+ [SignOz] WebSocket Send to wss://api.example.com/ws from page /dashboard: {"type":"subscribe","channel":"updates"}
329
+ [SignOz] WebSocket Receive from wss://api.example.com/ws on page /dashboard: {"type":"message","data":"Hello"}
330
+ [SignOz] WebSocket Closed wss://api.example.com/ws on page /dashboard - Code: 1000, Reason: Normal closure, Clean: true
331
+ ```
332
+
333
+ **Data yang Di-track:**
334
+ - WebSocket connection (open, close, error)
335
+ - Connection duration
336
+ - Messages sent (dengan content)
337
+ - Messages received (dengan content)
338
+ - Close code dan reason
339
+ - URL halaman frontend yang membuat connection
340
+ - Message type (jika ada field `type` atau `event` di JSON)
341
+ - Message text (jika ada field `message` di JSON)
342
+
343
+ **Melihat di SignOz:**
344
+ 1. Navigasi ke **Traces**
345
+ 2. Filter by span name: "WebSocket Connection", "WebSocket Send", "WebSocket Receive", "WebSocket Close", atau "WebSocket Error"
346
+ 3. Lihat span attributes:
347
+ - `websocket.url`: URL WebSocket
348
+ - `websocket.protocols`: Protocols yang digunakan
349
+ - `websocket.state`: State connection (open, closed, error)
350
+ - `websocket.direction`: Arah message (send/receive)
351
+ - `websocket.message`: Content message
352
+ - `websocket.message.type`: Tipe message (jika ada)
353
+ - `websocket.message.text`: Text message (jika ada field `message`)
354
+ - `websocket.close.code`: Close code
355
+ - `websocket.close.reason`: Alasan close
356
+ - `websocket.close.wasClean`: Apakah close dengan clean
357
+ - `duration_ms`: Durasi connection
358
+ - `page.url`: URL halaman frontend
359
+ - `page.pathname`: Pathname halaman frontend
360
+
361
+ **Mengaktifkan WebSocket Logging:**
362
+ ```typescript
363
+ // WebSocket logging disabled by default
364
+ // Untuk mengaktifkan:
365
+ initializeSignOzTracing({
366
+ // ... konfigurasi lainnya
367
+ enableWebSocketLogging: true,
368
+ logWebSocketMessages: true // Enable message logging
369
+ });
370
+
371
+ // Atau hanya track connection tanpa log messages
372
+ initializeSignOzTracing({
373
+ // ... konfigurasi lainnya
374
+ enableWebSocketLogging: true,
375
+ logWebSocketMessages: false // Hanya track connection, tidak log messages
376
+ });
377
+ ```
378
+
301
379
  ### Error Boundary
302
380
 
303
381
  #### Penggunaan Dasar
@@ -452,9 +530,12 @@ Inisialisasi SignOz tracing untuk aplikasi React.
452
530
  - `logRequestBody` (opsional): Log request body untuk POST/PUT/PATCH (default: true)
453
531
  - `logResponseBody` (opsional): Log response body untuk semua request (default: true)
454
532
  - `maxBodyLogSize` (opsional): Maksimal ukuran body yang di-log dalam bytes (default: 10000)
455
- - `enableDocumentLoad` (opsional): Aktifkan document load instrumentation (default: true)
533
+ - `enableDocumentLoad` (opsional): Aktifkan document load instrumentation (default: false)
456
534
  - `enableErrorTracking` (opsional): Aktifkan automatic error tracking (default: true)
457
- - `enableNavigationTracking` (opsional): Aktifkan navigation/route tracking (default: true)
535
+ - `enableNavigationTracking` (opsional): Aktifkan navigation/route tracking (default: false)
536
+ - `enableConsoleLog` (opsional): Aktifkan console.log output di browser (default: false)
537
+ - `enableWebSocketLogging` (opsional): Aktifkan WebSocket connection dan message tracking (default: false)
538
+ - `logWebSocketMessages` (opsional): Log WebSocket message content (default: false)
458
539
 
459
540
  ### `ErrorBoundary`
460
541
 
package/dist/index.d.ts CHANGED
@@ -20,6 +20,9 @@ interface SignOzConfig {
20
20
  enableDocumentLoad?: boolean;
21
21
  enableErrorTracking?: boolean;
22
22
  enableNavigationTracking?: boolean;
23
+ enableConsoleLog?: boolean;
24
+ enableWebSocketLogging?: boolean;
25
+ logWebSocketMessages?: boolean;
23
26
  }
24
27
  declare global {
25
28
  interface Window {
package/dist/index.esm.js CHANGED
@@ -15318,6 +15318,8 @@ function addFetchLogging(config) {
15318
15318
  // Capture current page info
15319
15319
  const pageUrl = window.location.href;
15320
15320
  const pagePath = window.location.pathname;
15321
+ // Track start time
15322
+ const startTime = performance.now();
15321
15323
  const tracer = trace.getTracer('fetch-logger');
15322
15324
  const span = tracer.startSpan(`HTTP ${method} ${url}`);
15323
15325
  try {
@@ -15332,9 +15334,14 @@ function addFetchLogging(config) {
15332
15334
  if (config.logRequestBody && (init === null || init === void 0 ? void 0 : init.body) && ['POST', 'PUT', 'PATCH'].includes(method.toUpperCase())) {
15333
15335
  const bodyStr = truncateBody(init.body, config.maxBodyLogSize);
15334
15336
  span.setAttribute('http.request.body', bodyStr);
15335
- console.log(`[SignOz] ${method} Request to ${url} from page ${pagePath}:`, bodyStr);
15337
+ if (config.enableConsoleLog) {
15338
+ console.log(`[SignOz] ${method} Request to ${url} from page ${pagePath}:`, bodyStr);
15339
+ }
15336
15340
  }
15337
15341
  const response = await originalFetch.apply(this, args);
15342
+ // Calculate duration
15343
+ const duration = performance.now() - startTime;
15344
+ span.setAttribute('duration_ms', Math.round(duration));
15338
15345
  // Log response data
15339
15346
  span.setAttribute('http.status_code', response.status);
15340
15347
  if (config.logResponseBody && response.ok) {
@@ -15342,23 +15349,42 @@ function addFetchLogging(config) {
15342
15349
  try {
15343
15350
  const responseData = await clonedResponse.text();
15344
15351
  const truncatedData = truncateBody(responseData, config.maxBodyLogSize);
15345
- span.setAttribute('http.response.body', truncatedData);
15346
- console.log(`[SignOz] ${method} Response from ${url} (${response.status}) on page ${pagePath}:`, truncatedData);
15352
+ span.setAttribute('response.data', truncatedData);
15353
+ // Try to parse JSON and extract message if exists
15354
+ try {
15355
+ const jsonData = JSON.parse(responseData);
15356
+ if (jsonData.message) {
15357
+ span.setAttribute('response.message', jsonData.message);
15358
+ }
15359
+ }
15360
+ catch (e) {
15361
+ // Not JSON or no message field, ignore
15362
+ }
15363
+ if (config.enableConsoleLog) {
15364
+ console.log(`[SignOz] ${method} Response from ${url} (${response.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
15365
+ }
15347
15366
  }
15348
15367
  catch (e) {
15349
- console.warn('[SignOz] Failed to read response body:', e);
15368
+ if (config.enableConsoleLog) {
15369
+ console.warn('[SignOz] Failed to read response body:', e);
15370
+ }
15350
15371
  }
15351
15372
  }
15352
- else if (!response.ok) {
15353
- console.log(`[SignOz] ${method} Request to ${url} from page ${pagePath} - Status: ${response.status}`);
15373
+ else if (!response.ok && config.enableConsoleLog) {
15374
+ console.log(`[SignOz] ${method} Request to ${url} from page ${pagePath} - Status: ${response.status} [${Math.round(duration)}ms]`);
15354
15375
  }
15355
15376
  span.setStatus({ code: SpanStatusCode.OK });
15356
15377
  return response;
15357
15378
  }
15358
15379
  catch (error) {
15380
+ // Calculate duration even on error
15381
+ const duration = performance.now() - startTime;
15382
+ span.setAttribute('duration_ms', Math.round(duration));
15359
15383
  span.recordException(error);
15360
15384
  span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
15361
- console.error(`[SignOz] ${method} Error for ${url} on page ${pagePath}:`, error);
15385
+ if (config.enableConsoleLog) {
15386
+ console.error(`[SignOz] ${method} Error for ${url} on page ${pagePath} [${Math.round(duration)}ms]:`, error);
15387
+ }
15362
15388
  throw error;
15363
15389
  }
15364
15390
  finally {
@@ -15375,6 +15401,7 @@ function addXHRLogging(config) {
15375
15401
  const xhr = new OriginalXHR();
15376
15402
  let method = '';
15377
15403
  let url = '';
15404
+ let startTime = 0;
15378
15405
  // Capture current page info when XHR is created
15379
15406
  const pageUrl = window.location.href;
15380
15407
  const pagePath = window.location.pathname;
@@ -15386,6 +15413,8 @@ function addXHRLogging(config) {
15386
15413
  };
15387
15414
  const originalSend = xhr.send;
15388
15415
  xhr.send = function (body) {
15416
+ // Track start time
15417
+ startTime = performance.now();
15389
15418
  const tracer = trace.getTracer('xhr-logger');
15390
15419
  const span = tracer.startSpan(`HTTP ${method} ${url}`);
15391
15420
  span.setAttribute('http.url', url);
@@ -15399,27 +15428,49 @@ function addXHRLogging(config) {
15399
15428
  if (config.logRequestBody && body && ['POST', 'PUT', 'PATCH'].includes(method.toUpperCase())) {
15400
15429
  const bodyStr = truncateBody(body, config.maxBodyLogSize);
15401
15430
  span.setAttribute('http.request.body', bodyStr);
15402
- console.log(`[SignOz] ${method} Request to ${url} from page ${pagePath}:`, bodyStr);
15431
+ if (config.enableConsoleLog) {
15432
+ console.log(`[SignOz] ${method} Request to ${url} from page ${pagePath}:`, bodyStr);
15433
+ }
15403
15434
  }
15404
15435
  this.addEventListener('load', function () {
15436
+ // Calculate duration
15437
+ const duration = performance.now() - startTime;
15438
+ span.setAttribute('duration_ms', Math.round(duration));
15405
15439
  span.setAttribute('http.status_code', xhr.status);
15406
15440
  // Log response body
15407
15441
  if (config.logResponseBody && xhr.status >= 200 && xhr.status < 300) {
15408
15442
  const responseData = xhr.responseText;
15409
15443
  const truncatedData = truncateBody(responseData, config.maxBodyLogSize);
15410
- span.setAttribute('http.response.body', truncatedData);
15411
- console.log(`[SignOz] ${method} Response from ${url} (${xhr.status}) on page ${pagePath}:`, truncatedData);
15444
+ span.setAttribute('response.data', truncatedData);
15445
+ // Try to parse JSON and extract message if exists
15446
+ try {
15447
+ const jsonData = JSON.parse(responseData);
15448
+ if (jsonData.message) {
15449
+ span.setAttribute('response.message', jsonData.message);
15450
+ }
15451
+ }
15452
+ catch (e) {
15453
+ // Not JSON or no message field, ignore
15454
+ }
15455
+ if (config.enableConsoleLog) {
15456
+ console.log(`[SignOz] ${method} Response from ${url} (${xhr.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
15457
+ }
15412
15458
  }
15413
- else if (xhr.status >= 300) {
15414
- console.log(`[SignOz] ${method} Request to ${url} from page ${pagePath} - Status: ${xhr.status}`);
15459
+ else if (xhr.status >= 300 && config.enableConsoleLog) {
15460
+ console.log(`[SignOz] ${method} Request to ${url} from page ${pagePath} - Status: ${xhr.status} [${Math.round(duration)}ms]`);
15415
15461
  }
15416
15462
  span.setStatus({ code: SpanStatusCode.OK });
15417
15463
  span.end();
15418
15464
  });
15419
15465
  this.addEventListener('error', function () {
15466
+ // Calculate duration even on error
15467
+ const duration = performance.now() - startTime;
15468
+ span.setAttribute('duration_ms', Math.round(duration));
15420
15469
  span.recordException(new Error('XHR request failed'));
15421
15470
  span.setStatus({ code: SpanStatusCode.ERROR, message: 'XHR request failed' });
15422
- console.error(`[SignOz] ${method} Error for ${url} on page ${pagePath}`);
15471
+ if (config.enableConsoleLog) {
15472
+ console.error(`[SignOz] ${method} Error for ${url} on page ${pagePath} [${Math.round(duration)}ms]`);
15473
+ }
15423
15474
  span.end();
15424
15475
  });
15425
15476
  return originalSend.call(this, body);
@@ -15428,7 +15479,7 @@ function addXHRLogging(config) {
15428
15479
  };
15429
15480
  }
15430
15481
  // Fungsi untuk menambahkan error tracking
15431
- function addErrorTracking() {
15482
+ function addErrorTracking(enableConsoleLog = false) {
15432
15483
  // Track unhandled errors
15433
15484
  window.addEventListener('error', (event) => {
15434
15485
  var _a;
@@ -15444,13 +15495,15 @@ function addErrorTracking() {
15444
15495
  span.setAttribute('error.stack', event.error.stack || '');
15445
15496
  }
15446
15497
  span.setStatus({ code: SpanStatusCode.ERROR, message: event.message });
15447
- console.error('[SignOz] Unhandled Error:', {
15448
- message: event.message,
15449
- filename: event.filename,
15450
- lineno: event.lineno,
15451
- colno: event.colno,
15452
- stack: (_a = event.error) === null || _a === void 0 ? void 0 : _a.stack
15453
- });
15498
+ if (enableConsoleLog) {
15499
+ console.error('[SignOz] Unhandled Error:', {
15500
+ message: event.message,
15501
+ filename: event.filename,
15502
+ lineno: event.lineno,
15503
+ colno: event.colno,
15504
+ stack: (_a = event.error) === null || _a === void 0 ? void 0 : _a.stack
15505
+ });
15506
+ }
15454
15507
  span.end();
15455
15508
  });
15456
15509
  // Track unhandled promise rejections
@@ -15465,12 +15518,14 @@ function addErrorTracking() {
15465
15518
  span.setAttribute('error.stack', event.reason.stack || '');
15466
15519
  }
15467
15520
  span.setStatus({ code: SpanStatusCode.ERROR, message: String(event.reason) });
15468
- console.error('[SignOz] Unhandled Promise Rejection:', event.reason);
15521
+ if (enableConsoleLog) {
15522
+ console.error('[SignOz] Unhandled Promise Rejection:', event.reason);
15523
+ }
15469
15524
  span.end();
15470
15525
  });
15471
15526
  }
15472
15527
  // Fungsi untuk menambahkan navigation tracking
15473
- function addNavigationTracking() {
15528
+ function addNavigationTracking(enableConsoleLog = false) {
15474
15529
  let previousUrl = window.location.href;
15475
15530
  // Track initial page load
15476
15531
  const tracer = trace.getTracer('navigation-tracker');
@@ -15480,10 +15535,12 @@ function addNavigationTracking() {
15480
15535
  initialSpan.setAttribute('navigation.pathname', window.location.pathname);
15481
15536
  initialSpan.setAttribute('navigation.search', window.location.search);
15482
15537
  initialSpan.setAttribute('navigation.hash', window.location.hash);
15483
- console.log('[SignOz] Page Load:', {
15484
- url: window.location.href,
15485
- pathname: window.location.pathname
15486
- });
15538
+ if (enableConsoleLog) {
15539
+ console.log('[SignOz] Page Load:', {
15540
+ url: window.location.href,
15541
+ pathname: window.location.pathname
15542
+ });
15543
+ }
15487
15544
  initialSpan.end();
15488
15545
  // Track popstate (browser back/forward)
15489
15546
  window.addEventListener('popstate', () => {
@@ -15494,11 +15551,13 @@ function addNavigationTracking() {
15494
15551
  span.setAttribute('navigation.pathname', window.location.pathname);
15495
15552
  span.setAttribute('navigation.search', window.location.search);
15496
15553
  span.setAttribute('navigation.hash', window.location.hash);
15497
- console.log('[SignOz] Navigation (popstate):', {
15498
- from: previousUrl,
15499
- to: window.location.href,
15500
- pathname: window.location.pathname
15501
- });
15554
+ if (enableConsoleLog) {
15555
+ console.log('[SignOz] Navigation (popstate):', {
15556
+ from: previousUrl,
15557
+ to: window.location.href,
15558
+ pathname: window.location.pathname
15559
+ });
15560
+ }
15502
15561
  previousUrl = window.location.href;
15503
15562
  span.end();
15504
15563
  });
@@ -15513,11 +15572,13 @@ function addNavigationTracking() {
15513
15572
  span.setAttribute('navigation.pathname', window.location.pathname);
15514
15573
  span.setAttribute('navigation.search', window.location.search);
15515
15574
  span.setAttribute('navigation.hash', window.location.hash);
15516
- console.log('[SignOz] Navigation (pushState):', {
15517
- from: previousUrl,
15518
- to: window.location.href,
15519
- pathname: window.location.pathname
15520
- });
15575
+ if (enableConsoleLog) {
15576
+ console.log('[SignOz] Navigation (pushState):', {
15577
+ from: previousUrl,
15578
+ to: window.location.href,
15579
+ pathname: window.location.pathname
15580
+ });
15581
+ }
15521
15582
  previousUrl = window.location.href;
15522
15583
  span.end();
15523
15584
  return result;
@@ -15532,16 +15593,181 @@ function addNavigationTracking() {
15532
15593
  span.setAttribute('navigation.pathname', window.location.pathname);
15533
15594
  span.setAttribute('navigation.search', window.location.search);
15534
15595
  span.setAttribute('navigation.hash', window.location.hash);
15535
- console.log('[SignOz] Navigation (replaceState):', {
15536
- from: previousUrl,
15537
- to: window.location.href,
15538
- pathname: window.location.pathname
15539
- });
15596
+ if (enableConsoleLog) {
15597
+ console.log('[SignOz] Navigation (replaceState):', {
15598
+ from: previousUrl,
15599
+ to: window.location.href,
15600
+ pathname: window.location.pathname
15601
+ });
15602
+ }
15540
15603
  previousUrl = window.location.href;
15541
15604
  span.end();
15542
15605
  return result;
15543
15606
  };
15544
15607
  }
15608
+ // Fungsi untuk menambahkan WebSocket logging
15609
+ function addWebSocketLogging(config) {
15610
+ if (!config.enableWebSocketLogging)
15611
+ return;
15612
+ const OriginalWebSocket = window.WebSocket;
15613
+ window.WebSocket = function (url, protocols) {
15614
+ const ws = new OriginalWebSocket(url, protocols);
15615
+ const wsUrl = typeof url === 'string' ? url : url.toString();
15616
+ // Capture current page info
15617
+ const pageUrl = window.location.href;
15618
+ const pagePath = window.location.pathname;
15619
+ const tracer = trace.getTracer('websocket-logger');
15620
+ let connectionSpan = tracer.startSpan('WebSocket Connection');
15621
+ const connectionStartTime = performance.now();
15622
+ connectionSpan.setAttribute('websocket.url', wsUrl);
15623
+ connectionSpan.setAttribute('websocket.protocols', Array.isArray(protocols) ? protocols.join(',') : (protocols || 'none'));
15624
+ connectionSpan.setAttribute('page.url', pageUrl);
15625
+ connectionSpan.setAttribute('page.pathname', pagePath);
15626
+ // Track connection open
15627
+ const originalOnOpen = ws.onopen;
15628
+ ws.addEventListener('open', function (event) {
15629
+ const duration = performance.now() - connectionStartTime;
15630
+ connectionSpan.setAttribute('websocket.state', 'open');
15631
+ connectionSpan.setAttribute('duration_ms', Math.round(duration));
15632
+ connectionSpan.setStatus({ code: SpanStatusCode.OK });
15633
+ if (config.enableConsoleLog) {
15634
+ console.log(`[SignOz] WebSocket Connected to ${wsUrl} from page ${pagePath} [${Math.round(duration)}ms]`);
15635
+ }
15636
+ connectionSpan.end();
15637
+ if (originalOnOpen) {
15638
+ originalOnOpen.call(ws, event);
15639
+ }
15640
+ });
15641
+ // Track messages sent
15642
+ const originalSend = ws.send;
15643
+ ws.send = function (data) {
15644
+ if (config.logWebSocketMessages) {
15645
+ const messageSpan = tracer.startSpan('WebSocket Send');
15646
+ const sendStartTime = performance.now();
15647
+ messageSpan.setAttribute('websocket.url', wsUrl);
15648
+ messageSpan.setAttribute('websocket.direction', 'send');
15649
+ messageSpan.setAttribute('page.url', pageUrl);
15650
+ messageSpan.setAttribute('page.pathname', pagePath);
15651
+ // Log message data
15652
+ if (typeof data === 'string') {
15653
+ const truncatedData = truncateBody(data, config.maxBodyLogSize);
15654
+ messageSpan.setAttribute('websocket.message', truncatedData);
15655
+ // Try to parse JSON and extract message if exists
15656
+ try {
15657
+ const jsonData = JSON.parse(data);
15658
+ if (jsonData.message) {
15659
+ messageSpan.setAttribute('websocket.message.text', jsonData.message);
15660
+ }
15661
+ if (jsonData.type || jsonData.event) {
15662
+ messageSpan.setAttribute('websocket.message.type', jsonData.type || jsonData.event);
15663
+ }
15664
+ }
15665
+ catch (e) {
15666
+ // Not JSON, ignore
15667
+ }
15668
+ if (config.enableConsoleLog) {
15669
+ console.log(`[SignOz] WebSocket Send to ${wsUrl} from page ${pagePath}:`, truncatedData);
15670
+ }
15671
+ }
15672
+ else {
15673
+ messageSpan.setAttribute('websocket.message', '[Binary Data]');
15674
+ messageSpan.setAttribute('websocket.message.type', 'binary');
15675
+ if (config.enableConsoleLog) {
15676
+ console.log(`[SignOz] WebSocket Send to ${wsUrl} from page ${pagePath}: [Binary Data]`);
15677
+ }
15678
+ }
15679
+ const duration = performance.now() - sendStartTime;
15680
+ messageSpan.setAttribute('duration_ms', Math.round(duration));
15681
+ messageSpan.setStatus({ code: SpanStatusCode.OK });
15682
+ messageSpan.end();
15683
+ }
15684
+ return originalSend.call(ws, data);
15685
+ };
15686
+ // Track messages received
15687
+ const originalOnMessage = ws.onmessage;
15688
+ ws.addEventListener('message', function (event) {
15689
+ if (config.logWebSocketMessages) {
15690
+ const messageSpan = tracer.startSpan('WebSocket Receive');
15691
+ messageSpan.setAttribute('websocket.url', wsUrl);
15692
+ messageSpan.setAttribute('websocket.direction', 'receive');
15693
+ messageSpan.setAttribute('page.url', pageUrl);
15694
+ messageSpan.setAttribute('page.pathname', pagePath);
15695
+ // Log message data
15696
+ if (typeof event.data === 'string') {
15697
+ const truncatedData = truncateBody(event.data, config.maxBodyLogSize);
15698
+ messageSpan.setAttribute('websocket.message', truncatedData);
15699
+ // Try to parse JSON and extract message if exists
15700
+ try {
15701
+ const jsonData = JSON.parse(event.data);
15702
+ if (jsonData.message) {
15703
+ messageSpan.setAttribute('websocket.message.text', jsonData.message);
15704
+ }
15705
+ if (jsonData.type || jsonData.event) {
15706
+ messageSpan.setAttribute('websocket.message.type', jsonData.type || jsonData.event);
15707
+ }
15708
+ }
15709
+ catch (e) {
15710
+ // Not JSON, ignore
15711
+ }
15712
+ if (config.enableConsoleLog) {
15713
+ console.log(`[SignOz] WebSocket Receive from ${wsUrl} on page ${pagePath}:`, truncatedData);
15714
+ }
15715
+ }
15716
+ else {
15717
+ messageSpan.setAttribute('websocket.message', '[Binary Data]');
15718
+ messageSpan.setAttribute('websocket.message.type', 'binary');
15719
+ if (config.enableConsoleLog) {
15720
+ console.log(`[SignOz] WebSocket Receive from ${wsUrl} on page ${pagePath}: [Binary Data]`);
15721
+ }
15722
+ }
15723
+ messageSpan.setStatus({ code: SpanStatusCode.OK });
15724
+ messageSpan.end();
15725
+ }
15726
+ if (originalOnMessage) {
15727
+ originalOnMessage.call(ws, event);
15728
+ }
15729
+ });
15730
+ // Track connection errors
15731
+ const originalOnError = ws.onerror;
15732
+ ws.addEventListener('error', function (event) {
15733
+ const errorSpan = tracer.startSpan('WebSocket Error');
15734
+ errorSpan.setAttribute('websocket.url', wsUrl);
15735
+ errorSpan.setAttribute('websocket.state', 'error');
15736
+ errorSpan.setAttribute('page.url', pageUrl);
15737
+ errorSpan.setAttribute('page.pathname', pagePath);
15738
+ errorSpan.recordException(new Error('WebSocket connection error'));
15739
+ errorSpan.setStatus({ code: SpanStatusCode.ERROR, message: 'WebSocket connection error' });
15740
+ if (config.enableConsoleLog) {
15741
+ console.error(`[SignOz] WebSocket Error for ${wsUrl} on page ${pagePath}`);
15742
+ }
15743
+ errorSpan.end();
15744
+ if (originalOnError) {
15745
+ originalOnError.call(ws, event);
15746
+ }
15747
+ });
15748
+ // Track connection close
15749
+ const originalOnClose = ws.onclose;
15750
+ ws.addEventListener('close', function (event) {
15751
+ const closeSpan = tracer.startSpan('WebSocket Close');
15752
+ closeSpan.setAttribute('websocket.url', wsUrl);
15753
+ closeSpan.setAttribute('websocket.state', 'closed');
15754
+ closeSpan.setAttribute('websocket.close.code', event.code);
15755
+ closeSpan.setAttribute('websocket.close.reason', event.reason || 'No reason provided');
15756
+ closeSpan.setAttribute('websocket.close.wasClean', event.wasClean);
15757
+ closeSpan.setAttribute('page.url', pageUrl);
15758
+ closeSpan.setAttribute('page.pathname', pagePath);
15759
+ if (config.enableConsoleLog) {
15760
+ console.log(`[SignOz] WebSocket Closed ${wsUrl} on page ${pagePath} - Code: ${event.code}, Reason: ${event.reason || 'No reason'}, Clean: ${event.wasClean}`);
15761
+ }
15762
+ closeSpan.setStatus({ code: SpanStatusCode.OK });
15763
+ closeSpan.end();
15764
+ if (originalOnClose) {
15765
+ originalOnClose.call(ws, event);
15766
+ }
15767
+ });
15768
+ return ws;
15769
+ };
15770
+ }
15545
15771
  /**
15546
15772
  * Inisialisasi SignOz tracing untuk aplikasi React
15547
15773
  * @param config - Konfigurasi SignOz (opsional, akan menggunakan environment variables jika tidak disediakan)
@@ -15570,9 +15796,12 @@ function initializeSignOzTracing(config) {
15570
15796
  logRequestBody: (config === null || config === void 0 ? void 0 : config.logRequestBody) !== undefined ? config.logRequestBody : (getConfigValue('REACT_APP_SIGNOZ_LOG_REQUEST_BODY') === 'true' || true),
15571
15797
  logResponseBody: (config === null || config === void 0 ? void 0 : config.logResponseBody) !== undefined ? config.logResponseBody : (getConfigValue('REACT_APP_SIGNOZ_LOG_RESPONSE_BODY') === 'true' || true),
15572
15798
  maxBodyLogSize: (config === null || config === void 0 ? void 0 : config.maxBodyLogSize) || parseInt(getConfigValue('REACT_APP_SIGNOZ_MAX_BODY_LOG_SIZE') || '10000') || 10000,
15573
- enableDocumentLoad: (config === null || config === void 0 ? void 0 : config.enableDocumentLoad) !== undefined ? config.enableDocumentLoad : (getConfigValue('REACT_APP_SIGNOZ_ENABLE_DOCUMENT_LOAD') !== 'false'),
15799
+ enableDocumentLoad: (config === null || config === void 0 ? void 0 : config.enableDocumentLoad) !== undefined ? config.enableDocumentLoad : (getConfigValue('REACT_APP_SIGNOZ_ENABLE_DOCUMENT_LOAD') === 'true'),
15574
15800
  enableErrorTracking: (config === null || config === void 0 ? void 0 : config.enableErrorTracking) !== undefined ? config.enableErrorTracking : (getConfigValue('REACT_APP_SIGNOZ_ENABLE_ERROR_TRACKING') !== 'false'),
15575
- enableNavigationTracking: (config === null || config === void 0 ? void 0 : config.enableNavigationTracking) !== undefined ? config.enableNavigationTracking : (getConfigValue('REACT_APP_SIGNOZ_ENABLE_NAVIGATION_TRACKING') !== 'false')
15801
+ enableNavigationTracking: (config === null || config === void 0 ? void 0 : config.enableNavigationTracking) !== undefined ? config.enableNavigationTracking : (getConfigValue('REACT_APP_SIGNOZ_ENABLE_NAVIGATION_TRACKING') === 'true'),
15802
+ enableConsoleLog: (config === null || config === void 0 ? void 0 : config.enableConsoleLog) !== undefined ? config.enableConsoleLog : (getConfigValue('REACT_APP_SIGNOZ_ENABLE_CONSOLE_LOG') === 'true'),
15803
+ enableWebSocketLogging: (config === null || config === void 0 ? void 0 : config.enableWebSocketLogging) !== undefined ? config.enableWebSocketLogging : (getConfigValue('REACT_APP_SIGNOZ_ENABLE_WEBSOCKET_LOGGING') === 'true'),
15804
+ logWebSocketMessages: (config === null || config === void 0 ? void 0 : config.logWebSocketMessages) !== undefined ? config.logWebSocketMessages : (getConfigValue('REACT_APP_SIGNOZ_LOG_WEBSOCKET_MESSAGES') === 'true')
15576
15805
  };
15577
15806
  // Validasi konfigurasi
15578
15807
  const { isValid, missingFields } = validateConfig(effectiveConfig);
@@ -15641,22 +15870,33 @@ function initializeSignOzTracing(config) {
15641
15870
  enableRequestLogging: effectiveConfig.enableRequestLogging,
15642
15871
  logRequestBody: effectiveConfig.logRequestBody,
15643
15872
  logResponseBody: effectiveConfig.logResponseBody,
15644
- maxBodyLogSize: effectiveConfig.maxBodyLogSize
15873
+ maxBodyLogSize: effectiveConfig.maxBodyLogSize,
15874
+ enableConsoleLog: effectiveConfig.enableConsoleLog
15645
15875
  });
15646
15876
  addXHRLogging({
15647
15877
  enableRequestLogging: effectiveConfig.enableRequestLogging,
15648
15878
  logRequestBody: effectiveConfig.logRequestBody,
15649
15879
  logResponseBody: effectiveConfig.logResponseBody,
15650
- maxBodyLogSize: effectiveConfig.maxBodyLogSize
15880
+ maxBodyLogSize: effectiveConfig.maxBodyLogSize,
15881
+ enableConsoleLog: effectiveConfig.enableConsoleLog
15651
15882
  });
15652
15883
  }
15653
15884
  // Tambahkan error tracking
15654
15885
  if (effectiveConfig.enableErrorTracking) {
15655
- addErrorTracking();
15886
+ addErrorTracking(effectiveConfig.enableConsoleLog);
15656
15887
  }
15657
15888
  // Tambahkan navigation tracking
15658
15889
  if (effectiveConfig.enableNavigationTracking) {
15659
- addNavigationTracking();
15890
+ addNavigationTracking(effectiveConfig.enableConsoleLog);
15891
+ }
15892
+ // Tambahkan WebSocket logging
15893
+ if (effectiveConfig.enableWebSocketLogging) {
15894
+ addWebSocketLogging({
15895
+ enableWebSocketLogging: effectiveConfig.enableWebSocketLogging,
15896
+ logWebSocketMessages: effectiveConfig.logWebSocketMessages,
15897
+ maxBodyLogSize: effectiveConfig.maxBodyLogSize,
15898
+ enableConsoleLog: effectiveConfig.enableConsoleLog
15899
+ });
15660
15900
  }
15661
15901
  console.log('SignOz: Konfigurasi tracing:', {
15662
15902
  serviceName: effectiveConfig.serviceName,
@@ -15669,7 +15909,9 @@ function initializeSignOzTracing(config) {
15669
15909
  maxBodyLogSize: effectiveConfig.maxBodyLogSize,
15670
15910
  enableDocumentLoad: effectiveConfig.enableDocumentLoad,
15671
15911
  enableErrorTracking: effectiveConfig.enableErrorTracking,
15672
- enableNavigationTracking: effectiveConfig.enableNavigationTracking
15912
+ enableNavigationTracking: effectiveConfig.enableNavigationTracking,
15913
+ enableWebSocketLogging: effectiveConfig.enableWebSocketLogging,
15914
+ logWebSocketMessages: effectiveConfig.logWebSocketMessages
15673
15915
  });
15674
15916
  console.log('SignOz: Tracing berhasil diinisialisasi');
15675
15917
  }