@echoteam/signoz-react 1.2.6 → 1.2.8

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/dist/index.js CHANGED
@@ -15364,24 +15364,49 @@ function addFetchLogging(config) {
15364
15364
  span.setAttribute('duration_ms', Math.round(duration));
15365
15365
  // Log response data
15366
15366
  span.setAttribute('http.status_code', response.status);
15367
- if (config.logResponseBody && response.ok) {
15367
+ // Log response content length from headers
15368
+ const contentLength = response.headers.get('content-length');
15369
+ if (contentLength) {
15370
+ span.setAttribute('http.response_content_length', parseInt(contentLength));
15371
+ }
15372
+ // Log response body for both success and error responses
15373
+ if (config.logResponseBody) {
15368
15374
  const clonedResponse = response.clone();
15369
15375
  try {
15370
15376
  const responseData = await clonedResponse.text();
15371
15377
  const truncatedData = truncateBody(responseData, config.maxBodyLogSize);
15372
15378
  span.setAttribute('response.data', truncatedData);
15379
+ // If content-length header is not available, calculate from response data
15380
+ if (!contentLength) {
15381
+ span.setAttribute('http.response_content_length', responseData.length);
15382
+ }
15373
15383
  // Try to parse JSON and extract message if exists
15374
15384
  try {
15375
15385
  const jsonData = JSON.parse(responseData);
15376
15386
  if (jsonData.message) {
15377
15387
  span.setAttribute('response.message', jsonData.message);
15378
15388
  }
15389
+ // Also log error details if present
15390
+ if (jsonData.errors) {
15391
+ span.setAttribute('response.errors', JSON.stringify(jsonData.errors));
15392
+ }
15393
+ if (jsonData.status !== undefined) {
15394
+ span.setAttribute('response.status', jsonData.status);
15395
+ }
15396
+ if (jsonData.status_code !== undefined) {
15397
+ span.setAttribute('response.status_code', jsonData.status_code);
15398
+ }
15379
15399
  }
15380
15400
  catch (e) {
15381
15401
  // Not JSON or no message field, ignore
15382
15402
  }
15383
15403
  if (config.enableConsoleLog) {
15384
- console.log(`[SignOz] ${method} Response from ${url} (${response.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
15404
+ if (response.ok) {
15405
+ console.log(`[SignOz] ${method} Response from ${url} (${response.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
15406
+ }
15407
+ else {
15408
+ console.error(`[SignOz] ${method} Error Response from ${url} (${response.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
15409
+ }
15385
15410
  }
15386
15411
  }
15387
15412
  catch (e) {
@@ -15391,7 +15416,7 @@ function addFetchLogging(config) {
15391
15416
  }
15392
15417
  }
15393
15418
  else if (!response.ok && config.enableConsoleLog) {
15394
- console.log(`[SignOz] ${method} Request to ${url} from page ${pagePath} - Status: ${response.status} [${Math.round(duration)}ms]`);
15419
+ console.error(`[SignOz] ${method} Request to ${url} from page ${pagePath} - Status: ${response.status} [${Math.round(duration)}ms]`);
15395
15420
  }
15396
15421
  span.setStatus({ code: SpanStatusCode.OK });
15397
15422
  return response;
@@ -15457,27 +15482,71 @@ function addXHRLogging(config) {
15457
15482
  const duration = performance.now() - startTime;
15458
15483
  span.setAttribute('duration_ms', Math.round(duration));
15459
15484
  span.setAttribute('http.status_code', xhr.status);
15460
- // Log response body
15461
- if (config.logResponseBody && xhr.status >= 200 && xhr.status < 300) {
15462
- const responseData = xhr.responseText;
15463
- const truncatedData = truncateBody(responseData, config.maxBodyLogSize);
15464
- span.setAttribute('response.data', truncatedData);
15465
- // Try to parse JSON and extract message if exists
15485
+ // Log response content length from headers
15486
+ const contentLength = xhr.getResponseHeader('content-length');
15487
+ if (contentLength) {
15488
+ span.setAttribute('http.response_content_length', parseInt(contentLength));
15489
+ }
15490
+ // Log response body for both success and error responses
15491
+ if (config.logResponseBody) {
15466
15492
  try {
15467
- const jsonData = JSON.parse(responseData);
15468
- if (jsonData.message) {
15469
- span.setAttribute('response.message', jsonData.message);
15493
+ // Only read responseText if responseType allows it
15494
+ if (xhr.responseType === '' || xhr.responseType === 'text') {
15495
+ const responseData = xhr.responseText;
15496
+ const truncatedData = truncateBody(responseData, config.maxBodyLogSize);
15497
+ span.setAttribute('response.data', truncatedData);
15498
+ // If content-length header is not available, calculate from response data
15499
+ if (!contentLength) {
15500
+ span.setAttribute('http.response_content_length', responseData.length);
15501
+ }
15502
+ // Try to parse JSON and extract message if exists
15503
+ try {
15504
+ const jsonData = JSON.parse(responseData);
15505
+ if (jsonData.message) {
15506
+ span.setAttribute('response.message', jsonData.message);
15507
+ }
15508
+ // Also log error details if present
15509
+ if (jsonData.errors) {
15510
+ span.setAttribute('response.errors', JSON.stringify(jsonData.errors));
15511
+ }
15512
+ if (jsonData.status !== undefined) {
15513
+ span.setAttribute('response.status', jsonData.status);
15514
+ }
15515
+ if (jsonData.status_code !== undefined) {
15516
+ span.setAttribute('response.status_code', jsonData.status_code);
15517
+ }
15518
+ }
15519
+ catch (e) {
15520
+ // Not JSON or no message field, ignore
15521
+ }
15522
+ if (config.enableConsoleLog) {
15523
+ if (xhr.status >= 200 && xhr.status < 300) {
15524
+ console.log(`[SignOz] ${method} Response from ${url} (${xhr.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
15525
+ }
15526
+ else {
15527
+ console.error(`[SignOz] ${method} Error Response from ${url} (${xhr.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
15528
+ }
15529
+ }
15530
+ }
15531
+ else {
15532
+ // For other response types (blob, arraybuffer, etc), just log the type
15533
+ span.setAttribute('response.data', `[${xhr.responseType} data]`);
15534
+ span.setAttribute('response.type', xhr.responseType);
15535
+ if (config.enableConsoleLog) {
15536
+ console.log(`[SignOz] ${method} Response from ${url} (${xhr.status}) on page ${pagePath} [${Math.round(duration)}ms]: [${xhr.responseType} data]`);
15537
+ }
15470
15538
  }
15471
15539
  }
15472
15540
  catch (e) {
15473
- // Not JSON or no message field, ignore
15474
- }
15475
- if (config.enableConsoleLog) {
15476
- console.log(`[SignOz] ${method} Response from ${url} (${xhr.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
15541
+ // If there's an error reading response, log it
15542
+ span.setAttribute('response.data', '[Error reading response]');
15543
+ if (config.enableConsoleLog) {
15544
+ console.warn(`[SignOz] Failed to read response from ${url}:`, e);
15545
+ }
15477
15546
  }
15478
15547
  }
15479
15548
  else if (xhr.status >= 300 && config.enableConsoleLog) {
15480
- console.log(`[SignOz] ${method} Request to ${url} from page ${pagePath} - Status: ${xhr.status} [${Math.round(duration)}ms]`);
15549
+ console.error(`[SignOz] ${method} Request to ${url} from page ${pagePath} - Status: ${xhr.status} [${Math.round(duration)}ms]`);
15481
15550
  }
15482
15551
  span.setStatus({ code: SpanStatusCode.OK });
15483
15552
  span.end();
@@ -15510,9 +15579,15 @@ function addErrorTracking(enableConsoleLog = false) {
15510
15579
  span.setAttribute('error.filename', event.filename || 'unknown');
15511
15580
  span.setAttribute('error.lineno', event.lineno || 0);
15512
15581
  span.setAttribute('error.colno', event.colno || 0);
15582
+ // Add page context
15583
+ span.setAttribute('page.url', window.location.href);
15584
+ span.setAttribute('page.pathname', window.location.pathname);
15585
+ span.setAttribute('page.search', window.location.search);
15586
+ span.setAttribute('page.hash', window.location.hash);
15513
15587
  if (event.error) {
15514
15588
  span.recordException(event.error);
15515
15589
  span.setAttribute('error.stack', event.error.stack || '');
15590
+ span.setAttribute('error.name', event.error.name || 'Error');
15516
15591
  }
15517
15592
  span.setStatus({ code: SpanStatusCode.ERROR, message: event.message });
15518
15593
  if (enableConsoleLog) {
@@ -15521,28 +15596,93 @@ function addErrorTracking(enableConsoleLog = false) {
15521
15596
  filename: event.filename,
15522
15597
  lineno: event.lineno,
15523
15598
  colno: event.colno,
15524
- stack: (_a = event.error) === null || _a === void 0 ? void 0 : _a.stack
15599
+ stack: (_a = event.error) === null || _a === void 0 ? void 0 : _a.stack,
15600
+ page: window.location.pathname
15525
15601
  });
15526
15602
  }
15527
15603
  span.end();
15528
- });
15604
+ }, true); // Use capture phase to catch errors early
15529
15605
  // Track unhandled promise rejections
15530
15606
  window.addEventListener('unhandledrejection', (event) => {
15531
15607
  const tracer = trace.getTracer('error-tracker');
15532
15608
  const span = tracer.startSpan('Unhandled Promise Rejection');
15533
15609
  span.setAttribute('error.type', 'unhandled_rejection');
15534
15610
  span.setAttribute('error.reason', String(event.reason));
15611
+ // Add page context
15612
+ span.setAttribute('page.url', window.location.href);
15613
+ span.setAttribute('page.pathname', window.location.pathname);
15614
+ span.setAttribute('page.search', window.location.search);
15615
+ span.setAttribute('page.hash', window.location.hash);
15535
15616
  if (event.reason instanceof Error) {
15536
15617
  span.recordException(event.reason);
15537
15618
  span.setAttribute('error.message', event.reason.message);
15538
15619
  span.setAttribute('error.stack', event.reason.stack || '');
15620
+ span.setAttribute('error.name', event.reason.name || 'Error');
15539
15621
  }
15540
15622
  span.setStatus({ code: SpanStatusCode.ERROR, message: String(event.reason) });
15541
15623
  if (enableConsoleLog) {
15542
- console.error('[SignOz] Unhandled Promise Rejection:', event.reason);
15624
+ console.error('[SignOz] Unhandled Promise Rejection:', event.reason, 'on page', window.location.pathname);
15543
15625
  }
15544
15626
  span.end();
15545
15627
  });
15628
+ // Track Zone.js errors (for Angular/React with zone.js)
15629
+ if (typeof Zone !== 'undefined' && Zone.current) {
15630
+ const currentZone = Zone.current;
15631
+ const originalHandleError = currentZone.handleError;
15632
+ if (originalHandleError) {
15633
+ currentZone.handleError = function (error) {
15634
+ const tracer = trace.getTracer('error-tracker');
15635
+ const span = tracer.startSpan('Zone.js Error');
15636
+ span.setAttribute('error.type', 'zone_error');
15637
+ span.setAttribute('error.message', error.message || String(error));
15638
+ span.setAttribute('error.name', error.name || 'Error');
15639
+ // Add page context
15640
+ span.setAttribute('page.url', window.location.href);
15641
+ span.setAttribute('page.pathname', window.location.pathname);
15642
+ span.setAttribute('page.search', window.location.search);
15643
+ span.setAttribute('page.hash', window.location.hash);
15644
+ if (error.stack) {
15645
+ span.setAttribute('error.stack', error.stack);
15646
+ }
15647
+ span.recordException(error);
15648
+ span.setStatus({ code: SpanStatusCode.ERROR, message: error.message || String(error) });
15649
+ if (enableConsoleLog) {
15650
+ console.error('[SignOz] Zone.js Error:', error, 'on page', window.location.pathname);
15651
+ }
15652
+ span.end();
15653
+ // Call original handler
15654
+ return originalHandleError.call(currentZone, error);
15655
+ };
15656
+ }
15657
+ }
15658
+ // Override console.error to catch React errors
15659
+ const originalConsoleError = console.error;
15660
+ console.error = function (...args) {
15661
+ // Check if this is a React error
15662
+ const errorMessage = args.map(arg => String(arg)).join(' ');
15663
+ if (errorMessage.includes('React') || errorMessage.includes('TypeError') || errorMessage.includes('Uncaught')) {
15664
+ const tracer = trace.getTracer('error-tracker');
15665
+ const span = tracer.startSpan('Console Error');
15666
+ span.setAttribute('error.type', 'console_error');
15667
+ span.setAttribute('error.message', errorMessage);
15668
+ // Add page context
15669
+ span.setAttribute('page.url', window.location.href);
15670
+ span.setAttribute('page.pathname', window.location.pathname);
15671
+ span.setAttribute('page.search', window.location.search);
15672
+ span.setAttribute('page.hash', window.location.hash);
15673
+ // Try to extract stack trace
15674
+ const errorObj = args.find(arg => arg instanceof Error);
15675
+ if (errorObj) {
15676
+ span.recordException(errorObj);
15677
+ span.setAttribute('error.stack', errorObj.stack || '');
15678
+ span.setAttribute('error.name', errorObj.name || 'Error');
15679
+ }
15680
+ span.setStatus({ code: SpanStatusCode.ERROR, message: errorMessage });
15681
+ span.end();
15682
+ }
15683
+ // Call original console.error
15684
+ return originalConsoleError.apply(console, args);
15685
+ };
15546
15686
  }
15547
15687
  // Fungsi untuk menambahkan navigation tracking
15548
15688
  function addNavigationTracking(enableConsoleLog = false) {
@@ -16105,17 +16245,6 @@ function hasArrayChanged() {
16105
16245
  }
16106
16246
 
16107
16247
  const DefaultErrorFallback = ({ error, resetErrorBoundary }) => {
16108
- const serviceName = window.REACT_APP_SIGNOZ_SERVICE_NAME || 'react-app';
16109
- const tracer = trace.getTracer(serviceName);
16110
- const span = tracer.startSpan(serviceName + ".error");
16111
- React2.useEffect(() => {
16112
- span.setAttribute('error.message', error.message);
16113
- span.setAttribute('error.stack', JSON.stringify(error.stack));
16114
- span.setAttribute('error.name', error.name);
16115
- span.recordException(error);
16116
- span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
16117
- span.end();
16118
- }, [error, span]);
16119
16248
  return (jsxRuntime.jsxs("div", { role: "alert", className: "error-boundary-fallback", children: [jsxRuntime.jsx("h1", { children: "Oops!" }), jsxRuntime.jsx("p", { children: "Terjadi kesalahan yang tidak terduga." }), jsxRuntime.jsx("p", { children: jsxRuntime.jsx("i", { children: error.statusText || error.message }) }), jsxRuntime.jsx("button", { onClick: resetErrorBoundary, children: "Coba lagi" })] }));
16120
16249
  };
16121
16250
  const ErrorBoundary = ({ children, fallback: FallbackComponent, onError, onReset, showResetButton = true, resetButtonText = "Coba lagi", fallbackClassName = "", }) => {
@@ -16124,10 +16253,16 @@ const ErrorBoundary = ({ children, fallback: FallbackComponent, onError, onReset
16124
16253
  const serviceName = window.REACT_APP_SIGNOZ_SERVICE_NAME || 'react-app';
16125
16254
  const tracer = trace.getTracer(serviceName);
16126
16255
  const span = tracer.startSpan(serviceName + ".error");
16256
+ span.setAttribute('error.type', 'react_error_boundary');
16127
16257
  span.setAttribute('error.message', error.message);
16128
- span.setAttribute('error.stack', JSON.stringify(error.stack));
16258
+ span.setAttribute('error.stack', error.stack || '');
16129
16259
  span.setAttribute('error.name', error.name);
16130
16260
  span.setAttribute('error.componentStack', errorInfo.componentStack || '');
16261
+ // Add page context
16262
+ span.setAttribute('page.url', window.location.href);
16263
+ span.setAttribute('page.pathname', window.location.pathname);
16264
+ span.setAttribute('page.search', window.location.search);
16265
+ span.setAttribute('page.hash', window.location.hash);
16131
16266
  span.recordException(error);
16132
16267
  span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
16133
16268
  span.end();