@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/README.md +1 -0
- package/dist/index.esm.js +167 -32
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +167 -32
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -194,6 +194,7 @@ Library ini secara otomatis melog semua HTTP request dan response yang dilakukan
|
|
|
194
194
|
- `http.url`: URL endpoint
|
|
195
195
|
- `http.method`: HTTP method
|
|
196
196
|
- `http.status_code`: Status code response
|
|
197
|
+
- `http.response_content_length`: Ukuran response dalam bytes
|
|
197
198
|
- `duration_ms`: Durasi request dalam milliseconds
|
|
198
199
|
- `page.url`: URL halaman frontend yang melakukan request
|
|
199
200
|
- `page.pathname`: Pathname halaman frontend
|
package/dist/index.esm.js
CHANGED
|
@@ -15344,24 +15344,49 @@ function addFetchLogging(config) {
|
|
|
15344
15344
|
span.setAttribute('duration_ms', Math.round(duration));
|
|
15345
15345
|
// Log response data
|
|
15346
15346
|
span.setAttribute('http.status_code', response.status);
|
|
15347
|
-
|
|
15347
|
+
// Log response content length from headers
|
|
15348
|
+
const contentLength = response.headers.get('content-length');
|
|
15349
|
+
if (contentLength) {
|
|
15350
|
+
span.setAttribute('http.response_content_length', parseInt(contentLength));
|
|
15351
|
+
}
|
|
15352
|
+
// Log response body for both success and error responses
|
|
15353
|
+
if (config.logResponseBody) {
|
|
15348
15354
|
const clonedResponse = response.clone();
|
|
15349
15355
|
try {
|
|
15350
15356
|
const responseData = await clonedResponse.text();
|
|
15351
15357
|
const truncatedData = truncateBody(responseData, config.maxBodyLogSize);
|
|
15352
15358
|
span.setAttribute('response.data', truncatedData);
|
|
15359
|
+
// If content-length header is not available, calculate from response data
|
|
15360
|
+
if (!contentLength) {
|
|
15361
|
+
span.setAttribute('http.response_content_length', responseData.length);
|
|
15362
|
+
}
|
|
15353
15363
|
// Try to parse JSON and extract message if exists
|
|
15354
15364
|
try {
|
|
15355
15365
|
const jsonData = JSON.parse(responseData);
|
|
15356
15366
|
if (jsonData.message) {
|
|
15357
15367
|
span.setAttribute('response.message', jsonData.message);
|
|
15358
15368
|
}
|
|
15369
|
+
// Also log error details if present
|
|
15370
|
+
if (jsonData.errors) {
|
|
15371
|
+
span.setAttribute('response.errors', JSON.stringify(jsonData.errors));
|
|
15372
|
+
}
|
|
15373
|
+
if (jsonData.status !== undefined) {
|
|
15374
|
+
span.setAttribute('response.status', jsonData.status);
|
|
15375
|
+
}
|
|
15376
|
+
if (jsonData.status_code !== undefined) {
|
|
15377
|
+
span.setAttribute('response.status_code', jsonData.status_code);
|
|
15378
|
+
}
|
|
15359
15379
|
}
|
|
15360
15380
|
catch (e) {
|
|
15361
15381
|
// Not JSON or no message field, ignore
|
|
15362
15382
|
}
|
|
15363
15383
|
if (config.enableConsoleLog) {
|
|
15364
|
-
|
|
15384
|
+
if (response.ok) {
|
|
15385
|
+
console.log(`[SignOz] ${method} Response from ${url} (${response.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
|
|
15386
|
+
}
|
|
15387
|
+
else {
|
|
15388
|
+
console.error(`[SignOz] ${method} Error Response from ${url} (${response.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
|
|
15389
|
+
}
|
|
15365
15390
|
}
|
|
15366
15391
|
}
|
|
15367
15392
|
catch (e) {
|
|
@@ -15371,7 +15396,7 @@ function addFetchLogging(config) {
|
|
|
15371
15396
|
}
|
|
15372
15397
|
}
|
|
15373
15398
|
else if (!response.ok && config.enableConsoleLog) {
|
|
15374
|
-
console.
|
|
15399
|
+
console.error(`[SignOz] ${method} Request to ${url} from page ${pagePath} - Status: ${response.status} [${Math.round(duration)}ms]`);
|
|
15375
15400
|
}
|
|
15376
15401
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
15377
15402
|
return response;
|
|
@@ -15437,27 +15462,71 @@ function addXHRLogging(config) {
|
|
|
15437
15462
|
const duration = performance.now() - startTime;
|
|
15438
15463
|
span.setAttribute('duration_ms', Math.round(duration));
|
|
15439
15464
|
span.setAttribute('http.status_code', xhr.status);
|
|
15440
|
-
// Log response
|
|
15441
|
-
|
|
15442
|
-
|
|
15443
|
-
|
|
15444
|
-
|
|
15445
|
-
|
|
15465
|
+
// Log response content length from headers
|
|
15466
|
+
const contentLength = xhr.getResponseHeader('content-length');
|
|
15467
|
+
if (contentLength) {
|
|
15468
|
+
span.setAttribute('http.response_content_length', parseInt(contentLength));
|
|
15469
|
+
}
|
|
15470
|
+
// Log response body for both success and error responses
|
|
15471
|
+
if (config.logResponseBody) {
|
|
15446
15472
|
try {
|
|
15447
|
-
|
|
15448
|
-
if (
|
|
15449
|
-
|
|
15473
|
+
// Only read responseText if responseType allows it
|
|
15474
|
+
if (xhr.responseType === '' || xhr.responseType === 'text') {
|
|
15475
|
+
const responseData = xhr.responseText;
|
|
15476
|
+
const truncatedData = truncateBody(responseData, config.maxBodyLogSize);
|
|
15477
|
+
span.setAttribute('response.data', truncatedData);
|
|
15478
|
+
// If content-length header is not available, calculate from response data
|
|
15479
|
+
if (!contentLength) {
|
|
15480
|
+
span.setAttribute('http.response_content_length', responseData.length);
|
|
15481
|
+
}
|
|
15482
|
+
// Try to parse JSON and extract message if exists
|
|
15483
|
+
try {
|
|
15484
|
+
const jsonData = JSON.parse(responseData);
|
|
15485
|
+
if (jsonData.message) {
|
|
15486
|
+
span.setAttribute('response.message', jsonData.message);
|
|
15487
|
+
}
|
|
15488
|
+
// Also log error details if present
|
|
15489
|
+
if (jsonData.errors) {
|
|
15490
|
+
span.setAttribute('response.errors', JSON.stringify(jsonData.errors));
|
|
15491
|
+
}
|
|
15492
|
+
if (jsonData.status !== undefined) {
|
|
15493
|
+
span.setAttribute('response.status', jsonData.status);
|
|
15494
|
+
}
|
|
15495
|
+
if (jsonData.status_code !== undefined) {
|
|
15496
|
+
span.setAttribute('response.status_code', jsonData.status_code);
|
|
15497
|
+
}
|
|
15498
|
+
}
|
|
15499
|
+
catch (e) {
|
|
15500
|
+
// Not JSON or no message field, ignore
|
|
15501
|
+
}
|
|
15502
|
+
if (config.enableConsoleLog) {
|
|
15503
|
+
if (xhr.status >= 200 && xhr.status < 300) {
|
|
15504
|
+
console.log(`[SignOz] ${method} Response from ${url} (${xhr.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
|
|
15505
|
+
}
|
|
15506
|
+
else {
|
|
15507
|
+
console.error(`[SignOz] ${method} Error Response from ${url} (${xhr.status}) on page ${pagePath} [${Math.round(duration)}ms]:`, truncatedData);
|
|
15508
|
+
}
|
|
15509
|
+
}
|
|
15510
|
+
}
|
|
15511
|
+
else {
|
|
15512
|
+
// For other response types (blob, arraybuffer, etc), just log the type
|
|
15513
|
+
span.setAttribute('response.data', `[${xhr.responseType} data]`);
|
|
15514
|
+
span.setAttribute('response.type', xhr.responseType);
|
|
15515
|
+
if (config.enableConsoleLog) {
|
|
15516
|
+
console.log(`[SignOz] ${method} Response from ${url} (${xhr.status}) on page ${pagePath} [${Math.round(duration)}ms]: [${xhr.responseType} data]`);
|
|
15517
|
+
}
|
|
15450
15518
|
}
|
|
15451
15519
|
}
|
|
15452
15520
|
catch (e) {
|
|
15453
|
-
//
|
|
15454
|
-
|
|
15455
|
-
|
|
15456
|
-
|
|
15521
|
+
// If there's an error reading response, log it
|
|
15522
|
+
span.setAttribute('response.data', '[Error reading response]');
|
|
15523
|
+
if (config.enableConsoleLog) {
|
|
15524
|
+
console.warn(`[SignOz] Failed to read response from ${url}:`, e);
|
|
15525
|
+
}
|
|
15457
15526
|
}
|
|
15458
15527
|
}
|
|
15459
15528
|
else if (xhr.status >= 300 && config.enableConsoleLog) {
|
|
15460
|
-
console.
|
|
15529
|
+
console.error(`[SignOz] ${method} Request to ${url} from page ${pagePath} - Status: ${xhr.status} [${Math.round(duration)}ms]`);
|
|
15461
15530
|
}
|
|
15462
15531
|
span.setStatus({ code: SpanStatusCode.OK });
|
|
15463
15532
|
span.end();
|
|
@@ -15490,9 +15559,15 @@ function addErrorTracking(enableConsoleLog = false) {
|
|
|
15490
15559
|
span.setAttribute('error.filename', event.filename || 'unknown');
|
|
15491
15560
|
span.setAttribute('error.lineno', event.lineno || 0);
|
|
15492
15561
|
span.setAttribute('error.colno', event.colno || 0);
|
|
15562
|
+
// Add page context
|
|
15563
|
+
span.setAttribute('page.url', window.location.href);
|
|
15564
|
+
span.setAttribute('page.pathname', window.location.pathname);
|
|
15565
|
+
span.setAttribute('page.search', window.location.search);
|
|
15566
|
+
span.setAttribute('page.hash', window.location.hash);
|
|
15493
15567
|
if (event.error) {
|
|
15494
15568
|
span.recordException(event.error);
|
|
15495
15569
|
span.setAttribute('error.stack', event.error.stack || '');
|
|
15570
|
+
span.setAttribute('error.name', event.error.name || 'Error');
|
|
15496
15571
|
}
|
|
15497
15572
|
span.setStatus({ code: SpanStatusCode.ERROR, message: event.message });
|
|
15498
15573
|
if (enableConsoleLog) {
|
|
@@ -15501,28 +15576,93 @@ function addErrorTracking(enableConsoleLog = false) {
|
|
|
15501
15576
|
filename: event.filename,
|
|
15502
15577
|
lineno: event.lineno,
|
|
15503
15578
|
colno: event.colno,
|
|
15504
|
-
stack: (_a = event.error) === null || _a === void 0 ? void 0 : _a.stack
|
|
15579
|
+
stack: (_a = event.error) === null || _a === void 0 ? void 0 : _a.stack,
|
|
15580
|
+
page: window.location.pathname
|
|
15505
15581
|
});
|
|
15506
15582
|
}
|
|
15507
15583
|
span.end();
|
|
15508
|
-
});
|
|
15584
|
+
}, true); // Use capture phase to catch errors early
|
|
15509
15585
|
// Track unhandled promise rejections
|
|
15510
15586
|
window.addEventListener('unhandledrejection', (event) => {
|
|
15511
15587
|
const tracer = trace.getTracer('error-tracker');
|
|
15512
15588
|
const span = tracer.startSpan('Unhandled Promise Rejection');
|
|
15513
15589
|
span.setAttribute('error.type', 'unhandled_rejection');
|
|
15514
15590
|
span.setAttribute('error.reason', String(event.reason));
|
|
15591
|
+
// Add page context
|
|
15592
|
+
span.setAttribute('page.url', window.location.href);
|
|
15593
|
+
span.setAttribute('page.pathname', window.location.pathname);
|
|
15594
|
+
span.setAttribute('page.search', window.location.search);
|
|
15595
|
+
span.setAttribute('page.hash', window.location.hash);
|
|
15515
15596
|
if (event.reason instanceof Error) {
|
|
15516
15597
|
span.recordException(event.reason);
|
|
15517
15598
|
span.setAttribute('error.message', event.reason.message);
|
|
15518
15599
|
span.setAttribute('error.stack', event.reason.stack || '');
|
|
15600
|
+
span.setAttribute('error.name', event.reason.name || 'Error');
|
|
15519
15601
|
}
|
|
15520
15602
|
span.setStatus({ code: SpanStatusCode.ERROR, message: String(event.reason) });
|
|
15521
15603
|
if (enableConsoleLog) {
|
|
15522
|
-
console.error('[SignOz] Unhandled Promise Rejection:', event.reason);
|
|
15604
|
+
console.error('[SignOz] Unhandled Promise Rejection:', event.reason, 'on page', window.location.pathname);
|
|
15523
15605
|
}
|
|
15524
15606
|
span.end();
|
|
15525
15607
|
});
|
|
15608
|
+
// Track Zone.js errors (for Angular/React with zone.js)
|
|
15609
|
+
if (typeof Zone !== 'undefined' && Zone.current) {
|
|
15610
|
+
const currentZone = Zone.current;
|
|
15611
|
+
const originalHandleError = currentZone.handleError;
|
|
15612
|
+
if (originalHandleError) {
|
|
15613
|
+
currentZone.handleError = function (error) {
|
|
15614
|
+
const tracer = trace.getTracer('error-tracker');
|
|
15615
|
+
const span = tracer.startSpan('Zone.js Error');
|
|
15616
|
+
span.setAttribute('error.type', 'zone_error');
|
|
15617
|
+
span.setAttribute('error.message', error.message || String(error));
|
|
15618
|
+
span.setAttribute('error.name', error.name || 'Error');
|
|
15619
|
+
// Add page context
|
|
15620
|
+
span.setAttribute('page.url', window.location.href);
|
|
15621
|
+
span.setAttribute('page.pathname', window.location.pathname);
|
|
15622
|
+
span.setAttribute('page.search', window.location.search);
|
|
15623
|
+
span.setAttribute('page.hash', window.location.hash);
|
|
15624
|
+
if (error.stack) {
|
|
15625
|
+
span.setAttribute('error.stack', error.stack);
|
|
15626
|
+
}
|
|
15627
|
+
span.recordException(error);
|
|
15628
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message || String(error) });
|
|
15629
|
+
if (enableConsoleLog) {
|
|
15630
|
+
console.error('[SignOz] Zone.js Error:', error, 'on page', window.location.pathname);
|
|
15631
|
+
}
|
|
15632
|
+
span.end();
|
|
15633
|
+
// Call original handler
|
|
15634
|
+
return originalHandleError.call(currentZone, error);
|
|
15635
|
+
};
|
|
15636
|
+
}
|
|
15637
|
+
}
|
|
15638
|
+
// Override console.error to catch React errors
|
|
15639
|
+
const originalConsoleError = console.error;
|
|
15640
|
+
console.error = function (...args) {
|
|
15641
|
+
// Check if this is a React error
|
|
15642
|
+
const errorMessage = args.map(arg => String(arg)).join(' ');
|
|
15643
|
+
if (errorMessage.includes('React') || errorMessage.includes('TypeError') || errorMessage.includes('Uncaught')) {
|
|
15644
|
+
const tracer = trace.getTracer('error-tracker');
|
|
15645
|
+
const span = tracer.startSpan('Console Error');
|
|
15646
|
+
span.setAttribute('error.type', 'console_error');
|
|
15647
|
+
span.setAttribute('error.message', errorMessage);
|
|
15648
|
+
// Add page context
|
|
15649
|
+
span.setAttribute('page.url', window.location.href);
|
|
15650
|
+
span.setAttribute('page.pathname', window.location.pathname);
|
|
15651
|
+
span.setAttribute('page.search', window.location.search);
|
|
15652
|
+
span.setAttribute('page.hash', window.location.hash);
|
|
15653
|
+
// Try to extract stack trace
|
|
15654
|
+
const errorObj = args.find(arg => arg instanceof Error);
|
|
15655
|
+
if (errorObj) {
|
|
15656
|
+
span.recordException(errorObj);
|
|
15657
|
+
span.setAttribute('error.stack', errorObj.stack || '');
|
|
15658
|
+
span.setAttribute('error.name', errorObj.name || 'Error');
|
|
15659
|
+
}
|
|
15660
|
+
span.setStatus({ code: SpanStatusCode.ERROR, message: errorMessage });
|
|
15661
|
+
span.end();
|
|
15662
|
+
}
|
|
15663
|
+
// Call original console.error
|
|
15664
|
+
return originalConsoleError.apply(console, args);
|
|
15665
|
+
};
|
|
15526
15666
|
}
|
|
15527
15667
|
// Fungsi untuk menambahkan navigation tracking
|
|
15528
15668
|
function addNavigationTracking(enableConsoleLog = false) {
|
|
@@ -16085,17 +16225,6 @@ function hasArrayChanged() {
|
|
|
16085
16225
|
}
|
|
16086
16226
|
|
|
16087
16227
|
const DefaultErrorFallback = ({ error, resetErrorBoundary }) => {
|
|
16088
|
-
const serviceName = window.REACT_APP_SIGNOZ_SERVICE_NAME || 'react-app';
|
|
16089
|
-
const tracer = trace.getTracer(serviceName);
|
|
16090
|
-
const span = tracer.startSpan(serviceName + ".error");
|
|
16091
|
-
React2__default.useEffect(() => {
|
|
16092
|
-
span.setAttribute('error.message', error.message);
|
|
16093
|
-
span.setAttribute('error.stack', JSON.stringify(error.stack));
|
|
16094
|
-
span.setAttribute('error.name', error.name);
|
|
16095
|
-
span.recordException(error);
|
|
16096
|
-
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
|
|
16097
|
-
span.end();
|
|
16098
|
-
}, [error, span]);
|
|
16099
16228
|
return (jsxs("div", { role: "alert", className: "error-boundary-fallback", children: [jsx("h1", { children: "Oops!" }), jsx("p", { children: "Terjadi kesalahan yang tidak terduga." }), jsx("p", { children: jsx("i", { children: error.statusText || error.message }) }), jsx("button", { onClick: resetErrorBoundary, children: "Coba lagi" })] }));
|
|
16100
16229
|
};
|
|
16101
16230
|
const ErrorBoundary = ({ children, fallback: FallbackComponent, onError, onReset, showResetButton = true, resetButtonText = "Coba lagi", fallbackClassName = "", }) => {
|
|
@@ -16104,10 +16233,16 @@ const ErrorBoundary = ({ children, fallback: FallbackComponent, onError, onReset
|
|
|
16104
16233
|
const serviceName = window.REACT_APP_SIGNOZ_SERVICE_NAME || 'react-app';
|
|
16105
16234
|
const tracer = trace.getTracer(serviceName);
|
|
16106
16235
|
const span = tracer.startSpan(serviceName + ".error");
|
|
16236
|
+
span.setAttribute('error.type', 'react_error_boundary');
|
|
16107
16237
|
span.setAttribute('error.message', error.message);
|
|
16108
|
-
span.setAttribute('error.stack',
|
|
16238
|
+
span.setAttribute('error.stack', error.stack || '');
|
|
16109
16239
|
span.setAttribute('error.name', error.name);
|
|
16110
16240
|
span.setAttribute('error.componentStack', errorInfo.componentStack || '');
|
|
16241
|
+
// Add page context
|
|
16242
|
+
span.setAttribute('page.url', window.location.href);
|
|
16243
|
+
span.setAttribute('page.pathname', window.location.pathname);
|
|
16244
|
+
span.setAttribute('page.search', window.location.search);
|
|
16245
|
+
span.setAttribute('page.hash', window.location.hash);
|
|
16111
16246
|
span.recordException(error);
|
|
16112
16247
|
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
|
|
16113
16248
|
span.end();
|