@echoteam/signoz-react
Version:
SignOz React JS - Library untuk monitoring dan tracing aplikasi React menggunakan OpenTelemetry dan SignOz
652 lines (541 loc) • 21.9 kB
Markdown
# @echoteam/signoz-react
Library React untuk monitoring dan tracing aplikasi menggunakan OpenTelemetry dan SignOz.
## 🚀 Fitur
- **Tracing Otomatis**: Integrasi OpenTelemetry untuk tracing HTTP requests, fetch, dan XMLHttpRequest
- **Request/Response Logging**: Otomatis melog data request dan response untuk debugging dan monitoring
- Log GET request dengan response data
- Log POST/PUT/PATCH request dengan request body dan response data
- **Log halaman frontend (page URL)** yang melakukan request
- Konfigurasi maksimal ukuran body yang di-log
- Data tersimpan di span attributes SignOz
- **Error Tracking**: Otomatis menangkap dan melog unhandled errors dan promise rejections
- Track JavaScript errors dengan stack trace
- Track unhandled promise rejections
- Error details tersimpan di SignOz untuk analisis
- **Navigation Tracking**: Track route changes dan page navigation
- Track initial page load
- Track SPA navigation (pushState/replaceState)
- Track browser back/forward (popstate)
- Navigation history tersimpan di SignOz
- **Document Load Performance**: Track page load performance metrics
- First Paint, First Contentful Paint
- DOM Content Loaded, Load Complete
- Resource timing
- **WebSocket Logging**: Otomatis track WebSocket connections dan messages
- Track connection open, close, error
- Log messages sent dan received
- Extract message type dan text dari JSON
- Connection duration tracking
- Data tersimpan di SignOz span attributes
- **No Click Tracking**: User interaction (click events) tidak di-track untuk privacy dan performa
- **Error Boundary**: Komponen React untuk menangkap dan melaporkan error dengan tracing
- **Error Page**: Halaman error untuk React Router dengan integrasi tracing
- **TypeScript Support**: Dukungan penuh untuk TypeScript
- **Zero Configuration**: Mudah digunakan dengan environment variables
- **Customizable**: ErrorPage dan ErrorBoundary dapat dikustomisasi sesuai kebutuhan
## 📚 Dokumentasi
- [Konfigurasi CORS Backend](./BACKEND_CORS_SETUP.md) - Panduan lengkap setup CORS di berbagai framework backend
- [Troubleshooting](./TROUBLESHOOTING.md) - Solusi untuk masalah umum
- [OpenTelemetry Documentation](https://opentelemetry.io/docs/)
- [React Error Boundary](https://reactjs.org/docs/error-boundaries.html)
## 📦 Instalasi
```bash
yarn add @echoteam/signoz-react
npm install @echoteam/signoz-react
```
## 🔧 Konfigurasi
### Environment Variables
Tambahkan environment variables berikut ke file `.env`:
```env
REACT_APP_SIGNOZ_SERVICE_NAME=my-react-app
REACT_APP_SIGNOZ_SERVICE_VERSION=1.0.0
REACT_APP_SIGNOZ_ENV=production
REACT_APP_SIGNOZ_SERVICE_NAMESPACE=frontend
REACT_APP_SIGNOZ_URL=https://your-signoz-instance.com/v1/traces
REACT_APP_SIGNOZ_TRACE_SAMPLE_RATE=1.0
REACT_APP_SIGNOZ_ALLOWED_ORIGINS=https://api1.example.com,https://api2.example.com,/^https:\/\/.*\.your-domain\.com$/
# Konfigurasi Request/Response Logging (opsional)
REACT_APP_SIGNOZ_ENABLE_REQUEST_LOGGING=true
REACT_APP_SIGNOZ_LOG_REQUEST_BODY=true
REACT_APP_SIGNOZ_LOG_RESPONSE_BODY=true
REACT_APP_SIGNOZ_MAX_BODY_LOG_SIZE=10000
# Konfigurasi Tracking (opsional)
REACT_APP_SIGNOZ_ENABLE_DOCUMENT_LOAD=false # default: false
REACT_APP_SIGNOZ_ENABLE_ERROR_TRACKING=true # default: true
REACT_APP_SIGNOZ_ENABLE_NAVIGATION_TRACKING=false # default: false
# WebSocket Logging (opsional, default: false)
REACT_APP_SIGNOZ_ENABLE_WEBSOCKET_LOGGING=false
REACT_APP_SIGNOZ_LOG_WEBSOCKET_MESSAGES=false
# Console Logging (opsional, default: false)
REACT_APP_SIGNOZ_ENABLE_CONSOLE_LOG=false
```
> **Catatan untuk REACT_APP_SIGNOZ_ALLOWED_ORIGINS:**
> - Daftar URL yang diizinkan untuk CORS, dipisahkan dengan koma
> - Untuk RegExp pattern, gunakan format `/pattern/` (contoh: `/^https:\/\/.*\.example\.com$/`)
> - Gunakan '*' untuk mengizinkan semua origin
> - Jika tidak diisi, default ke '*' (mengizinkan semua origin)
> - Spasi di sekitar koma akan dihapus otomatis
> **Catatan untuk Request/Response Logging:**
> - `REACT_APP_SIGNOZ_ENABLE_REQUEST_LOGGING`: Aktifkan/nonaktifkan logging request/response (default: true)
> - `REACT_APP_SIGNOZ_LOG_REQUEST_BODY`: Log body untuk POST/PUT/PATCH request (default: true)
> - `REACT_APP_SIGNOZ_LOG_RESPONSE_BODY`: Log response body untuk semua request (default: true)
> - `REACT_APP_SIGNOZ_MAX_BODY_LOG_SIZE`: Maksimal ukuran body yang di-log dalam bytes (default: 10000)
> - Data akan di-log ke console browser dan dikirim sebagai span attributes ke SignOz
### Inisialisasi
```typescript
import { initializeSignOzTracing } from '@echoteam/signoz-react';
// Inisialisasi dengan environment variables
initializeSignOzTracing();
// Atau dengan konfigurasi manual
// Inisialisasi dengan konfigurasi minimal
initializeSignOzTracing({
serviceName: 'my-app',
serviceVersion: '1.0.0',
environment: 'production',
serviceNamespace: 'default',
url: 'https://api.signoz.io/v1/traces'
});
// Inisialisasi dengan konfigurasi lengkap
initializeSignOzTracing({
serviceName: 'my-app',
serviceVersion: '1.0.0',
environment: 'production',
serviceNamespace: 'default',
url: 'https://api.signoz.io/v1/traces',
headers: {
'X-API-Key': 'your-api-key'
},
traceSampleRate: 0.5, // Sampling 50% trace
batchSpanProcessorConfig: {
maxQueueSize: 100,
scheduledDelayMillis: 5000,
exportTimeoutMillis: 30000
},
allowedOrigins: [
'https://api.example.com',
/^https:\/\/.*\.your-domain\.com$/,
'*' // Mengizinkan semua origin (default)
],
// Konfigurasi logging request/response
enableRequestLogging: true, // Aktifkan logging (default: true)
logRequestBody: true, // Log request body untuk POST/PUT/PATCH (default: true)
logResponseBody: true, // Log response body (default: true)
maxBodyLogSize: 10000, // Maksimal 10KB per log (default: 10000)
// Konfigurasi tracking
enableDocumentLoad: false, // Track page load performance (default: false)
enableErrorTracking: true, // Track unhandled errors (default: true)
enableNavigationTracking: false, // Track route changes (default: false)
// WebSocket logging (default: false)
enableWebSocketLogging: false, // Track WebSocket connections and messages
logWebSocketMessages: false, // Log WebSocket message content
// Console logging (default: false, hanya kirim ke SignOz tanpa console.log)
enableConsoleLog: false // Set true untuk enable console.log di browser
});
```
## 🎯 Penggunaan
### Request/Response Logging
Library ini secara otomatis melog semua HTTP request dan response yang dilakukan melalui `fetch` atau `XMLHttpRequest`. Data yang di-log meliputi:
**Untuk GET Request:**
- URL endpoint
- HTTP method
- Status code response
- Response body (jika `logResponseBody: true`)
- **URL halaman frontend** yang melakukan request (page.url, page.pathname)
**Untuk POST/PUT/PATCH Request:**
- URL endpoint
- HTTP method
- Request body (jika `logRequestBody: true`)
- Status code response
- Response body (jika `logResponseBody: true`)
- **URL halaman frontend** yang melakukan request (page.url, page.pathname)
**Contoh Output di Console:**
```
[SignOz] GET Response from https://api.example.com/users (200) on page /dashboard: {"users":[{"id":1,"name":"John"}]}
[SignOz] POST Request to https://api.example.com/users from page /users/create: {"name":"Jane","email":"jane@example.com"}
[SignOz] POST Response from https://api.example.com/users (201) on page /users/create: {"id":2,"name":"Jane","email":"jane@example.com"}
```
**Melihat Data di SignOz Dashboard:**
1. Buka SignOz dashboard
2. Navigasi ke **Traces**
3. Pilih trace yang ingin dilihat
4. Lihat span attributes:
- `http.request.body`: Body dari request (untuk POST/PUT/PATCH)
- `response.data`: Body dari response
- `response.message`: Message dari response JSON (jika ada field `message`)
- `http.url`: URL endpoint
- `http.method`: HTTP method
- `http.status_code`: Status code response
- `http.response_content_length`: Ukuran response dalam bytes
- `duration_ms`: Durasi request dalam milliseconds
- `page.url`: URL halaman frontend yang melakukan request
- `page.pathname`: Pathname halaman frontend
- `page.search`: Query parameters halaman frontend
- `page.hash`: Hash fragment halaman frontend
**Menonaktifkan Logging:**
```typescript
// Nonaktifkan semua logging
initializeSignOzTracing({
// ... konfigurasi lainnya
enableRequestLogging: false
});
// Atau hanya nonaktifkan logging body tertentu
initializeSignOzTracing({
// ... konfigurasi lainnya
enableRequestLogging: true,
logRequestBody: false, // Tidak log request body
logResponseBody: true // Tetap log response body
});
```
### Error Tracking
Library ini otomatis menangkap dan melog semua unhandled errors dan promise rejections.
**Contoh Output di Console:**
```
[SignOz] Unhandled Error: {
message: "Cannot read property 'foo' of undefined",
filename: "app.js",
lineno: 42,
colno: 15,
stack: "TypeError: Cannot read property 'foo' of undefined\n at App.js:42:15"
}
[SignOz] Unhandled Promise Rejection: Error: API call failed
```
**Data yang Di-track:**
- Error message
- Stack trace
- Filename dan line number
- Error type (unhandled error atau promise rejection)
**Melihat di SignOz:**
1. Navigasi ke **Traces**
2. Filter by span name: "Unhandled Error" atau "Unhandled Promise Rejection"
3. Lihat span attributes:
- `error.type`: Tipe error
- `error.message`: Pesan error
- `error.stack`: Stack trace
- `error.filename`: File yang error
- `error.lineno`: Line number
**Menonaktifkan Error Tracking:**
```typescript
initializeSignOzTracing({
// ... konfigurasi lainnya
enableErrorTracking: false
});
```
### Navigation Tracking
Library ini otomatis track semua route changes dan page navigation.
**Contoh Output di Console:**
```
[SignOz] Page Load: { url: "https://example.com/", pathname: "/" }
[SignOz] Navigation (pushState): { from: "/", to: "/users", pathname: "/users" }
[SignOz] Navigation (popstate): { from: "/users", to: "/", pathname: "/" }
```
**Data yang Di-track:**
- Initial page load
- SPA navigation (React Router, etc)
- Browser back/forward navigation
- URL, pathname, search params, hash
**Melihat di SignOz:**
1. Navigasi ke **Traces**
2. Filter by span name: "Page Load" atau "Navigation"
3. Lihat span attributes:
- `navigation.type`: Tipe navigasi (initial, pushState, replaceState, popstate)
- `navigation.from`: URL sebelumnya
- `navigation.to`: URL tujuan
- `navigation.pathname`: Pathname
- `navigation.search`: Query parameters
- `navigation.hash`: Hash fragment
**Menonaktifkan Navigation Tracking:**
```typescript
initializeSignOzTracing({
// ... konfigurasi lainnya
enableNavigationTracking: false
});
```
### Document Load Performance
Library ini otomatis track page load performance metrics menggunakan Navigation Timing API.
**Metrics yang Di-track:**
- First Paint (FP)
- First Contentful Paint (FCP)
- DOM Content Loaded
- Load Complete
- Resource timing (CSS, JS, images, etc)
**Melihat di SignOz:**
1. Navigasi ke **Traces**
2. Filter by span name: "documentLoad" atau "documentFetch"
3. Lihat metrics untuk page load performance
**Menonaktifkan Document Load Tracking:**
```typescript
initializeSignOzTracing({
// ... konfigurasi lainnya
enableDocumentLoad: false
});
```
### WebSocket Logging
Library ini otomatis track semua WebSocket connections dan messages.
**Contoh Output di Console:**
```
[SignOz] WebSocket Connected to wss://api.example.com/ws from page /dashboard [45ms]
[SignOz] WebSocket Send to wss://api.example.com/ws from page /dashboard: {"type":"subscribe","channel":"updates"}
[SignOz] WebSocket Receive from wss://api.example.com/ws on page /dashboard: {"type":"message","data":"Hello"}
[SignOz] WebSocket Closed wss://api.example.com/ws on page /dashboard - Code: 1000, Reason: Normal closure, Clean: true
```
**Data yang Di-track:**
- WebSocket connection (open, close, error)
- Connection duration
- Messages sent (dengan content)
- Messages received (dengan content)
- Close code dan reason
- URL halaman frontend yang membuat connection
- Message type (jika ada field `type` atau `event` di JSON)
- Message text (jika ada field `message` di JSON)
**Melihat di SignOz:**
1. Navigasi ke **Traces**
2. Filter by span name: "WebSocket Connection", "WebSocket Send", "WebSocket Receive", "WebSocket Close", atau "WebSocket Error"
3. Lihat span attributes:
- `websocket.url`: URL WebSocket
- `websocket.protocols`: Protocols yang digunakan
- `websocket.state`: State connection (open, closed, error)
- `websocket.direction`: Arah message (send/receive)
- `websocket.message`: Content message
- `websocket.message.type`: Tipe message (jika ada)
- `websocket.message.text`: Text message (jika ada field `message`)
- `response.data`: Data yang diterima dari WebSocket (untuk receive messages)
- `response.message`: Message yang diterima (jika ada field `message` di JSON)
- `websocket.close.code`: Close code
- `websocket.close.reason`: Alasan close
- `websocket.close.wasClean`: Apakah close dengan clean
- `duration_ms`: Durasi connection
- `page.url`: URL halaman frontend
- `page.pathname`: Pathname halaman frontend
**Mengaktifkan WebSocket Logging:**
```typescript
// WebSocket logging disabled by default
// Untuk mengaktifkan:
initializeSignOzTracing({
// ... konfigurasi lainnya
enableWebSocketLogging: true,
logWebSocketMessages: true // Enable message logging
});
// Atau hanya track connection tanpa log messages
initializeSignOzTracing({
// ... konfigurasi lainnya
enableWebSocketLogging: true,
logWebSocketMessages: false // Hanya track connection, tidak log messages
});
```
### Error Boundary
#### Penggunaan Dasar
```tsx
import { ErrorBoundary } from '@echoteam/signoz-react';
function App() {
return (
<ErrorBoundary>
<YourApp />
</ErrorBoundary>
);
}
```
#### Error Boundary dengan Kustomisasi
```tsx
import { ErrorBoundary, ErrorBoundaryProps } from '@echoteam/signoz-react';
// Custom fallback component
const CustomErrorFallback: React.FC<{ error: Error; resetErrorBoundary: () => void }> = ({
error,
resetErrorBoundary
}) => (
<div className="custom-error">
<h2>Terjadi Kesalahan!</h2>
<p>{error.message}</p>
<button onClick={resetErrorBoundary}>Coba Lagi</button>
</div>
);
function App() {
const handleError = (error: Error, errorInfo: React.ErrorInfo) => {
console.log('Error caught:', error);
// Kirim ke service lain jika diperlukan
};
return (
<ErrorBoundary
fallback={CustomErrorFallback}
onError={handleError}
onReset={() => console.log('Error boundary reset')}
fallbackClassName="my-error-boundary"
>
<YourApp />
</ErrorBoundary>
);
}
```
### Error Page untuk React Router
#### Penggunaan Dasar
```tsx
import { ErrorPage } from '@echoteam/signoz-react';
import { createBrowserRouter } from 'react-router-dom';
const router = createBrowserRouter([
{
path: "/",
element: <Root />,
errorElement: <ErrorPage />,
},
]);
```
#### Error Page dengan Kustomisasi
```tsx
import { ErrorPage, ErrorPageProps } from '@echoteam/signoz-react';
// Custom error page
const CustomErrorPage: React.FC<ErrorPageProps> = (props) => (
<ErrorPage
title="Halaman Tidak Ditemukan"
message="Maaf, halaman yang Anda cari tidak tersedia."
showStackTrace={process.env.NODE_ENV === 'development'}
actionButton={
<button onClick={() => window.history.back()}>
Kembali ke Halaman Sebelumnya
</button>
}
className="custom-error-page"
/>
);
// Atau dengan custom render function
const CustomErrorPageWithRender: React.FC<ErrorPageProps> = () => (
<ErrorPage
renderError={(error) => (
<div className="my-custom-error">
<h1>🚨 Error!</h1>
<p>Kode Error: {error.name}</p>
<p>Pesan: {error.message}</p>
<button onClick={() => window.location.href = '/'}>
Kembali ke Beranda
</button>
</div>
)}
/>
);
const router = createBrowserRouter([
{
path: "/",
element: <Root />,
errorElement: <CustomErrorPage />,
},
]);
```
### Tracing Manual
```typescript
import { trace } from '@opentelemetry/api';
const tracer = trace.getTracer('my-service');
const span = tracer.startSpan('my-operation');
try {
// Lakukan operasi
span.setAttribute('operation.type', 'database-query');
span.setAttribute('operation.result', 'success');
} catch (error) {
span.recordException(error);
span.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
} finally {
span.end();
}
```
## 📋 API Reference
### `initializeSignOzTracing(config?)`
Inisialisasi SignOz tracing untuk aplikasi React.
**Parameter:**
- `config` (opsional): Konfigurasi SignOz
- `serviceName`: Nama layanan
- `serviceVersion`: Versi layanan
- `environment`: Environment (production, staging, development)
- `serviceNamespace`: Namespace layanan
- `url`: URL endpoint SignOz
- `headers` (opsional): Header tambahan untuk request
- `traceSampleRate` (opsional): Rate sampling trace (0-1, default: 1.0)
- `batchSpanProcessorConfig` (opsional): Konfigurasi batch processor
- `maxQueueSize`: Ukuran maksimum antrian span
- `scheduledDelayMillis`: Delay pengiriman batch dalam milidetik
- `exportTimeoutMillis`: Timeout ekspor dalam milidetik
- `allowedOrigins` (wajib): Array URL/RegExp yang diizinkan untuk CORS. Gunakan ['*'] untuk mengizinkan semua origin
- `enableRequestLogging` (opsional): Aktifkan logging request/response (default: true)
- `logRequestBody` (opsional): Log request body untuk POST/PUT/PATCH (default: true)
- `logResponseBody` (opsional): Log response body untuk semua request (default: true)
- `maxBodyLogSize` (opsional): Maksimal ukuran body yang di-log dalam bytes (default: 10000)
- `enableDocumentLoad` (opsional): Aktifkan document load instrumentation (default: false)
- `enableErrorTracking` (opsional): Aktifkan automatic error tracking (default: true)
- `enableNavigationTracking` (opsional): Aktifkan navigation/route tracking (default: false)
- `enableConsoleLog` (opsional): Aktifkan console.log output di browser (default: false)
- `enableWebSocketLogging` (opsional): Aktifkan WebSocket connection dan message tracking (default: false)
- `logWebSocketMessages` (opsional): Log WebSocket message content (default: false)
### `ErrorBoundary`
Komponen React untuk menangkap error dan melaporkan ke SignOz.
**Props:**
- `children`: React children
- `fallback`: Custom fallback component
- `onError`: Custom error handler function
- `onReset`: Custom reset handler
- `showResetButton`: Apakah menampilkan reset button (default: true)
- `resetButtonText`: Custom reset button text
- `fallbackClassName`: Custom CSS class untuk fallback
### `ErrorPage`
Komponen halaman error untuk React Router.
**Props:**
- `title`: Judul halaman error (default: "Oops!")
- `message`: Pesan error utama (default: "Terjadi kesalahan yang tidak terduga.")
- `renderError`: Custom render function untuk menampilkan error
- `className`: Custom CSS class untuk container
- `showStackTrace`: Apakah menampilkan stack trace (default: false)
- `actionButton`: Custom action button
## 🔍 Monitoring
Setelah setup, Anda dapat melihat traces di dashboard SignOz:
1. **Service Overview**: Melihat performa layanan secara keseluruhan
2. **Traces**: Melihat detail traces untuk setiap request
3. **Errors**: Melihat error yang terjadi dengan stack trace
4. **Metrics**: Melihat metrics performa aplikasi
## 🚨 Troubleshooting
### Error: Can't resolve 'perf_hooks'
Jika Anda mendapatkan error seperti ini:
```
ERROR in ./node_modules/@echoteam/signoz-react/dist/index.esm.js 1:0-58
Module not found: Error: Can't resolve 'perf_hooks' in '/path/to/node_modules/@echoteam/signoz-react/dist'
```
**Solusi:**
Library ini sudah diperbaiki untuk menangani masalah ini. Pastikan Anda menggunakan versi terbaru:
```bash
yarn add @echoteam/signoz-react@latest
```
Jika masih mengalami masalah, lihat [TROUBLESHOOTING.md](TROUBLESHOOTING.md) untuk solusi lengkap berdasarkan bundler yang Anda gunakan (Webpack, Vite, Create React App).
### Masalah Umum Lainnya
1. **Environment Variables Tidak Terdeteksi**: Pastikan semua environment variables sudah dikonfigurasi dengan benar
2. **CORS Error**: Pastikan URL SignOz dapat diakses dari domain aplikasi Anda
3. **Network Error**: Periksa koneksi internet dan firewall settings
Untuk informasi troubleshooting lebih lengkap, lihat [TROUBLESHOOTING.md](TROUBLESHOOTING.md).
## 🛠️ Development
### Setup Development
```bash
# Clone repository
git clone https://gitlab.echoteam.tech/codr/package/signoz-react-js.git
cd signoz-react-js
# Install dependencies
yarn install
# Build package
yarn build
# Development mode
yarn dev
```
### Scripts
- `yarn build`: Build package untuk production
- `yarn dev`: Build dalam mode development dengan watch
- `yarn test`: Jalankan tests
- `yarn lint`: Lint kode
- `yarn format`: Format kode dengan Prettier
## 📄 License
MIT License - lihat file [LICENSE](LICENSE) untuk detail.
## 🤝 Contributing
1. Fork repository
2. Buat feature branch (`git checkout -b feature/amazing-feature`)
3. Commit perubahan (`git commit -m 'Add amazing feature'`)
4. Push ke branch (`git push origin feature/amazing-feature`)
5. Buat Pull Request
## 📞 Support
- **Issues**: [GitLab Issues](https://gitlab.echoteam.tech/codr/package/signoz-react-js/-/issues)
- **Email**: dev@codr.id
- **Documentation**: [GitLab Wiki](https://gitlab.echoteam.tech/codr/package/signoz-react-js/-/wikis)
## 🔗 Links
- [SignOz Documentation](https://signoz.io/docs/)
- [OpenTelemetry Documentation](https://opentelemetry.io/docs/)
- [React Error Boundary](https://reactjs.org/docs/error-boundaries.html)