@xeonr/telemetry-web 0.0.0-stage → 0.1.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/README.md +168 -2
- package/dist/classify.d.ts +48 -0
- package/dist/classify.d.ts.map +1 -0
- package/dist/classify.js +117 -0
- package/dist/classify.js.map +1 -0
- package/dist/client.d.ts +135 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +511 -0
- package/dist/client.js.map +1 -0
- package/dist/connect.d.ts +11 -0
- package/dist/connect.d.ts.map +1 -0
- package/dist/connect.js +44 -0
- package/dist/connect.js.map +1 -0
- package/dist/env.d.ts +68 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +97 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +89 -0
- package/dist/index.js.map +1 -0
- package/dist/otlp.d.ts +124 -0
- package/dist/otlp.d.ts.map +1 -0
- package/dist/otlp.js +105 -0
- package/dist/otlp.js.map +1 -0
- package/dist/queue.d.ts +92 -0
- package/dist/queue.d.ts.map +1 -0
- package/dist/queue.js +355 -0
- package/dist/queue.js.map +1 -0
- package/dist/react.d.ts +34 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +46 -0
- package/dist/react.js.map +1 -0
- package/dist/stack.d.ts +23 -0
- package/dist/stack.d.ts.map +1 -0
- package/dist/stack.js +52 -0
- package/dist/stack.js.map +1 -0
- package/dist/trace.d.ts +10 -0
- package/dist/trace.d.ts.map +1 -0
- package/dist/trace.js +46 -0
- package/dist/trace.js.map +1 -0
- package/dist/vitals.d.ts +20 -0
- package/dist/vitals.d.ts.map +1 -0
- package/dist/vitals.js +151 -0
- package/dist/vitals.js.map +1 -0
- package/dist/vite.d.ts +41 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +171 -0
- package/dist/vite.js.map +1 -0
- package/package.json +59 -3
package/dist/client.js
ADDED
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
// The client: what a console's errors, requests, routes and vitals become on
|
|
2
|
+
// the wire. The event names and attribute keys are Lantern's ingest contract
|
|
3
|
+
// (lantern/docs/WAVE4-client-ingest.md §7); a key the ingest has not
|
|
4
|
+
// declared is dropped at the door, so new ones are added there first.
|
|
5
|
+
import { browserEnv, hex, meta, newSpanId, newTraceId } from "./env.js";
|
|
6
|
+
import { attributes, clientSpan, logRecord, normaliseTraceId } from "./otlp.js";
|
|
7
|
+
import { Delivery } from "./queue.js";
|
|
8
|
+
import { classify, codeName, isConnectError, probeCors } from "./classify.js";
|
|
9
|
+
import { isExtensionFrame, scrub, scrubStackHeader, stripQueries, topFrame } from "./stack.js";
|
|
10
|
+
import { observeVitals } from "./vitals.js";
|
|
11
|
+
import { traceIdFrom } from "./trace.js";
|
|
12
|
+
export const SDK_NAME = "@xeonr/telemetry-web";
|
|
13
|
+
export const SDK_VERSION = "0.1.0";
|
|
14
|
+
export const DEFAULT_ENDPOINT = "https://telemetry.xeonr.io";
|
|
15
|
+
/** The record attribute carrying breadcrumbs (a JSON string). */
|
|
16
|
+
export const BREADCRUMBS_KEY = "app.breadcrumbs";
|
|
17
|
+
const NOOP_HANDLE = { headers: {}, end() { } };
|
|
18
|
+
/** A client that does nothing, for a disabled or unconfigured page. Same shape, so callers never null-check. */
|
|
19
|
+
export function noopClient(service = "", release = "dev", endpoint = DEFAULT_ENDPOINT) {
|
|
20
|
+
return {
|
|
21
|
+
enabled: false,
|
|
22
|
+
service,
|
|
23
|
+
release,
|
|
24
|
+
endpoint,
|
|
25
|
+
instanceId: "",
|
|
26
|
+
sessionId: "",
|
|
27
|
+
captureException() { },
|
|
28
|
+
trackRoute() { },
|
|
29
|
+
event() { },
|
|
30
|
+
breadcrumb() { },
|
|
31
|
+
setAttributes() { },
|
|
32
|
+
beginRequest: () => NOOP_HANDLE,
|
|
33
|
+
isOwnUrl: () => false,
|
|
34
|
+
flush: () => Promise.resolve(),
|
|
35
|
+
shutdown() { },
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
const LOCAL_HOST = /^(localhost|127\.0\.0\.1|\[::1\]|::1)$|\.localhost$|\.test$/i;
|
|
39
|
+
/** Whether this page is a local development server, where telemetry is off by default. */
|
|
40
|
+
export function isLocalDevHost(hostname) {
|
|
41
|
+
return !!hostname && LOCAL_HOST.test(hostname);
|
|
42
|
+
}
|
|
43
|
+
function persistentId(storage, key, env) {
|
|
44
|
+
try {
|
|
45
|
+
const have = storage?.getItem(key);
|
|
46
|
+
if (have && /^[0-9a-f]{16,64}$/.test(have))
|
|
47
|
+
return have;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
/* fall through */
|
|
51
|
+
}
|
|
52
|
+
const id = hex(env.randomBytes(16));
|
|
53
|
+
try {
|
|
54
|
+
storage?.setItem(key, id);
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
/* an id for this page only */
|
|
58
|
+
}
|
|
59
|
+
return id;
|
|
60
|
+
}
|
|
61
|
+
function errorParts(err) {
|
|
62
|
+
if (err instanceof Error || (typeof err === "object" && err !== null && "message" in err)) {
|
|
63
|
+
const e = err;
|
|
64
|
+
const type = (typeof e.name === "string" && e.name) || e.constructor?.name || "Error";
|
|
65
|
+
return { type, message: String(e.message ?? ""), stack: typeof e.stack === "string" ? e.stack : undefined };
|
|
66
|
+
}
|
|
67
|
+
if (typeof err === "string")
|
|
68
|
+
return { type: "Error", message: err, stack: undefined };
|
|
69
|
+
let message;
|
|
70
|
+
try {
|
|
71
|
+
message = JSON.stringify(err) ?? String(err);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
message = String(err);
|
|
75
|
+
}
|
|
76
|
+
return { type: err === null ? "null" : typeof err, message, stack: undefined };
|
|
77
|
+
}
|
|
78
|
+
// Browser noise no console can act on.
|
|
79
|
+
const IGNORED = [/^Script error\.?$/, /^ResizeObserver loop (limit exceeded|completed with undelivered notifications)/];
|
|
80
|
+
/**
|
|
81
|
+
* One allowance per key per window: a render loop throwing the same error, or
|
|
82
|
+
* a dead API failing every call, is one signal, not a thousand records.
|
|
83
|
+
*/
|
|
84
|
+
class Throttle {
|
|
85
|
+
seen = new Map();
|
|
86
|
+
perKey;
|
|
87
|
+
windowMs;
|
|
88
|
+
constructor(perKey, windowMs) {
|
|
89
|
+
this.perKey = perKey;
|
|
90
|
+
this.windowMs = windowMs;
|
|
91
|
+
}
|
|
92
|
+
/** undefined: drop. A number: send, carrying how many were dropped since the last one sent. */
|
|
93
|
+
take(key, now) {
|
|
94
|
+
const s = this.seen.get(key);
|
|
95
|
+
if (!s || now - s.at > this.windowMs) {
|
|
96
|
+
const suppressed = s?.suppressed ?? 0;
|
|
97
|
+
this.seen.set(key, { at: now, n: 1, suppressed: 0 });
|
|
98
|
+
if (this.seen.size > 500)
|
|
99
|
+
this.seen.clear();
|
|
100
|
+
return suppressed;
|
|
101
|
+
}
|
|
102
|
+
if (s.n < this.perKey) {
|
|
103
|
+
s.n++;
|
|
104
|
+
const suppressed = s.suppressed;
|
|
105
|
+
s.suppressed = 0;
|
|
106
|
+
return suppressed;
|
|
107
|
+
}
|
|
108
|
+
s.suppressed++;
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
class Client {
|
|
113
|
+
enabled = true;
|
|
114
|
+
service;
|
|
115
|
+
release;
|
|
116
|
+
endpoint;
|
|
117
|
+
instanceId;
|
|
118
|
+
sessionId;
|
|
119
|
+
env;
|
|
120
|
+
opts;
|
|
121
|
+
delivery;
|
|
122
|
+
sampleRate;
|
|
123
|
+
vitalsSampled;
|
|
124
|
+
crumbs = [];
|
|
125
|
+
extraAttrs = {};
|
|
126
|
+
resourceBase;
|
|
127
|
+
exceptions = new Throttle(5, 60_000);
|
|
128
|
+
failures = new Throttle(1, 10_000);
|
|
129
|
+
route;
|
|
130
|
+
lastSuccessAt;
|
|
131
|
+
vitals;
|
|
132
|
+
teardown = [];
|
|
133
|
+
constructor(env, opts, service, release, endpoint) {
|
|
134
|
+
this.env = env;
|
|
135
|
+
this.opts = opts;
|
|
136
|
+
this.service = service;
|
|
137
|
+
this.release = release;
|
|
138
|
+
this.endpoint = endpoint;
|
|
139
|
+
this.instanceId = persistentId(env.local, "xeonr.telemetry.instance", env);
|
|
140
|
+
this.sessionId = persistentId(env.session, "xeonr.telemetry.session", env);
|
|
141
|
+
this.sampleRate = Math.min(1, Math.max(0, opts.sampleRate ?? 1));
|
|
142
|
+
this.vitalsSampled = this.sample();
|
|
143
|
+
this.resourceBase = this.resourceAttrs();
|
|
144
|
+
this.delivery = new Delivery(env, {
|
|
145
|
+
endpoint,
|
|
146
|
+
service,
|
|
147
|
+
scope: { name: SDK_NAME, version: SDK_VERSION },
|
|
148
|
+
resource: (version) => attributes({ ...this.resourceBase, "service.version": version }),
|
|
149
|
+
flushIntervalMs: opts.flushIntervalMs,
|
|
150
|
+
maxBatch: opts.maxBatch,
|
|
151
|
+
maxStored: opts.maxStored,
|
|
152
|
+
maxStoredBytes: opts.maxStoredBytes,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
sample() {
|
|
156
|
+
if (this.sampleRate >= 1)
|
|
157
|
+
return true;
|
|
158
|
+
if (this.sampleRate <= 0)
|
|
159
|
+
return false;
|
|
160
|
+
const b = this.env.randomBytes(4);
|
|
161
|
+
const n = (((b[0] ?? 0) << 24) >>> 0) + ((b[1] ?? 0) << 16) + ((b[2] ?? 0) << 8) + (b[3] ?? 0);
|
|
162
|
+
return n / 0x1_0000_0000 < this.sampleRate;
|
|
163
|
+
}
|
|
164
|
+
resourceAttrs() {
|
|
165
|
+
const nav = this.env.navigator;
|
|
166
|
+
const uad = nav?.userAgentData;
|
|
167
|
+
return {
|
|
168
|
+
"service.name": this.service,
|
|
169
|
+
"service.version": this.release,
|
|
170
|
+
"service.namespace": this.opts.product,
|
|
171
|
+
"service.instance.id": this.instanceId,
|
|
172
|
+
"deployment.environment": this.opts.environment,
|
|
173
|
+
"telemetry.sdk.name": SDK_NAME,
|
|
174
|
+
"telemetry.sdk.version": SDK_VERSION,
|
|
175
|
+
"telemetry.sdk.language": "webjs",
|
|
176
|
+
"browser.brands": uad?.brands?.map((b) => `${b.brand} ${b.version}`),
|
|
177
|
+
"browser.platform": uad?.platform ?? undefined,
|
|
178
|
+
"browser.mobile": uad?.mobile ?? undefined,
|
|
179
|
+
"browser.language": nav?.language ?? undefined,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
start() {
|
|
183
|
+
const { env } = this;
|
|
184
|
+
this.delivery.start();
|
|
185
|
+
if (this.opts.captureGlobalErrors !== false && env.window) {
|
|
186
|
+
const onError = (ev) => {
|
|
187
|
+
const e = ev;
|
|
188
|
+
const err = e.error ?? e.message;
|
|
189
|
+
this.capture(err, { mechanism: "onerror" }, e.filename ? { file: e.filename, line: e.lineno, column: e.colno } : undefined);
|
|
190
|
+
};
|
|
191
|
+
const onRejection = (ev) => this.capture(ev.reason, { mechanism: "unhandledrejection" });
|
|
192
|
+
env.window.addEventListener("error", onError);
|
|
193
|
+
env.window.addEventListener("unhandledrejection", onRejection);
|
|
194
|
+
this.teardown.push(() => {
|
|
195
|
+
env.window?.removeEventListener?.("error", onError);
|
|
196
|
+
env.window?.removeEventListener?.("unhandledrejection", onRejection);
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
if (this.opts.capturePerformance !== false) {
|
|
200
|
+
if (this.vitalsSampled) {
|
|
201
|
+
this.vitals = observeVitals(env, (name, value, rating) => this.log("INFO", `${name} ${Math.round(value * 1000) / 1000}`, {
|
|
202
|
+
"event.name": "web_vital",
|
|
203
|
+
"web_vital.name": name,
|
|
204
|
+
"web_vital.value": value,
|
|
205
|
+
"web_vital.rating": rating,
|
|
206
|
+
}));
|
|
207
|
+
this.delivery.beforeHide = () => this.vitals?.finalize();
|
|
208
|
+
}
|
|
209
|
+
this.pageView();
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
// ---- records ----
|
|
213
|
+
currentPath() {
|
|
214
|
+
return this.route ?? this.env.location?.pathname;
|
|
215
|
+
}
|
|
216
|
+
common() {
|
|
217
|
+
return { ...this.extraAttrs, "session.id": this.sessionId, "url.path": this.currentPath() };
|
|
218
|
+
}
|
|
219
|
+
enqueue(item) {
|
|
220
|
+
try {
|
|
221
|
+
this.delivery.push(item);
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
/* never into the host */
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
log(severity, body, attrs, traceId, spanId) {
|
|
228
|
+
const rec = logRecord({ time: this.env.now(), severity, body, attrs: { ...this.common(), ...attrs }, traceId, spanId });
|
|
229
|
+
this.enqueue({ k: "l", v: this.release, r: rec, ...(severity === "ERROR" ? { e: 1 } : {}) });
|
|
230
|
+
}
|
|
231
|
+
event(name, attrs = {}, opts = {}) {
|
|
232
|
+
try {
|
|
233
|
+
this.log(opts.severity ?? "INFO", opts.body ?? name, { ...attrs, "event.name": name });
|
|
234
|
+
}
|
|
235
|
+
catch {
|
|
236
|
+
/* never */
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
breadcrumb(b) {
|
|
240
|
+
this.crumbs.push({ ...b, ts: Math.round(this.env.now()) });
|
|
241
|
+
if (this.crumbs.length > 20)
|
|
242
|
+
this.crumbs.splice(0, this.crumbs.length - 20);
|
|
243
|
+
}
|
|
244
|
+
setAttributes(attrs) {
|
|
245
|
+
for (const [k, v] of Object.entries(attrs)) {
|
|
246
|
+
if (v === undefined || v === null)
|
|
247
|
+
delete this.extraAttrs[k];
|
|
248
|
+
else
|
|
249
|
+
this.extraAttrs[k] = v;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
captureException(err, ctx = {}) {
|
|
253
|
+
this.capture(err, ctx);
|
|
254
|
+
}
|
|
255
|
+
capture(err, ctx, frameHint) {
|
|
256
|
+
try {
|
|
257
|
+
const { type, message: raw, stack } = errorParts(err);
|
|
258
|
+
if (!stack && IGNORED.some((re) => re.test(raw)))
|
|
259
|
+
return;
|
|
260
|
+
const frame = topFrame(stack) ?? frameHint;
|
|
261
|
+
if (isExtensionFrame(frame?.file))
|
|
262
|
+
return;
|
|
263
|
+
const now = this.env.now();
|
|
264
|
+
const suppressed = this.exceptions.take(`${type}|${raw}|${frame?.file}:${frame?.line}`, now);
|
|
265
|
+
if (suppressed === undefined)
|
|
266
|
+
return;
|
|
267
|
+
const message = scrub(raw);
|
|
268
|
+
const traceId = normaliseTraceId(ctx.traceId ?? traceIdFrom(err));
|
|
269
|
+
const route = ctx.route !== undefined ? stripQueries(ctx.route).split(/[?#]/)[0] : this.currentPath();
|
|
270
|
+
const attrs = {
|
|
271
|
+
"event.name": "exception",
|
|
272
|
+
"exception.type": type,
|
|
273
|
+
"exception.message": message,
|
|
274
|
+
"exception.stacktrace": stack ? scrubStackHeader(stack, raw, message).slice(0, 32 * 1024) : undefined,
|
|
275
|
+
"exception.mechanism": ctx.mechanism ?? "manual",
|
|
276
|
+
"exception.component_stack": ctx.componentStack?.slice(0, 8 * 1024),
|
|
277
|
+
"exception.suppressed_count": suppressed > 0 ? suppressed : undefined,
|
|
278
|
+
"code.filepath": frame?.file ? stripQueries(frame.file) : undefined,
|
|
279
|
+
"code.lineno": frame?.line,
|
|
280
|
+
"code.column": frame?.column,
|
|
281
|
+
"url.path": route,
|
|
282
|
+
"http.response.header.x-trace-id": traceId,
|
|
283
|
+
"rpc.response.status_code": isConnectError(err) ? codeName(err.code) : undefined,
|
|
284
|
+
"user_agent.original": this.env.navigator?.userAgent,
|
|
285
|
+
[BREADCRUMBS_KEY]: this.crumbs.length ? JSON.stringify(this.crumbs) : undefined,
|
|
286
|
+
...ctx.extra,
|
|
287
|
+
};
|
|
288
|
+
this.log(ctx.severity ?? "ERROR", message || type, attrs, traceId);
|
|
289
|
+
}
|
|
290
|
+
catch {
|
|
291
|
+
/* never into the host */
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
trackRoute(path) {
|
|
295
|
+
try {
|
|
296
|
+
const clean = stripQueries(path).split(/[?#]/)[0] || "/";
|
|
297
|
+
const prev = this.currentPath();
|
|
298
|
+
const first = this.route === undefined;
|
|
299
|
+
this.route = clean;
|
|
300
|
+
if (clean === prev)
|
|
301
|
+
return;
|
|
302
|
+
this.breadcrumb({ type: "route", path: clean });
|
|
303
|
+
// The first call is usually the router settling on the page that just
|
|
304
|
+
// loaded, which page_view already covers.
|
|
305
|
+
if (first && clean === this.env.location?.pathname)
|
|
306
|
+
return;
|
|
307
|
+
this.log("INFO", `route_change ${clean}`, { "event.name": "route_change" });
|
|
308
|
+
}
|
|
309
|
+
catch {
|
|
310
|
+
/* never */
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
pageView() {
|
|
314
|
+
const send = () => {
|
|
315
|
+
try {
|
|
316
|
+
const nav = this.env.performance?.getEntriesByType?.("navigation")[0];
|
|
317
|
+
const ms = (v) => (v !== undefined && v > 0 ? Math.round(v) : undefined);
|
|
318
|
+
this.log("INFO", `page_view ${this.currentPath() ?? ""}`.trim(), {
|
|
319
|
+
"event.name": "page_view",
|
|
320
|
+
"document_load.type": nav?.type,
|
|
321
|
+
"document_load.dom_interactive_ms": ms(nav?.domInteractive),
|
|
322
|
+
"document_load.dom_content_loaded_ms": ms(nav?.domContentLoadedEventEnd),
|
|
323
|
+
"document_load.load_ms": ms(nav?.loadEventEnd),
|
|
324
|
+
"document_load.transfer_size": nav?.transferSize || undefined,
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
catch {
|
|
328
|
+
/* never */
|
|
329
|
+
}
|
|
330
|
+
};
|
|
331
|
+
const doc = this.env.document;
|
|
332
|
+
if (!doc || doc.readyState === "complete") {
|
|
333
|
+
this.env.setTimeout(send, 0);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
// After load, so loadEventEnd is filled in.
|
|
337
|
+
this.env.window?.addEventListener("load", () => this.env.setTimeout(send, 0), { once: true });
|
|
338
|
+
}
|
|
339
|
+
// ---- requests ----
|
|
340
|
+
isOwnUrl(url) {
|
|
341
|
+
return url.startsWith(this.endpoint + "/") || url === this.endpoint;
|
|
342
|
+
}
|
|
343
|
+
beginRequest(r) {
|
|
344
|
+
try {
|
|
345
|
+
return this.request(r);
|
|
346
|
+
}
|
|
347
|
+
catch {
|
|
348
|
+
return NOOP_HANDLE;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
request(r) {
|
|
352
|
+
const { env } = this;
|
|
353
|
+
if (this.isOwnUrl(r.url))
|
|
354
|
+
return NOOP_HANDLE;
|
|
355
|
+
const base = env.location?.href ?? "http://localhost/";
|
|
356
|
+
let url;
|
|
357
|
+
try {
|
|
358
|
+
url = new URL(r.url, base);
|
|
359
|
+
}
|
|
360
|
+
catch {
|
|
361
|
+
return NOOP_HANDLE;
|
|
362
|
+
}
|
|
363
|
+
const sameOrigin = env.location ? url.origin === env.location.origin : false;
|
|
364
|
+
const method = (r.method ?? (r.procedure ? "POST" : "GET")).toUpperCase();
|
|
365
|
+
const start = env.now();
|
|
366
|
+
const sampled = this.sample();
|
|
367
|
+
const traceId = newTraceId(env);
|
|
368
|
+
const spanId = newSpanId(env);
|
|
369
|
+
const headers = {};
|
|
370
|
+
if (sampled) {
|
|
371
|
+
const traceparent = `00-${traceId}-${spanId}-01`;
|
|
372
|
+
const pick = this.opts.getTraceHeaders ?? ((_u, c) => (c.sameOrigin ? { traceparent: c.traceparent } : undefined));
|
|
373
|
+
try {
|
|
374
|
+
Object.assign(headers, pick(url, { traceparent, sameOrigin }) ?? {});
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
/* a throwing hook propagates nothing */
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
let ended = false;
|
|
381
|
+
return {
|
|
382
|
+
headers,
|
|
383
|
+
end: (e) => {
|
|
384
|
+
if (ended)
|
|
385
|
+
return;
|
|
386
|
+
ended = true;
|
|
387
|
+
try {
|
|
388
|
+
this.finish({ r, url, sameOrigin, method, start, sampled, traceId, spanId, propagated: "traceparent" in headers }, e);
|
|
389
|
+
}
|
|
390
|
+
catch {
|
|
391
|
+
/* never into the host */
|
|
392
|
+
}
|
|
393
|
+
},
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
finish(s, e) {
|
|
397
|
+
const { env } = this;
|
|
398
|
+
const end = env.now();
|
|
399
|
+
const online = env.navigator?.onLine !== false;
|
|
400
|
+
const cls = classify({ error: e.error, status: e.status, online, sameOrigin: s.sameOrigin });
|
|
401
|
+
const connectCode = e.error === undefined ? (s.r.procedure ? "ok" : undefined) : isConnectError(e.error) ? codeName(e.error.code) : undefined;
|
|
402
|
+
const serverTrace = normaliseTraceId(e.traceId ?? traceIdFrom(e.error)) ?? (s.propagated ? s.traceId : undefined);
|
|
403
|
+
const host = s.url.host;
|
|
404
|
+
// Breadcrumb: procedure (or method + host) and an outcome; never a payload.
|
|
405
|
+
if (s.r.procedure)
|
|
406
|
+
this.breadcrumb({ type: "rpc", procedure: s.r.procedure, code: connectCode ?? (cls ?? "error") });
|
|
407
|
+
else
|
|
408
|
+
this.breadcrumb({ type: "fetch", method: s.method, host, status: e.status !== undefined ? String(e.status) : (cls ?? "error") });
|
|
409
|
+
if (cls === null)
|
|
410
|
+
this.lastSuccessAt = end;
|
|
411
|
+
if (s.sampled) {
|
|
412
|
+
const attrs = {
|
|
413
|
+
...this.extraAttrs,
|
|
414
|
+
"session.id": this.sessionId,
|
|
415
|
+
"server.address": s.url.hostname,
|
|
416
|
+
"server.port": s.url.port ? Number(s.url.port) : undefined,
|
|
417
|
+
"rpc.system": s.r.procedure ? "connect_rpc" : undefined,
|
|
418
|
+
"rpc.method": s.r.procedure,
|
|
419
|
+
"rpc.service": s.r.procedure?.split("/")[0],
|
|
420
|
+
"rpc.response.status_code": connectCode,
|
|
421
|
+
"http.request.method": s.r.procedure ? undefined : s.method,
|
|
422
|
+
"http.response.status_code": e.status,
|
|
423
|
+
"error.type": cls && cls !== "maybe-cors" ? cls : e.error !== undefined ? (connectCode ?? errorParts(e.error).type) : undefined,
|
|
424
|
+
"url.path": this.currentPath(),
|
|
425
|
+
};
|
|
426
|
+
const failed = e.error !== undefined || (e.status !== undefined && e.status >= 500);
|
|
427
|
+
const span = clientSpan({
|
|
428
|
+
traceId: s.traceId,
|
|
429
|
+
spanId: s.spanId,
|
|
430
|
+
name: s.r.procedure ?? `HTTP ${s.method} ${host}`,
|
|
431
|
+
start: s.start,
|
|
432
|
+
end,
|
|
433
|
+
attrs,
|
|
434
|
+
error: failed ? (connectCode ?? (e.status !== undefined ? String(e.status) : errorParts(e.error).type)) : undefined,
|
|
435
|
+
});
|
|
436
|
+
this.enqueue({ k: "s", v: this.release, r: span });
|
|
437
|
+
}
|
|
438
|
+
if (cls === null)
|
|
439
|
+
return;
|
|
440
|
+
const emit = (errorType) => {
|
|
441
|
+
const suppressed = this.failures.take(`${host}|${s.r.procedure ?? s.method}|${errorType}`, end);
|
|
442
|
+
if (suppressed === undefined)
|
|
443
|
+
return;
|
|
444
|
+
const what = s.r.procedure ?? `${s.method} ${host}`;
|
|
445
|
+
this.log("WARN", `${what} failed: ${errorType}`, {
|
|
446
|
+
"event.name": "client.request.failed",
|
|
447
|
+
"server.address": s.url.hostname,
|
|
448
|
+
"rpc.method": s.r.procedure,
|
|
449
|
+
"http.request.method": s.r.procedure ? undefined : s.method,
|
|
450
|
+
"url.full": s.r.procedure ? undefined : s.url.origin + s.url.pathname,
|
|
451
|
+
"http.response.status_code": e.status,
|
|
452
|
+
"rpc.response.status_code": connectCode,
|
|
453
|
+
"error.type": errorType,
|
|
454
|
+
"client.online": online,
|
|
455
|
+
"client.since_last_success_ms": this.lastSuccessAt !== undefined ? Math.round(end - this.lastSuccessAt) : undefined,
|
|
456
|
+
"client.request.duration_ms": Math.round(end - s.start),
|
|
457
|
+
"client.request.suppressed_count": suppressed > 0 ? suppressed : undefined,
|
|
458
|
+
"http.response.header.x-trace-id": serverTrace,
|
|
459
|
+
}, serverTrace);
|
|
460
|
+
};
|
|
461
|
+
if (cls === "maybe-cors")
|
|
462
|
+
void probeCors(env.fetch, s.url.origin + s.url.pathname).then(emit, () => emit("network"));
|
|
463
|
+
else
|
|
464
|
+
emit(cls);
|
|
465
|
+
}
|
|
466
|
+
flush() {
|
|
467
|
+
return this.delivery.flush();
|
|
468
|
+
}
|
|
469
|
+
shutdown() {
|
|
470
|
+
try {
|
|
471
|
+
this.vitals?.finalize();
|
|
472
|
+
this.vitals?.stop();
|
|
473
|
+
this.delivery.hide();
|
|
474
|
+
this.delivery.stop();
|
|
475
|
+
for (const t of this.teardown.splice(0))
|
|
476
|
+
t();
|
|
477
|
+
}
|
|
478
|
+
catch {
|
|
479
|
+
/* never */
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
/**
|
|
484
|
+
* Build a client against an explicit environment. `init` is this over the
|
|
485
|
+
* real browser, plus the page-wide singleton; tests call it directly.
|
|
486
|
+
*/
|
|
487
|
+
export function createClient(opts = {}, env = browserEnv()) {
|
|
488
|
+
try {
|
|
489
|
+
const service = opts.service ?? meta(env, "lantern-service");
|
|
490
|
+
const release = opts.release ?? meta(env, "lantern-release") ?? "dev";
|
|
491
|
+
const endpoint = (opts.endpoint ?? DEFAULT_ENDPOINT).replace(/\/+$/, "");
|
|
492
|
+
const enabled = opts.enabled ?? (meta(env, "lantern-telemetry") !== "off" && !isLocalDevHost(env.location?.hostname));
|
|
493
|
+
if (!enabled)
|
|
494
|
+
return noopClient(service ?? "", release, endpoint);
|
|
495
|
+
// Not a browser page (a server render, a worker): nothing to observe, and
|
|
496
|
+
// a server must never report as a client.
|
|
497
|
+
if (!env.document || !env.location)
|
|
498
|
+
return noopClient(service ?? "", release, endpoint);
|
|
499
|
+
if (!service) {
|
|
500
|
+
env.warn("@xeonr/telemetry-web: no service name (pass `service`, or add <meta name=\"lantern-service\">); telemetry is off");
|
|
501
|
+
return noopClient("", release, endpoint);
|
|
502
|
+
}
|
|
503
|
+
const c = new Client(env, opts, service, release, endpoint);
|
|
504
|
+
c.start();
|
|
505
|
+
return c;
|
|
506
|
+
}
|
|
507
|
+
catch {
|
|
508
|
+
return noopClient();
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Interceptor } from "@connectrpc/connect";
|
|
2
|
+
import { type TelemetryClient } from "./index.ts";
|
|
3
|
+
export type ClientRef = TelemetryClient | (() => TelemetryClient | undefined);
|
|
4
|
+
/**
|
|
5
|
+
* A Connect interceptor reporting through `client` — by default the page's
|
|
6
|
+
* client, looked up per call, so the interceptor can be built before `init`
|
|
7
|
+
* runs (a transport created at module load). Put it first in the list, so it
|
|
8
|
+
* times everything the other interceptors do.
|
|
9
|
+
*/
|
|
10
|
+
export declare function telemetryInterceptor(client?: ClientRef): Interceptor;
|
|
11
|
+
//# sourceMappingURL=connect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.d.ts","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAGzE,MAAM,MAAM,SAAS,GAAG,eAAe,GAAG,CAAC,MAAM,eAAe,GAAG,SAAS,CAAC,CAAC;AAE9E;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,SAAS,GAAG,WAAW,CAiBpE"}
|
package/dist/connect.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// @xeonr/telemetry-web/connect — the ConnectRPC interceptor.
|
|
2
|
+
//
|
|
3
|
+
// import { telemetryInterceptor } from "@xeonr/telemetry-web/connect";
|
|
4
|
+
// createConnectTransport({ baseUrl, interceptors: [telemetryInterceptor()] });
|
|
5
|
+
//
|
|
6
|
+
// Every call becomes a breadcrumb (procedure + code, never a payload) and,
|
|
7
|
+
// when sampled, a CLIENT span named by the procedure. A call that gets no
|
|
8
|
+
// answer, times out or fails server-side (Unavailable, Internal, …) becomes a
|
|
9
|
+
// `client.request.failed` record. A same-origin call carries `traceparent`,
|
|
10
|
+
// so the browser span parents the server's trace at the edge.
|
|
11
|
+
//
|
|
12
|
+
// Only types are imported from @connectrpc/connect: this module adds nothing
|
|
13
|
+
// to a bundle but itself.
|
|
14
|
+
import { getClient, noopClient } from "./index.js";
|
|
15
|
+
import { traceIdFrom } from "./trace.js";
|
|
16
|
+
/**
|
|
17
|
+
* A Connect interceptor reporting through `client` — by default the page's
|
|
18
|
+
* client, looked up per call, so the interceptor can be built before `init`
|
|
19
|
+
* runs (a transport created at module load). Put it first in the list, so it
|
|
20
|
+
* times everything the other interceptors do.
|
|
21
|
+
*/
|
|
22
|
+
export function telemetryInterceptor(client) {
|
|
23
|
+
const resolve = () => (typeof client === "function" ? client() : client ?? getClient()) ?? noopClient();
|
|
24
|
+
return (next) => async (req) => {
|
|
25
|
+
const c = resolve();
|
|
26
|
+
if (!c.enabled)
|
|
27
|
+
return next(req);
|
|
28
|
+
const procedure = `${req.service.typeName}/${req.method.name}`;
|
|
29
|
+
const h = c.beginRequest({ url: req.url, procedure, method: req.requestMethod });
|
|
30
|
+
for (const [k, v] of Object.entries(h.headers))
|
|
31
|
+
if (!req.header.has(k))
|
|
32
|
+
req.header.set(k, v);
|
|
33
|
+
try {
|
|
34
|
+
const res = await next(req);
|
|
35
|
+
h.end({ traceId: res.header.get("x-trace-id") });
|
|
36
|
+
return res;
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
h.end({ error: err, traceId: traceIdFrom(err) });
|
|
40
|
+
throw err;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=connect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connect.js","sourceRoot":"","sources":["../src/connect.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,EAAE;AACF,yEAAyE;AACzE,iFAAiF;AACjF,EAAE;AACF,2EAA2E;AAC3E,0EAA0E;AAC1E,8EAA8E;AAC9E,4EAA4E;AAC5E,8DAA8D;AAC9D,EAAE;AACF,6EAA6E;AAC7E,0BAA0B;AAG1B,OAAO,EAAE,SAAS,EAAE,UAAU,EAAwB,MAAM,YAAY,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAIzC;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,MAAkB;IACrD,MAAM,OAAO,GAAG,GAAoB,EAAE,CAAC,CAAC,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC;IACzH,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QAC7B,MAAM,CAAC,GAAG,OAAO,EAAE,CAAC;QACpB,IAAI,CAAC,CAAC,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,SAAS,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC/D,MAAM,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC;QACjF,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;YAAE,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC7F,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;YAC5B,CAAC,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YACjD,OAAO,GAAG,CAAC;QACb,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,CAAC,CAAC,GAAG,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACjD,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|