-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathotel-utils.js
More file actions
121 lines (108 loc) · 3.02 KB
/
otel-utils.js
File metadata and controls
121 lines (108 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
const MAX_STACK_LENGTH = 1000;
function getTelemetryClient() {
if (typeof window !== 'undefined' && window.fastcashTelemetry) {
return window.fastcashTelemetry;
}
return {
track() {
return false;
},
trackError() {
return false;
},
};
}
/**
* Track page navigation/tab changes
*/
export function trackTabChange(tabName) {
return getTelemetryClient().track('tab.change', {
'tab.name': tabName,
'user.action': 'navigation',
});
}
/**
* Track user interactions (clicks, form submissions)
*/
export function trackUserAction(actionName, details = {}) {
return getTelemetryClient().track('user.action', {
'action.name': actionName,
...Object.entries(details).reduce((acc, [key, value]) => {
acc[`action.${key}`] = String(value);
return acc;
}, {}),
});
}
/**
* Track page load performance
*/
export function trackPageMetrics() {
if (typeof window !== 'undefined' && window.performance) {
const navigationEntry = window.performance.getEntriesByType('navigation')[0];
if (navigationEntry) {
return getTelemetryClient().track('page.load', {
'page.load_time_ms': Math.round(navigationEntry.loadEventEnd),
'page.dom_interactive_ms': Math.round(navigationEntry.domInteractive),
'page.dom_complete_ms': Math.round(navigationEntry.domComplete),
});
}
const perfData = window.performance.timing;
const navigationStart = perfData.navigationStart || 0;
return getTelemetryClient().track('page.load', {
'page.load_time_ms': perfData.loadEventEnd - navigationStart,
'page.dom_interactive_ms': perfData.domInteractive - navigationStart,
'page.dom_complete_ms': perfData.domComplete - navigationStart,
});
}
return false;
}
/**
* Track errors
*/
export function trackError(errorName, errorMessage, errorStack = '') {
return getTelemetryClient().trackError(
errorName,
errorMessage,
// Keep telemetry payloads small and avoid leaking oversized stacks.
String(errorStack).slice(0, MAX_STACK_LENGTH),
);
}
/**
* Track API calls
*/
export function trackAPICall(endpoint, method = 'GET', details = {}) {
const telemetry = getTelemetryClient();
const startedAt = Date.now();
telemetry.track('api.call.start', {
'http.method': method,
'http.url': endpoint,
...Object.entries(details).reduce((acc, [key, value]) => {
acc[`api.${key}`] = String(value);
return acc;
}, {}),
});
return {
end: (statusCode, duration) => {
return telemetry.track('api.call.complete', {
'http.method': method,
'http.url': endpoint,
'http.status_code': statusCode,
'http.duration_ms': duration ?? (Date.now() - startedAt),
});
},
recordError: (error) => {
return telemetry.trackError(
'api.call',
error?.message || `API call failed: ${method} ${endpoint}`,
error?.stack || '',
);
},
};
}
export default {
trackTabChange,
trackUserAction,
trackPageMetrics,
trackError,
trackAPICall,
};