datadog-frontend-toolkit 1.0.0
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/LICENSE +21 -0
- package/README.md +486 -0
- package/dist/cjs/context/ContextManager.js +197 -0
- package/dist/cjs/context/ContextManager.js.map +1 -0
- package/dist/cjs/core/BootstrapGuard.js +81 -0
- package/dist/cjs/core/BootstrapGuard.js.map +1 -0
- package/dist/cjs/core/ConfigManager.js +133 -0
- package/dist/cjs/core/ConfigManager.js.map +1 -0
- package/dist/cjs/core/ObservabilitySDK.js +355 -0
- package/dist/cjs/core/ObservabilitySDK.js.map +1 -0
- package/dist/cjs/errors/ErrorBoundary.js +187 -0
- package/dist/cjs/errors/ErrorBoundary.js.map +1 -0
- package/dist/cjs/index.js +110 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/logger/LoggerService.js +256 -0
- package/dist/cjs/logger/LoggerService.js.map +1 -0
- package/dist/cjs/logs/LogsManager.js +112 -0
- package/dist/cjs/logs/LogsManager.js.map +1 -0
- package/dist/cjs/network/NetworkInterceptor.js +185 -0
- package/dist/cjs/network/NetworkInterceptor.js.map +1 -0
- package/dist/cjs/performance/PerformanceMonitor.js +290 -0
- package/dist/cjs/performance/PerformanceMonitor.js.map +1 -0
- package/dist/cjs/resources/ResourceProvisioner.js +210 -0
- package/dist/cjs/resources/ResourceProvisioner.js.map +1 -0
- package/dist/cjs/resources/templates/dashboard.js +333 -0
- package/dist/cjs/resources/templates/dashboard.js.map +1 -0
- package/dist/cjs/resources/templates/monitors.js +120 -0
- package/dist/cjs/resources/templates/monitors.js.map +1 -0
- package/dist/cjs/resources/templates/slos.js +79 -0
- package/dist/cjs/resources/templates/slos.js.map +1 -0
- package/dist/cjs/rum/RumManager.js +164 -0
- package/dist/cjs/rum/RumManager.js.map +1 -0
- package/dist/cjs/types/config.js +13 -0
- package/dist/cjs/types/config.js.map +1 -0
- package/dist/cjs/types/events.js +26 -0
- package/dist/cjs/types/events.js.map +1 -0
- package/dist/cjs/types/index.js +20 -0
- package/dist/cjs/types/index.js.map +1 -0
- package/dist/cjs/types/logger.js +13 -0
- package/dist/cjs/types/logger.js.map +1 -0
- package/dist/cjs/utils/EventEmitter.js +49 -0
- package/dist/cjs/utils/EventEmitter.js.map +1 -0
- package/dist/cjs/utils/fingerprint.js +48 -0
- package/dist/cjs/utils/fingerprint.js.map +1 -0
- package/dist/cjs/utils/retry.js +35 -0
- package/dist/cjs/utils/retry.js.map +1 -0
- package/dist/cjs/utils/sanitizer.js +106 -0
- package/dist/cjs/utils/sanitizer.js.map +1 -0
- package/dist/cjs/utils/storage.js +99 -0
- package/dist/cjs/utils/storage.js.map +1 -0
- package/dist/cli/commands/setup.js +178 -0
- package/dist/cli/commands/setup.js.map +1 -0
- package/dist/cli/commands/status.js +103 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/index.js +111 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/prompt.js +140 -0
- package/dist/cli/prompt.js.map +1 -0
- package/dist/esm/context/ContextManager.js +193 -0
- package/dist/esm/context/ContextManager.js.map +1 -0
- package/dist/esm/core/BootstrapGuard.js +77 -0
- package/dist/esm/core/BootstrapGuard.js.map +1 -0
- package/dist/esm/core/ConfigManager.js +129 -0
- package/dist/esm/core/ConfigManager.js.map +1 -0
- package/dist/esm/core/ObservabilitySDK.js +351 -0
- package/dist/esm/core/ObservabilitySDK.js.map +1 -0
- package/dist/esm/errors/ErrorBoundary.js +183 -0
- package/dist/esm/errors/ErrorBoundary.js.map +1 -0
- package/dist/esm/index.js +87 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/logger/LoggerService.js +251 -0
- package/dist/esm/logger/LoggerService.js.map +1 -0
- package/dist/esm/logs/LogsManager.js +108 -0
- package/dist/esm/logs/LogsManager.js.map +1 -0
- package/dist/esm/network/NetworkInterceptor.js +181 -0
- package/dist/esm/network/NetworkInterceptor.js.map +1 -0
- package/dist/esm/performance/PerformanceMonitor.js +286 -0
- package/dist/esm/performance/PerformanceMonitor.js.map +1 -0
- package/dist/esm/resources/ResourceProvisioner.js +206 -0
- package/dist/esm/resources/ResourceProvisioner.js.map +1 -0
- package/dist/esm/resources/templates/dashboard.js +330 -0
- package/dist/esm/resources/templates/dashboard.js.map +1 -0
- package/dist/esm/resources/templates/monitors.js +117 -0
- package/dist/esm/resources/templates/monitors.js.map +1 -0
- package/dist/esm/resources/templates/slos.js +76 -0
- package/dist/esm/resources/templates/slos.js.map +1 -0
- package/dist/esm/rum/RumManager.js +160 -0
- package/dist/esm/rum/RumManager.js.map +1 -0
- package/dist/esm/types/config.js +10 -0
- package/dist/esm/types/config.js.map +1 -0
- package/dist/esm/types/events.js +23 -0
- package/dist/esm/types/events.js.map +1 -0
- package/dist/esm/types/index.js +4 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/esm/types/logger.js +10 -0
- package/dist/esm/types/logger.js.map +1 -0
- package/dist/esm/utils/EventEmitter.js +45 -0
- package/dist/esm/utils/EventEmitter.js.map +1 -0
- package/dist/esm/utils/fingerprint.js +44 -0
- package/dist/esm/utils/fingerprint.js.map +1 -0
- package/dist/esm/utils/retry.js +32 -0
- package/dist/esm/utils/retry.js.map +1 -0
- package/dist/esm/utils/sanitizer.js +102 -0
- package/dist/esm/utils/sanitizer.js.map +1 -0
- package/dist/esm/utils/storage.js +95 -0
- package/dist/esm/utils/storage.js.map +1 -0
- package/dist/resources/ResourceProvisioner.js +207 -0
- package/dist/resources/ResourceProvisioner.js.map +1 -0
- package/dist/resources/templates/dashboard.js +333 -0
- package/dist/resources/templates/dashboard.js.map +1 -0
- package/dist/resources/templates/monitors.js +120 -0
- package/dist/resources/templates/monitors.js.map +1 -0
- package/dist/resources/templates/slos.js +79 -0
- package/dist/resources/templates/slos.js.map +1 -0
- package/dist/types/config.js +13 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/context/ContextManager.d.ts +63 -0
- package/dist/types/context/ContextManager.d.ts.map +1 -0
- package/dist/types/core/BootstrapGuard.d.ts +46 -0
- package/dist/types/core/BootstrapGuard.d.ts.map +1 -0
- package/dist/types/core/ConfigManager.d.ts +13 -0
- package/dist/types/core/ConfigManager.d.ts.map +1 -0
- package/dist/types/core/ObservabilitySDK.d.ts +141 -0
- package/dist/types/core/ObservabilitySDK.d.ts.map +1 -0
- package/dist/types/errors/ErrorBoundary.d.ts +55 -0
- package/dist/types/errors/ErrorBoundary.d.ts.map +1 -0
- package/dist/types/events.js +26 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/index.d.ts +75 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +20 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/logger/LoggerService.d.ts +104 -0
- package/dist/types/logger/LoggerService.d.ts.map +1 -0
- package/dist/types/logger.js +13 -0
- package/dist/types/logger.js.map +1 -0
- package/dist/types/logs/LogsManager.d.ts +41 -0
- package/dist/types/logs/LogsManager.d.ts.map +1 -0
- package/dist/types/network/NetworkInterceptor.d.ts +35 -0
- package/dist/types/network/NetworkInterceptor.d.ts.map +1 -0
- package/dist/types/performance/PerformanceMonitor.d.ts +44 -0
- package/dist/types/performance/PerformanceMonitor.d.ts.map +1 -0
- package/dist/types/resources/ResourceProvisioner.d.ts +46 -0
- package/dist/types/resources/ResourceProvisioner.d.ts.map +1 -0
- package/dist/types/resources/templates/dashboard.d.ts +6 -0
- package/dist/types/resources/templates/dashboard.d.ts.map +1 -0
- package/dist/types/resources/templates/monitors.d.ts +11 -0
- package/dist/types/resources/templates/monitors.d.ts.map +1 -0
- package/dist/types/resources/templates/slos.d.ts +18 -0
- package/dist/types/resources/templates/slos.d.ts.map +1 -0
- package/dist/types/rum/RumManager.d.ts +70 -0
- package/dist/types/rum/RumManager.d.ts.map +1 -0
- package/dist/types/types/config.d.ts +271 -0
- package/dist/types/types/config.d.ts.map +1 -0
- package/dist/types/types/events.d.ts +71 -0
- package/dist/types/types/events.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +4 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/types/types/logger.d.ts +102 -0
- package/dist/types/types/logger.d.ts.map +1 -0
- package/dist/types/utils/EventEmitter.d.ts +14 -0
- package/dist/types/utils/EventEmitter.d.ts.map +1 -0
- package/dist/types/utils/fingerprint.d.ts +10 -0
- package/dist/types/utils/fingerprint.d.ts.map +1 -0
- package/dist/types/utils/retry.d.ts +9 -0
- package/dist/types/utils/retry.d.ts.map +1 -0
- package/dist/types/utils/sanitizer.d.ts +14 -0
- package/dist/types/utils/sanitizer.d.ts.map +1 -0
- package/dist/types/utils/storage.d.ts +17 -0
- package/dist/types/utils/storage.d.ts.map +1 -0
- package/dist/utils/retry.js +35 -0
- package/dist/utils/retry.js.map +1 -0
- package/package.json +84 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
# datadog-frontend-toolkit
|
|
2
|
+
|
|
3
|
+
> Enterprise-grade, framework-agnostic frontend observability toolkit for Datadog.
|
|
4
|
+
|
|
5
|
+
One `init()` call to auto-instrument **RUM**, **Logs**, **Error Tracking**, **Performance Monitoring**, and auto-provision **Dashboards**, **Monitors** & **SLOs** in Datadog.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Zero-config observability** — single `init()` bootstraps everything
|
|
12
|
+
- **Framework agnostic** — works with React, Vue, Angular, Svelte, vanilla JS
|
|
13
|
+
- **Full TypeScript support** — complete type declarations and IntelliSense
|
|
14
|
+
- **Structured LoggerService** — `debug`, `info`, `warn`, `error`, `critical` with auto-forwarding to Datadog
|
|
15
|
+
- **Global Error Boundary** — catches unhandled errors + promise rejections automatically
|
|
16
|
+
- **Web Vitals tracking** — LCP, CLS, FID, INP, FCP, TTFB with threshold alerts
|
|
17
|
+
- **Network interception** — monitors XHR/Fetch for failures and slow requests
|
|
18
|
+
- **PII sanitization** — auto-redacts emails, credit cards, passwords from logs
|
|
19
|
+
- **Resource provisioning CLI** — auto-creates Dashboards, Monitors, and SLOs
|
|
20
|
+
- **Plugin system** — extend with custom integrations
|
|
21
|
+
- **Lifecycle hooks** — `beforeInit`, `afterInit`, `beforeLog`, `beforeError`
|
|
22
|
+
- **Child loggers** — scoped context for module-specific logging
|
|
23
|
+
- **Session replay** — configurable recording with privacy controls
|
|
24
|
+
- **Consent mode** — GDPR-friendly opt-in tracking
|
|
25
|
+
- **Retry with backoff** — resilient API communication
|
|
26
|
+
- **Throttling** — prevents log flooding during error storms
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Installation
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
npm install datadog-frontend-toolkit
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
> `@datadog/browser-rum` and `@datadog/browser-logs` are included as dependencies — no need to install them separately.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { init } from 'datadog-frontend-toolkit';
|
|
44
|
+
|
|
45
|
+
const observatory = init({
|
|
46
|
+
clientToken: 'pub-xxxxxxxxxxxxxxxxxxxx',
|
|
47
|
+
applicationId: 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx',
|
|
48
|
+
service: 'my-frontend-app',
|
|
49
|
+
env: 'production',
|
|
50
|
+
version: '1.2.3',
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// That's it! RUM, Logs, Error Tracking, and Performance Monitoring are now active.
|
|
54
|
+
|
|
55
|
+
// Use the logger anywhere
|
|
56
|
+
observatory.logger.info('Application started');
|
|
57
|
+
observatory.logger.error('Payment failed', new Error('timeout'), { orderId: 'abc-123' });
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## API Reference
|
|
63
|
+
|
|
64
|
+
### `init(config): ObservabilitySDK`
|
|
65
|
+
|
|
66
|
+
Initializes the SDK. Call once at application bootstrap.
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
import { init } from 'datadog-frontend-toolkit';
|
|
70
|
+
|
|
71
|
+
const observatory = init({
|
|
72
|
+
// Required
|
|
73
|
+
clientToken: 'pub-xxx',
|
|
74
|
+
applicationId: 'xxx-xxx',
|
|
75
|
+
service: 'my-app',
|
|
76
|
+
env: 'production',
|
|
77
|
+
|
|
78
|
+
// Optional
|
|
79
|
+
version: '1.0.0',
|
|
80
|
+
site: 'datadoghq.com',
|
|
81
|
+
debug: false,
|
|
82
|
+
logLevel: 'warn',
|
|
83
|
+
|
|
84
|
+
// Sampling
|
|
85
|
+
sampling: {
|
|
86
|
+
sessionSampleRate: 100,
|
|
87
|
+
sessionReplaySampleRate: 20,
|
|
88
|
+
traceSampleRate: 100,
|
|
89
|
+
},
|
|
90
|
+
|
|
91
|
+
// Error tracking
|
|
92
|
+
errorTracking: {
|
|
93
|
+
enabled: true,
|
|
94
|
+
unhandledRejections: true,
|
|
95
|
+
consoleErrors: true,
|
|
96
|
+
ignorePatterns: ['ResizeObserver loop'],
|
|
97
|
+
maxErrorsPerMinute: 100,
|
|
98
|
+
},
|
|
99
|
+
|
|
100
|
+
// Performance
|
|
101
|
+
performance: {
|
|
102
|
+
webVitals: true,
|
|
103
|
+
longTasks: true,
|
|
104
|
+
resourceTiming: true,
|
|
105
|
+
},
|
|
106
|
+
|
|
107
|
+
// Network
|
|
108
|
+
network: {
|
|
109
|
+
enabled: true,
|
|
110
|
+
excludeUrls: [/analytics/, 'hotjar.com'],
|
|
111
|
+
failedOnly: false,
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
// Privacy
|
|
115
|
+
privacy: {
|
|
116
|
+
defaultPrivacyLevel: 'mask-user-input',
|
|
117
|
+
piiFields: ['ssn', 'dob'],
|
|
118
|
+
requireConsent: false,
|
|
119
|
+
},
|
|
120
|
+
|
|
121
|
+
// User context
|
|
122
|
+
user: {
|
|
123
|
+
id: 'user-123',
|
|
124
|
+
name: 'John Doe',
|
|
125
|
+
email: 'john@example.com',
|
|
126
|
+
plan: 'enterprise',
|
|
127
|
+
},
|
|
128
|
+
|
|
129
|
+
// Global context for all events
|
|
130
|
+
globalContext: {
|
|
131
|
+
team: 'frontend',
|
|
132
|
+
region: 'us-east-1',
|
|
133
|
+
},
|
|
134
|
+
|
|
135
|
+
tags: ['team:frontend', 'product:checkout'],
|
|
136
|
+
|
|
137
|
+
// APM correlation
|
|
138
|
+
allowedTracingUrls: ['https://api.myapp.com'],
|
|
139
|
+
|
|
140
|
+
// Lifecycle hooks
|
|
141
|
+
hooks: {
|
|
142
|
+
beforeLog: (level, message) => {
|
|
143
|
+
// Return false to skip this log
|
|
144
|
+
return !message.includes('noisy-module');
|
|
145
|
+
},
|
|
146
|
+
afterInit: () => {
|
|
147
|
+
console.log('Observability ready!');
|
|
148
|
+
},
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Logger
|
|
154
|
+
|
|
155
|
+
```typescript
|
|
156
|
+
const logger = observatory.logger;
|
|
157
|
+
|
|
158
|
+
// Standard levels
|
|
159
|
+
logger.debug('Detailed info for development');
|
|
160
|
+
logger.info('User signed in', { userId: '123' });
|
|
161
|
+
logger.warn('Deprecation notice', { feature: 'old-api' });
|
|
162
|
+
logger.error('Request failed', new Error('500'), { endpoint: '/api/users' });
|
|
163
|
+
logger.critical('Database unreachable', new Error('ECONNREFUSED'));
|
|
164
|
+
|
|
165
|
+
// Timed operations
|
|
166
|
+
const result = await logger.time('fetchUsers', async () => {
|
|
167
|
+
return await fetch('/api/users');
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
// Child loggers with scoped context
|
|
171
|
+
const authLogger = logger.child({ module: 'auth' });
|
|
172
|
+
authLogger.info('Login attempt'); // includes { module: 'auth' } in every log
|
|
173
|
+
|
|
174
|
+
// Scoped context
|
|
175
|
+
logger.setContext({ requestId: 'req-456' });
|
|
176
|
+
logger.info('Processing'); // includes requestId in context
|
|
177
|
+
logger.clearContext();
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### User Context
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
// Set user after login
|
|
184
|
+
observatory.setUser({
|
|
185
|
+
id: 'user-123',
|
|
186
|
+
name: 'Jane Doe',
|
|
187
|
+
email: 'jane@example.com',
|
|
188
|
+
plan: 'enterprise',
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
// Clear on logout
|
|
192
|
+
observatory.clearUser();
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### SPA View Tracking
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
// Call on route change
|
|
199
|
+
observatory.setView('/dashboard');
|
|
200
|
+
observatory.setView('/settings/profile');
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Custom Actions
|
|
204
|
+
|
|
205
|
+
```typescript
|
|
206
|
+
observatory.trackAction('add_to_cart', {
|
|
207
|
+
productId: 'prod-456',
|
|
208
|
+
price: 29.99,
|
|
209
|
+
currency: 'USD',
|
|
210
|
+
});
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Error Capture
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
try {
|
|
217
|
+
await riskyOperation();
|
|
218
|
+
} catch (error) {
|
|
219
|
+
observatory.captureError(error, {
|
|
220
|
+
operation: 'riskyOperation',
|
|
221
|
+
userId: 'user-123',
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Capture a message
|
|
226
|
+
observatory.captureMessage('Feature flag evaluation failed', {
|
|
227
|
+
flag: 'new-checkout',
|
|
228
|
+
});
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Performance Marks
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
observatory.mark('checkout-start');
|
|
235
|
+
// ... checkout logic ...
|
|
236
|
+
observatory.mark('checkout-end');
|
|
237
|
+
const duration = observatory.measure('checkout', 'checkout-start', 'checkout-end');
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
### Session Replay
|
|
241
|
+
|
|
242
|
+
```typescript
|
|
243
|
+
observatory.startSessionReplay();
|
|
244
|
+
observatory.stopSessionReplay();
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
### Global Context
|
|
248
|
+
|
|
249
|
+
```typescript
|
|
250
|
+
observatory.addGlobalContext('tenant', 'acme-corp');
|
|
251
|
+
observatory.removeGlobalContext('tenant');
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### Events
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
import { SDKEvent } from 'datadog-frontend-toolkit';
|
|
258
|
+
|
|
259
|
+
observatory.onEvent(SDKEvent.ERROR_CAPTURED, (payload) => {
|
|
260
|
+
console.log('Error captured:', payload.data);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
observatory.onEvent(SDKEvent.PERFORMANCE_ENTRY, (payload) => {
|
|
264
|
+
console.log('Web Vital:', payload.data);
|
|
265
|
+
});
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Global Access
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
// From anywhere in your app
|
|
272
|
+
import { getInstance, getLogger } from 'datadog-frontend-toolkit';
|
|
273
|
+
|
|
274
|
+
const sdk = getInstance(); // returns null if not initialized
|
|
275
|
+
const logger = getLogger(); // throws if not initialized
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Destroy
|
|
279
|
+
|
|
280
|
+
```typescript
|
|
281
|
+
await observatory.destroy(); // Cleans up all handlers
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## Plugins
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
import { init, ObservabilityPlugin } from 'datadog-frontend-toolkit';
|
|
290
|
+
|
|
291
|
+
const myPlugin: ObservabilityPlugin = {
|
|
292
|
+
name: 'my-custom-plugin',
|
|
293
|
+
version: '1.0.0',
|
|
294
|
+
setup(sdk) {
|
|
295
|
+
sdk.addGlobalContext('plugin', 'active');
|
|
296
|
+
sdk.onEvent('sdk:error_captured', (payload) => {
|
|
297
|
+
// Custom error processing
|
|
298
|
+
});
|
|
299
|
+
},
|
|
300
|
+
teardown() {
|
|
301
|
+
// Cleanup
|
|
302
|
+
},
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
init({
|
|
306
|
+
clientToken: '...',
|
|
307
|
+
applicationId: '...',
|
|
308
|
+
service: 'my-app',
|
|
309
|
+
env: 'production',
|
|
310
|
+
plugins: [myPlugin],
|
|
311
|
+
});
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## CLI — Resource Provisioning
|
|
317
|
+
|
|
318
|
+
The CLI provisions Datadog resources (dashboards, monitors, SLOs) for your service automatically.
|
|
319
|
+
|
|
320
|
+
> **Note:** This uses Datadog API/App keys and runs server-side only. Never expose these keys in the browser.
|
|
321
|
+
|
|
322
|
+
### Setup Resources
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
# Using CLI arguments
|
|
326
|
+
npx dd-toolkit setup \
|
|
327
|
+
--service my-app \
|
|
328
|
+
--env production \
|
|
329
|
+
--api-key $DD_API_KEY \
|
|
330
|
+
--app-key $DD_APP_KEY \
|
|
331
|
+
--team frontend
|
|
332
|
+
|
|
333
|
+
# Using environment variables
|
|
334
|
+
export DD_API_KEY=your-api-key
|
|
335
|
+
export DD_APP_KEY=your-app-key
|
|
336
|
+
npx dd-toolkit setup -s my-app -e production
|
|
337
|
+
|
|
338
|
+
# Dry run (preview only)
|
|
339
|
+
npx dd-toolkit setup -s my-app -e production --dry-run
|
|
340
|
+
|
|
341
|
+
# Skip specific resources
|
|
342
|
+
npx dd-toolkit setup -s my-app -e production --no-slos
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Check Status
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
npx dd-toolkit status -s my-app -e production
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### What Gets Provisioned
|
|
352
|
+
|
|
353
|
+
**Dashboard:**
|
|
354
|
+
- Frontend Observability overview with RUM metrics, Web Vitals, error tracking, and performance panels
|
|
355
|
+
|
|
356
|
+
**Monitors (6):**
|
|
357
|
+
- High Frontend Error Rate (>50 errors/5min)
|
|
358
|
+
- Poor LCP Performance (p75 > 4s)
|
|
359
|
+
- High CLS Score (p75 > 0.25)
|
|
360
|
+
- JS Error Spike (>100 errors/5min)
|
|
361
|
+
- Error Log Anomaly (>200 error logs/15min)
|
|
362
|
+
- Poor INP Performance (p75 > 500ms)
|
|
363
|
+
|
|
364
|
+
**SLOs (4):**
|
|
365
|
+
- Frontend Availability (99.5% target)
|
|
366
|
+
- LCP Performance (75% good threshold)
|
|
367
|
+
- INP Performance (75% good threshold)
|
|
368
|
+
- CLS Performance (75% good threshold)
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Framework Examples
|
|
373
|
+
|
|
374
|
+
### React
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
// src/index.tsx
|
|
378
|
+
import { init } from 'datadog-frontend-toolkit';
|
|
379
|
+
|
|
380
|
+
const observatory = init({
|
|
381
|
+
clientToken: process.env.REACT_APP_DD_CLIENT_TOKEN!,
|
|
382
|
+
applicationId: process.env.REACT_APP_DD_APP_ID!,
|
|
383
|
+
service: 'react-app',
|
|
384
|
+
env: process.env.NODE_ENV,
|
|
385
|
+
version: process.env.REACT_APP_VERSION,
|
|
386
|
+
});
|
|
387
|
+
|
|
388
|
+
export { observatory };
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Vue
|
|
392
|
+
|
|
393
|
+
```typescript
|
|
394
|
+
// src/main.ts
|
|
395
|
+
import { init } from 'datadog-frontend-toolkit';
|
|
396
|
+
|
|
397
|
+
const observatory = init({
|
|
398
|
+
clientToken: import.meta.env.VITE_DD_CLIENT_TOKEN,
|
|
399
|
+
applicationId: import.meta.env.VITE_DD_APP_ID,
|
|
400
|
+
service: 'vue-app',
|
|
401
|
+
env: import.meta.env.MODE,
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
app.config.errorHandler = (err) => {
|
|
405
|
+
observatory.captureError(err instanceof Error ? err : new Error(String(err)));
|
|
406
|
+
};
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
### Angular
|
|
410
|
+
|
|
411
|
+
```typescript
|
|
412
|
+
// src/main.ts
|
|
413
|
+
import { init } from 'datadog-frontend-toolkit';
|
|
414
|
+
|
|
415
|
+
init({
|
|
416
|
+
clientToken: environment.ddClientToken,
|
|
417
|
+
applicationId: environment.ddAppId,
|
|
418
|
+
service: 'angular-app',
|
|
419
|
+
env: environment.production ? 'production' : 'development',
|
|
420
|
+
});
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### Next.js
|
|
424
|
+
|
|
425
|
+
```typescript
|
|
426
|
+
// src/lib/observability.ts
|
|
427
|
+
import { init } from 'datadog-frontend-toolkit';
|
|
428
|
+
|
|
429
|
+
export const observatory =
|
|
430
|
+
typeof window !== 'undefined'
|
|
431
|
+
? init({
|
|
432
|
+
clientToken: process.env.NEXT_PUBLIC_DD_CLIENT_TOKEN!,
|
|
433
|
+
applicationId: process.env.NEXT_PUBLIC_DD_APP_ID!,
|
|
434
|
+
service: 'nextjs-app',
|
|
435
|
+
env: process.env.NODE_ENV,
|
|
436
|
+
})
|
|
437
|
+
: null;
|
|
438
|
+
```
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## Architecture
|
|
443
|
+
|
|
444
|
+
```
|
|
445
|
+
┌─────────────────────────────────────────────────┐
|
|
446
|
+
│ init(config) │
|
|
447
|
+
│ ObservabilitySDK │
|
|
448
|
+
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
|
|
449
|
+
│ │ RUM │ │ Logs │ │ Logger │ │
|
|
450
|
+
│ │ Manager │ │ Manager │ │ Service │ │
|
|
451
|
+
│ └──────────┘ └──────────┘ └───────────────┘ │
|
|
452
|
+
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
|
|
453
|
+
│ │ Error │ │ Perf │ │ Network │ │
|
|
454
|
+
│ │ Boundary │ │ Monitor │ │ Interceptor │ │
|
|
455
|
+
│ └──────────┘ └──────────┘ └───────────────┘ │
|
|
456
|
+
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
|
|
457
|
+
│ │ Context │ │ Bootstrap│ │ Event │ │
|
|
458
|
+
│ │ Manager │ │ Guard │ │ Emitter │ │
|
|
459
|
+
│ └──────────┘ └──────────┘ └───────────────┘ │
|
|
460
|
+
└─────────────────────────────────────────────────┘
|
|
461
|
+
│
|
|
462
|
+
▼ (CLI only, server-side)
|
|
463
|
+
┌─────────────────────────────────────────────────┐
|
|
464
|
+
│ Resource Provisioner │
|
|
465
|
+
│ ┌──────────┐ ┌──────────┐ ┌───────────────┐ │
|
|
466
|
+
│ │Dashboard │ │ Monitor │ │ SLO │ │
|
|
467
|
+
│ │Templates │ │Templates │ │ Templates │ │
|
|
468
|
+
│ └──────────┘ └──────────┘ └───────────────┘ │
|
|
469
|
+
└─────────────────────────────────────────────────┘
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
**Design Patterns Used:**
|
|
473
|
+
- **Singleton** — SDK instance management
|
|
474
|
+
- **Facade** — Single entry point for all features
|
|
475
|
+
- **Observer** — Event system for loose coupling
|
|
476
|
+
- **Adapter** — Log level normalization
|
|
477
|
+
- **Builder** — Configuration resolution
|
|
478
|
+
- **Chain of Responsibility** — Error processing pipeline
|
|
479
|
+
- **Proxy/Decorator** — Network interception
|
|
480
|
+
- **Template Method** — Resource provisioning
|
|
481
|
+
|
|
482
|
+
---
|
|
483
|
+
|
|
484
|
+
## License
|
|
485
|
+
|
|
486
|
+
MIT
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContextManager = void 0;
|
|
4
|
+
const events_1 = require("../types/events");
|
|
5
|
+
/**
|
|
6
|
+
* Centralized context management for enriching all events with
|
|
7
|
+
* browser, user, session, and application metadata.
|
|
8
|
+
* Implements the Mediator pattern to share context across modules.
|
|
9
|
+
*/
|
|
10
|
+
class ContextManager {
|
|
11
|
+
globalContext;
|
|
12
|
+
userContext;
|
|
13
|
+
config;
|
|
14
|
+
emitter;
|
|
15
|
+
viewName;
|
|
16
|
+
cachedBrowserInfo;
|
|
17
|
+
constructor(config, emitter) {
|
|
18
|
+
this.config = config;
|
|
19
|
+
this.emitter = emitter;
|
|
20
|
+
this.globalContext = { ...config.globalContext };
|
|
21
|
+
this.userContext = config.user ? { ...config.user } : undefined;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Returns the full context snapshot to attach to logs and events.
|
|
25
|
+
*/
|
|
26
|
+
getFullContext() {
|
|
27
|
+
return {
|
|
28
|
+
...this.globalContext,
|
|
29
|
+
service: this.config.service,
|
|
30
|
+
env: this.config.env,
|
|
31
|
+
version: this.config.version,
|
|
32
|
+
url: this.getCurrentUrl(),
|
|
33
|
+
view: this.viewName,
|
|
34
|
+
browser: this.getBrowserInfo(),
|
|
35
|
+
user: this.userContext,
|
|
36
|
+
tags: this.config.tags,
|
|
37
|
+
timestamp: new Date().toISOString(),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Returns only the global context (without browser info).
|
|
42
|
+
*/
|
|
43
|
+
getGlobalContext() {
|
|
44
|
+
return { ...this.globalContext };
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Sets a key-value pair in the global context.
|
|
48
|
+
*/
|
|
49
|
+
setGlobalContext(key, value) {
|
|
50
|
+
this.globalContext[key] = value;
|
|
51
|
+
this.emitter.emit(events_1.SDKEvent.CONTEXT_UPDATED, {
|
|
52
|
+
type: events_1.SDKEvent.CONTEXT_UPDATED,
|
|
53
|
+
timestamp: Date.now(),
|
|
54
|
+
data: { key, value },
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Removes a key from the global context.
|
|
59
|
+
*/
|
|
60
|
+
removeGlobalContext(key) {
|
|
61
|
+
delete this.globalContext[key];
|
|
62
|
+
this.emitter.emit(events_1.SDKEvent.CONTEXT_UPDATED, {
|
|
63
|
+
type: events_1.SDKEvent.CONTEXT_UPDATED,
|
|
64
|
+
timestamp: Date.now(),
|
|
65
|
+
data: { key, removed: true },
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Sets user context.
|
|
70
|
+
*/
|
|
71
|
+
setUser(user) {
|
|
72
|
+
this.userContext = { ...user };
|
|
73
|
+
this.emitter.emit(events_1.SDKEvent.USER_SET, {
|
|
74
|
+
type: events_1.SDKEvent.USER_SET,
|
|
75
|
+
timestamp: Date.now(),
|
|
76
|
+
data: { userId: user.id },
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Clears user context.
|
|
81
|
+
*/
|
|
82
|
+
clearUser() {
|
|
83
|
+
this.userContext = undefined;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Gets current user context.
|
|
87
|
+
*/
|
|
88
|
+
getUser() {
|
|
89
|
+
return this.userContext ? { ...this.userContext } : undefined;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Sets the current view/route name.
|
|
93
|
+
*/
|
|
94
|
+
setView(name) {
|
|
95
|
+
this.viewName = name;
|
|
96
|
+
this.emitter.emit(events_1.SDKEvent.VIEW_CHANGED, {
|
|
97
|
+
type: events_1.SDKEvent.VIEW_CHANGED,
|
|
98
|
+
timestamp: Date.now(),
|
|
99
|
+
data: { view: name },
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Gets the current view/route name.
|
|
104
|
+
*/
|
|
105
|
+
getView() {
|
|
106
|
+
return this.viewName;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Collects browser and device information.
|
|
110
|
+
* Cached after first call since these values rarely change.
|
|
111
|
+
*/
|
|
112
|
+
getBrowserInfo() {
|
|
113
|
+
if (this.cachedBrowserInfo) {
|
|
114
|
+
return {
|
|
115
|
+
...this.cachedBrowserInfo,
|
|
116
|
+
online: typeof navigator !== 'undefined' ? navigator.onLine : true,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
if (typeof window === 'undefined' || typeof navigator === 'undefined') {
|
|
120
|
+
return this.getSSRBrowserInfo();
|
|
121
|
+
}
|
|
122
|
+
this.cachedBrowserInfo = {
|
|
123
|
+
userAgent: navigator.userAgent,
|
|
124
|
+
language: navigator.language,
|
|
125
|
+
platform: navigator.platform ?? 'unknown',
|
|
126
|
+
vendor: navigator.vendor ?? 'unknown',
|
|
127
|
+
cookieEnabled: navigator.cookieEnabled,
|
|
128
|
+
online: navigator.onLine,
|
|
129
|
+
screenResolution: `${screen.width}x${screen.height}`,
|
|
130
|
+
viewportSize: `${window.innerWidth}x${window.innerHeight}`,
|
|
131
|
+
devicePixelRatio: window.devicePixelRatio,
|
|
132
|
+
colorDepth: screen.colorDepth,
|
|
133
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
134
|
+
memory: this.getMemoryInfo(),
|
|
135
|
+
connection: this.getConnectionInfo(),
|
|
136
|
+
};
|
|
137
|
+
return { ...this.cachedBrowserInfo };
|
|
138
|
+
}
|
|
139
|
+
getCurrentUrl() {
|
|
140
|
+
try {
|
|
141
|
+
return typeof window !== 'undefined' ? window.location.href : 'unknown';
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
return 'unknown';
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
getMemoryInfo() {
|
|
148
|
+
try {
|
|
149
|
+
const perf = performance;
|
|
150
|
+
if (perf.memory) {
|
|
151
|
+
return {
|
|
152
|
+
jsHeapSizeLimit: perf.memory.jsHeapSizeLimit,
|
|
153
|
+
totalJSHeapSize: perf.memory.totalJSHeapSize,
|
|
154
|
+
usedJSHeapSize: perf.memory.usedJSHeapSize,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
// Not available
|
|
160
|
+
}
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
getConnectionInfo() {
|
|
164
|
+
try {
|
|
165
|
+
const nav = navigator;
|
|
166
|
+
if (nav.connection) {
|
|
167
|
+
return {
|
|
168
|
+
effectiveType: nav.connection.effectiveType,
|
|
169
|
+
downlink: nav.connection.downlink,
|
|
170
|
+
rtt: nav.connection.rtt,
|
|
171
|
+
saveData: nav.connection.saveData,
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
// Not available
|
|
177
|
+
}
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
180
|
+
getSSRBrowserInfo() {
|
|
181
|
+
return {
|
|
182
|
+
userAgent: 'ssr',
|
|
183
|
+
language: 'en',
|
|
184
|
+
platform: 'server',
|
|
185
|
+
vendor: 'unknown',
|
|
186
|
+
cookieEnabled: false,
|
|
187
|
+
online: true,
|
|
188
|
+
screenResolution: '0x0',
|
|
189
|
+
viewportSize: '0x0',
|
|
190
|
+
devicePixelRatio: 1,
|
|
191
|
+
colorDepth: 0,
|
|
192
|
+
timezone: 'UTC',
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
exports.ContextManager = ContextManager;
|
|
197
|
+
//# sourceMappingURL=ContextManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ContextManager.js","sourceRoot":"","sources":["../../../src/context/ContextManager.ts"],"names":[],"mappings":"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"}
|