@oconde/radar 0.2.0 → 0.4.1
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/CHANGELOG.md +27 -0
- package/README.md +21 -0
- package/dist/{client-CZHtsQAd.d.cts → client-DRZ7htMJ.d.cts} +27 -2
- package/dist/{client-DbBsXgpj.d.ts → client-FkXWx8sJ.d.ts} +27 -2
- package/dist/index.cjs +218 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +227 -30
- package/dist/index.js.map +1 -1
- package/dist/nest/index.cjs +218 -21
- package/dist/nest/index.cjs.map +1 -1
- package/dist/nest/index.d.cts +1 -1
- package/dist/nest/index.d.ts +1 -1
- package/dist/nest/index.js +227 -30
- package/dist/nest/index.js.map +1 -1
- package/dist/sveltekit/index.cjs +220 -23
- package/dist/sveltekit/index.cjs.map +1 -1
- package/dist/sveltekit/index.d.cts +1 -1
- package/dist/sveltekit/index.d.ts +1 -1
- package/dist/sveltekit/index.js +231 -34
- package/dist/sveltekit/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequestEvent, RequestHandler, Handle, HandleServerError } from '@sveltejs/kit';
|
|
2
|
-
import { R as RadarClient } from '../client-
|
|
2
|
+
import { R as RadarClient } from '../client-DRZ7htMJ.cjs';
|
|
3
3
|
import '../protocol/index.cjs';
|
|
4
4
|
|
|
5
5
|
declare function moveClientSourceMaps(buildDir?: string): number;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { RequestEvent, RequestHandler, Handle, HandleServerError } from '@sveltejs/kit';
|
|
2
|
-
import { R as RadarClient } from '../client-
|
|
2
|
+
import { R as RadarClient } from '../client-FkXWx8sJ.js';
|
|
3
3
|
import '../protocol/index.js';
|
|
4
4
|
|
|
5
5
|
declare function moveClientSourceMaps(buildDir?: string): number;
|
package/dist/sveltekit/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// src/sveltekit/index.ts
|
|
2
2
|
import { existsSync as existsSync2 } from "fs";
|
|
3
3
|
import { resolve as resolve3, sep as sep3 } from "path";
|
|
4
|
-
import { performance as
|
|
4
|
+
import { performance as performance5 } from "perf_hooks";
|
|
5
5
|
|
|
6
6
|
// src/context.ts
|
|
7
7
|
import { AsyncLocalStorage } from "async_hooks";
|
|
@@ -57,10 +57,10 @@ function requestIdFrom(incoming) {
|
|
|
57
57
|
// src/client.ts
|
|
58
58
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
59
59
|
import { hostname } from "os";
|
|
60
|
-
import { performance as
|
|
60
|
+
import { performance as performance4 } from "perf_hooks";
|
|
61
61
|
|
|
62
62
|
// src/express.ts
|
|
63
|
-
import { performance } from "perf_hooks";
|
|
63
|
+
import { performance as performance2 } from "perf_hooks";
|
|
64
64
|
|
|
65
65
|
// src/redact.ts
|
|
66
66
|
import { createHash, createHmac, randomBytes } from "crypto";
|
|
@@ -258,9 +258,18 @@ function requestPath(req) {
|
|
|
258
258
|
const end = url.indexOf("?");
|
|
259
259
|
return end >= 0 ? url.slice(0, end) : url;
|
|
260
260
|
}
|
|
261
|
+
function matchesRequest(pattern, path, route) {
|
|
262
|
+
const candidates = route === void 0 ? [path] : [path, route];
|
|
263
|
+
if (pattern instanceof RegExp) return candidates.some((value) => value.search(pattern) !== -1);
|
|
264
|
+
const prefix = pattern.endsWith("/") ? pattern : `${pattern}/`;
|
|
265
|
+
return candidates.some((value) => value === pattern || value.startsWith(prefix));
|
|
266
|
+
}
|
|
261
267
|
function requestRoute(req, route) {
|
|
262
268
|
if (route) return route;
|
|
263
|
-
|
|
269
|
+
if (typeof req.route?.path !== "string") return void 0;
|
|
270
|
+
const base = typeof req.baseUrl === "string" ? req.baseUrl.replace(/\/+$/, "") : "";
|
|
271
|
+
if (!base) return req.route.path;
|
|
272
|
+
return req.route.path === "/" ? base : `${base}${req.route.path}`;
|
|
264
273
|
}
|
|
265
274
|
var ROUTE_PARAM = /^:([A-Za-z_$][\w$]*)/;
|
|
266
275
|
function pathSegments(value) {
|
|
@@ -380,7 +389,7 @@ function createMiddleware(logger) {
|
|
|
380
389
|
let context;
|
|
381
390
|
try {
|
|
382
391
|
const requestId = requestIdFrom(headerValue(req.headers["x-request-id"]));
|
|
383
|
-
context = { requestId, startedAt:
|
|
392
|
+
context = { requestId, startedAt: performance2.now(), req };
|
|
384
393
|
res.setHeader("x-request-id", requestId);
|
|
385
394
|
if (logger.shouldLogRequest(req)) res.once("finish", () => logger.logHttpRequest(context, res.statusCode));
|
|
386
395
|
} catch {
|
|
@@ -394,6 +403,25 @@ function createMiddleware(logger) {
|
|
|
394
403
|
// src/options.ts
|
|
395
404
|
var DEFAULT_ENDPOINT = "https://radar-ingest.oconde.dev";
|
|
396
405
|
var LEVELS = ["debug", "info", "warn", "error"];
|
|
406
|
+
function patterns(value) {
|
|
407
|
+
if (!Array.isArray(value)) return [];
|
|
408
|
+
return value.flatMap((item) => {
|
|
409
|
+
if (item instanceof RegExp) return [item];
|
|
410
|
+
if (typeof item === "string" && item.trim() !== "") return [item.trim()];
|
|
411
|
+
return [];
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
function resolveTraceFetch(value) {
|
|
415
|
+
if (!value) return { enabled: false, propagateTo: [], ignore: [] };
|
|
416
|
+
if (value === true) return { enabled: true, propagateTo: [], ignore: [] };
|
|
417
|
+
return { enabled: true, propagateTo: patterns(value.propagateTo), ignore: patterns(value.ignore) };
|
|
418
|
+
}
|
|
419
|
+
function resolveLogRequests(value) {
|
|
420
|
+
if (value === false) return { enabled: false, include: [], exclude: [], sample: 1 };
|
|
421
|
+
if (value === void 0 || value === true || typeof value !== "object" || value === null) return { enabled: true, include: [], exclude: [], sample: 1 };
|
|
422
|
+
const sample = typeof value.sample === "number" && Number.isFinite(value.sample) && value.sample >= 0 && value.sample <= 1 ? value.sample : 1;
|
|
423
|
+
return { enabled: true, include: patterns(value.include), exclude: patterns(value.exclude), sample };
|
|
424
|
+
}
|
|
397
425
|
function resolveOptions(options = {}, env = process.env) {
|
|
398
426
|
const key = options.key?.trim() || void 0;
|
|
399
427
|
return {
|
|
@@ -406,9 +434,10 @@ function resolveOptions(options = {}, env = process.env) {
|
|
|
406
434
|
minLevel: options.minLevel && LEVELS.includes(options.minLevel) ? options.minLevel : "info",
|
|
407
435
|
redact: options.redact === "none" ? "none" : "mask",
|
|
408
436
|
requestDetail: options.requestDetail === "route" ? "route" : "full",
|
|
409
|
-
logRequests: options.logRequests
|
|
437
|
+
logRequests: resolveLogRequests(options.logRequests),
|
|
410
438
|
ignorePaths: options.ignorePaths ?? ["/healthz", "/health"],
|
|
411
439
|
captureUnhandled: options.captureUnhandled ?? true,
|
|
440
|
+
traceFetch: resolveTraceFetch(options.traceFetch),
|
|
412
441
|
debug: options.debug ?? false
|
|
413
442
|
};
|
|
414
443
|
}
|
|
@@ -476,6 +505,7 @@ var IDENTIFIER = "[A-Za-z_$][\\w$]*";
|
|
|
476
505
|
var MAX_LINES_UP = 400;
|
|
477
506
|
var MAX_HEADER_LINES = 6;
|
|
478
507
|
var MAX_NAME_LENGTH = 100;
|
|
508
|
+
var MAX_COMMENT_LINES = 40;
|
|
479
509
|
var CONTROL_BLOCK = /^\s*(?:\}\s*)?(?:if|else|for|while|do|switch|try|catch|finally|with)\b/;
|
|
480
510
|
var CLASS_BODY = new RegExp(`\\bclass\\s+${IDENTIFIER}`);
|
|
481
511
|
var MARKUP_BOUNDARY = /<\/?(?:script|style|template)\b/i;
|
|
@@ -488,8 +518,58 @@ var NAME_PATTERNS = [
|
|
|
488
518
|
];
|
|
489
519
|
var METHOD_PATTERN = new RegExp(`^\\s*(?:(?:export|default|public|private|protected|static|async|override|readonly|get|set)\\s+)*\\*?\\s*(${IDENTIFIER})\\s*(?:<[^>]*>)?\\s*\\([^]*\\)\\s*(?::\\s*[^{]+)?$`);
|
|
490
520
|
var ANONYMOUS_FUNCTION = /\bfunction\b|=>/;
|
|
491
|
-
|
|
492
|
-
|
|
521
|
+
var STRING_LITERAL = /(["'`])(?:\\.|(?!\1)[^\\])*\1/g;
|
|
522
|
+
function lineCommentAt(text, from) {
|
|
523
|
+
for (let index = text.indexOf("//", from); index >= 0; index = text.indexOf("//", index + 1)) {
|
|
524
|
+
if (index === 0 || text[index - 1] !== ":") return index;
|
|
525
|
+
}
|
|
526
|
+
return -1;
|
|
527
|
+
}
|
|
528
|
+
function blockCommentAt(text, from) {
|
|
529
|
+
for (let index = text.indexOf("/*", from); index >= 0; index = text.indexOf("/*", index + 1)) {
|
|
530
|
+
if (index === 0 || text[index - 1] !== "\\") return index;
|
|
531
|
+
}
|
|
532
|
+
return -1;
|
|
533
|
+
}
|
|
534
|
+
function stripComments(text, insideComment, closesLater) {
|
|
535
|
+
let code = "";
|
|
536
|
+
let position = 0;
|
|
537
|
+
let inside = insideComment;
|
|
538
|
+
while (position < text.length) {
|
|
539
|
+
if (inside) {
|
|
540
|
+
const end = text.indexOf("*/", position);
|
|
541
|
+
if (end < 0) return { code, insideComment: true };
|
|
542
|
+
inside = false;
|
|
543
|
+
position = end + 2;
|
|
544
|
+
continue;
|
|
545
|
+
}
|
|
546
|
+
const block = blockCommentAt(text, position);
|
|
547
|
+
const line = lineCommentAt(text, position);
|
|
548
|
+
if (line >= 0 && (block < 0 || line < block)) return { code: code + text.slice(position, line), insideComment: false };
|
|
549
|
+
if (block < 0) return { code: code + text.slice(position), insideComment: false };
|
|
550
|
+
if (text.indexOf("*/", block + 2) < 0 && !closesLater()) {
|
|
551
|
+
code += text.slice(position, block + 2);
|
|
552
|
+
position = block + 2;
|
|
553
|
+
continue;
|
|
554
|
+
}
|
|
555
|
+
code += text.slice(position, block);
|
|
556
|
+
inside = true;
|
|
557
|
+
position = block + 2;
|
|
558
|
+
}
|
|
559
|
+
return { code, insideComment: inside };
|
|
560
|
+
}
|
|
561
|
+
function codeLines(lines, from, start, column) {
|
|
562
|
+
const plain = lines.slice(from, start + 1).map((line) => line.replace(STRING_LITERAL, '""'));
|
|
563
|
+
const closesWithin = (index) => plain.slice(index + 1, index + 1 + MAX_COMMENT_LINES).some((line) => line.includes("*/"));
|
|
564
|
+
const result = [];
|
|
565
|
+
let insideComment = false;
|
|
566
|
+
for (let index = 0; index < plain.length; index++) {
|
|
567
|
+
const text = index === plain.length - 1 && column ? (lines[start] ?? "").slice(0, Math.max(0, column - 1)).replace(STRING_LITERAL, '""') : plain[index] ?? "";
|
|
568
|
+
const stripped = stripComments(text, insideComment, () => closesWithin(index));
|
|
569
|
+
insideComment = stripped.insideComment;
|
|
570
|
+
result.push(stripped.code);
|
|
571
|
+
}
|
|
572
|
+
return result;
|
|
493
573
|
}
|
|
494
574
|
function parenBalance(text) {
|
|
495
575
|
let balance = 0;
|
|
@@ -499,17 +579,17 @@ function parenBalance(text) {
|
|
|
499
579
|
}
|
|
500
580
|
return balance;
|
|
501
581
|
}
|
|
502
|
-
function headerOf(
|
|
582
|
+
function headerOf(code, index, prefix) {
|
|
503
583
|
let header = prefix;
|
|
504
584
|
for (let previous = index - 1; previous >= 0 && previous >= index - MAX_HEADER_LINES; previous--) {
|
|
505
585
|
if (header.trim() !== "" && parenBalance(header) >= 0) break;
|
|
506
|
-
header = `${
|
|
586
|
+
header = `${code[previous] ?? ""} ${header}`;
|
|
507
587
|
}
|
|
508
588
|
return header;
|
|
509
589
|
}
|
|
510
590
|
function nameIn(header) {
|
|
511
|
-
const
|
|
512
|
-
for (const pattern of
|
|
591
|
+
const patterns2 = ANONYMOUS_FUNCTION.test(header) ? NAME_PATTERNS : [...NAME_PATTERNS, METHOD_PATTERN];
|
|
592
|
+
for (const pattern of patterns2) {
|
|
513
593
|
const name = pattern.exec(header)?.[1];
|
|
514
594
|
if (name && !KEYWORDS.has(name)) return name.slice(0, MAX_NAME_LENGTH);
|
|
515
595
|
}
|
|
@@ -518,11 +598,12 @@ function nameIn(header) {
|
|
|
518
598
|
function enclosingFunctionName(lines, line, column) {
|
|
519
599
|
const start = line - 1;
|
|
520
600
|
if (start < 0 || start >= lines.length) return void 0;
|
|
601
|
+
const from = Math.max(0, start - MAX_LINES_UP - MAX_HEADER_LINES);
|
|
602
|
+
const cleaned = codeLines(lines, from, start, column);
|
|
521
603
|
let depth = 0;
|
|
522
604
|
for (let index = start; index >= 0 && index >= start - MAX_LINES_UP; index--) {
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
const code = codeOnly(index === start && column ? raw.slice(0, Math.max(0, column - 1)) : raw);
|
|
605
|
+
if (index < start && MARKUP_BOUNDARY.test(lines[index] ?? "")) return void 0;
|
|
606
|
+
const code = cleaned[index - from] ?? "";
|
|
526
607
|
for (let position = code.length - 1; position >= 0; position--) {
|
|
527
608
|
const char = code[position];
|
|
528
609
|
if (char === "}") {
|
|
@@ -532,7 +613,7 @@ function enclosingFunctionName(lines, line, column) {
|
|
|
532
613
|
depth -= 1;
|
|
533
614
|
continue;
|
|
534
615
|
}
|
|
535
|
-
const header = headerOf(
|
|
616
|
+
const header = headerOf(cleaned, index - from, code.slice(0, position));
|
|
536
617
|
if (CLASS_BODY.test(header)) return void 0;
|
|
537
618
|
if (CONTROL_BLOCK.test(header)) continue;
|
|
538
619
|
const name = nameIn(header);
|
|
@@ -797,20 +878,118 @@ function safeStringify(value) {
|
|
|
797
878
|
}
|
|
798
879
|
}
|
|
799
880
|
|
|
800
|
-
// src/transport.ts
|
|
801
|
-
import { promisify } from "util";
|
|
802
|
-
import { gzip } from "zlib";
|
|
803
|
-
|
|
804
881
|
// src/util.ts
|
|
805
|
-
import { performance as
|
|
882
|
+
import { performance as performance3 } from "perf_hooks";
|
|
806
883
|
function describeError(error) {
|
|
807
884
|
return error instanceof Error ? error.message : String(error);
|
|
808
885
|
}
|
|
809
886
|
function elapsedSince(startedAt) {
|
|
810
|
-
return Math.round(
|
|
887
|
+
return Math.round(performance3.now() - startedAt);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
// src/trace-fetch.ts
|
|
891
|
+
var WRAPPED = /* @__PURE__ */ Symbol.for("@oconde/radar.fetch");
|
|
892
|
+
var REQUEST_ID_HEADER = "x-request-id";
|
|
893
|
+
var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
894
|
+
var TELEGRAM_BOT = /^bot\d{5,}:[\w-]{20,}$/;
|
|
895
|
+
var TOKEN_LIKE = /^[\w\-.~+=]{20,}$/;
|
|
896
|
+
function secretSegment(segment) {
|
|
897
|
+
if (UUID.test(segment)) return false;
|
|
898
|
+
if (TELEGRAM_BOT.test(segment) || looksLikeCredential(segment)) return true;
|
|
899
|
+
return TOKEN_LIKE.test(segment) && /[A-Za-z]/.test(segment) && /\d/.test(segment);
|
|
900
|
+
}
|
|
901
|
+
function outboundPath(pathname, mode) {
|
|
902
|
+
if (mode === "none") return pathname;
|
|
903
|
+
return pathname.split("/").map((segment) => {
|
|
904
|
+
let decoded = segment;
|
|
905
|
+
try {
|
|
906
|
+
decoded = decodeURIComponent(segment);
|
|
907
|
+
} catch {
|
|
908
|
+
decoded = segment;
|
|
909
|
+
}
|
|
910
|
+
return secretSegment(decoded) ? maskValue(decoded, false) : segment;
|
|
911
|
+
}).join("/");
|
|
912
|
+
}
|
|
913
|
+
function failureOf(error) {
|
|
914
|
+
const message = describeError(error);
|
|
915
|
+
const cause = error instanceof Error ? error.cause : void 0;
|
|
916
|
+
const detail = typeof cause?.code === "string" ? cause.code : typeof cause?.message === "string" ? cause.message : "";
|
|
917
|
+
return detail && !message.includes(detail) ? `${message} (${detail})` : message;
|
|
918
|
+
}
|
|
919
|
+
function urlOf(input) {
|
|
920
|
+
try {
|
|
921
|
+
if (typeof input === "string") return new URL(input);
|
|
922
|
+
if (input instanceof URL) return input;
|
|
923
|
+
return new URL(input.url);
|
|
924
|
+
} catch {
|
|
925
|
+
return null;
|
|
926
|
+
}
|
|
927
|
+
}
|
|
928
|
+
function originOf(value) {
|
|
929
|
+
try {
|
|
930
|
+
return new URL(value).origin;
|
|
931
|
+
} catch {
|
|
932
|
+
return null;
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
function hostMatches(url, host) {
|
|
936
|
+
const wanted = host.trim().toLowerCase();
|
|
937
|
+
if (wanted.startsWith(".")) return url.hostname.toLowerCase().endsWith(wanted);
|
|
938
|
+
return url.host.toLowerCase() === wanted || url.hostname.toLowerCase() === wanted;
|
|
939
|
+
}
|
|
940
|
+
function targets(url, target) {
|
|
941
|
+
if (target instanceof RegExp) return url.host.search(target) !== -1;
|
|
942
|
+
return hostMatches(url, target);
|
|
943
|
+
}
|
|
944
|
+
function ignored(url, target) {
|
|
945
|
+
if (target instanceof RegExp) return `${url.host}${url.pathname}`.search(target) !== -1;
|
|
946
|
+
return hostMatches(url, target);
|
|
947
|
+
}
|
|
948
|
+
function isPlainObject(value) {
|
|
949
|
+
if (value === null || typeof value !== "object") return false;
|
|
950
|
+
const prototype = Object.getPrototypeOf(value);
|
|
951
|
+
return prototype === Object.prototype || prototype === null;
|
|
952
|
+
}
|
|
953
|
+
function withRequestId(input, init, requestId) {
|
|
954
|
+
const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : void 0));
|
|
955
|
+
if (headers.has(REQUEST_ID_HEADER)) return [input, init];
|
|
956
|
+
headers.set(REQUEST_ID_HEADER, requestId);
|
|
957
|
+
if (init === void 0 || isPlainObject(init)) return [input, { ...init, headers }];
|
|
958
|
+
return [new Request(input, init), { headers }];
|
|
959
|
+
}
|
|
960
|
+
function traceFetch(config) {
|
|
961
|
+
const current = globalThis.fetch;
|
|
962
|
+
if (typeof current !== "function" || current[WRAPPED]) return () => void 0;
|
|
963
|
+
const original = current;
|
|
964
|
+
const radarOrigin = originOf(config.endpoint);
|
|
965
|
+
const traced = async (input, init) => {
|
|
966
|
+
const url = urlOf(input);
|
|
967
|
+
if (!url || url.origin === radarOrigin || url.protocol !== "http:" && url.protocol !== "https:") return original(input, init);
|
|
968
|
+
const method = (init?.method ?? (input instanceof Request ? input.method : "GET")).toUpperCase();
|
|
969
|
+
const context = currentContext();
|
|
970
|
+
const [nextInput, nextInit] = context && config.propagateTo.some((target) => targets(url, target)) ? withRequestId(input, init, context.requestId) : [input, init];
|
|
971
|
+
if (config.ignore?.some((target) => ignored(url, target))) return original(nextInput, nextInit);
|
|
972
|
+
const attrs = { method, host: url.host, path: outboundPath(url.pathname, config.redact) };
|
|
973
|
+
const started = performance.now();
|
|
974
|
+
try {
|
|
975
|
+
const response = await original(nextInput, nextInit);
|
|
976
|
+
config.record(response.status >= 500 ? "error" : response.status >= 400 ? "warn" : "info", { ...attrs, status: response.status, durationMs: elapsedSince(started) });
|
|
977
|
+
return response;
|
|
978
|
+
} catch (error) {
|
|
979
|
+
config.record("error", { ...attrs, error: failureOf(error), durationMs: elapsedSince(started) });
|
|
980
|
+
throw error;
|
|
981
|
+
}
|
|
982
|
+
};
|
|
983
|
+
Object.defineProperty(traced, WRAPPED, { value: original });
|
|
984
|
+
globalThis.fetch = traced;
|
|
985
|
+
return () => {
|
|
986
|
+
if (globalThis.fetch === traced) globalThis.fetch = original;
|
|
987
|
+
};
|
|
811
988
|
}
|
|
812
989
|
|
|
813
990
|
// src/transport.ts
|
|
991
|
+
import { promisify } from "util";
|
|
992
|
+
import { gzip } from "zlib";
|
|
814
993
|
var gzipAsync = promisify(gzip);
|
|
815
994
|
var MAX_BATCH_BYTES = 9e5;
|
|
816
995
|
var GZIP_THRESHOLD_BYTES = 8192;
|
|
@@ -1038,7 +1217,7 @@ function withTimeout(promise, ms) {
|
|
|
1038
1217
|
|
|
1039
1218
|
// src/version.ts
|
|
1040
1219
|
var SDK_NAME = "@oconde/radar";
|
|
1041
|
-
var SDK_VERSION = true ? "0.
|
|
1220
|
+
var SDK_VERSION = true ? "0.4.1" : "0.0.0-dev";
|
|
1042
1221
|
|
|
1043
1222
|
// src/client.ts
|
|
1044
1223
|
var MAX_CHECK_IN_DURATION_MS = 7 * 864e5;
|
|
@@ -1050,6 +1229,7 @@ var RadarClient = class {
|
|
|
1050
1229
|
initialized = false;
|
|
1051
1230
|
closed = false;
|
|
1052
1231
|
captured = /* @__PURE__ */ new WeakSet();
|
|
1232
|
+
restoreFetch = null;
|
|
1053
1233
|
get isEnabled() {
|
|
1054
1234
|
return this.transport !== null && !this.closed;
|
|
1055
1235
|
}
|
|
@@ -1077,6 +1257,15 @@ var RadarClient = class {
|
|
|
1077
1257
|
});
|
|
1078
1258
|
}
|
|
1079
1259
|
if (this.options.captureUnhandled && (this.transport || this.options.console)) installProcessHandlers(this);
|
|
1260
|
+
if (this.options.traceFetch.enabled && (this.transport || this.options.console)) {
|
|
1261
|
+
this.restoreFetch = traceFetch({
|
|
1262
|
+
endpoint: this.options.endpoint,
|
|
1263
|
+
propagateTo: this.options.traceFetch.propagateTo,
|
|
1264
|
+
ignore: this.options.traceFetch.ignore,
|
|
1265
|
+
redact: this.options.redact,
|
|
1266
|
+
record: (level, attrs) => this.safely(() => this.emitLog(level, "http.client", attrs))
|
|
1267
|
+
});
|
|
1268
|
+
}
|
|
1080
1269
|
} catch (error) {
|
|
1081
1270
|
this.debugWarn(`radar.init falhou: ${describeError(error)}`);
|
|
1082
1271
|
}
|
|
@@ -1120,7 +1309,7 @@ var RadarClient = class {
|
|
|
1120
1309
|
}
|
|
1121
1310
|
async track(name, fn, data) {
|
|
1122
1311
|
const execute = async () => {
|
|
1123
|
-
const started =
|
|
1312
|
+
const started = performance4.now();
|
|
1124
1313
|
try {
|
|
1125
1314
|
const result = await fn();
|
|
1126
1315
|
this.info(name, { ...data, durationMs: elapsedSince(started), ok: true });
|
|
@@ -1132,10 +1321,10 @@ var RadarClient = class {
|
|
|
1132
1321
|
}
|
|
1133
1322
|
};
|
|
1134
1323
|
if (currentContext()) return execute();
|
|
1135
|
-
return runWithContext({ requestId: randomUUID2(), startedAt:
|
|
1324
|
+
return runWithContext({ requestId: randomUUID2(), startedAt: performance4.now() }, execute);
|
|
1136
1325
|
}
|
|
1137
1326
|
withContext(fn, options = {}) {
|
|
1138
|
-
return runWithContext({ requestId: requestIdFrom(options.requestId), startedAt:
|
|
1327
|
+
return runWithContext({ requestId: requestIdFrom(options.requestId), startedAt: performance4.now() }, fn);
|
|
1139
1328
|
}
|
|
1140
1329
|
async checkIn(slug, status, options = {}) {
|
|
1141
1330
|
try {
|
|
@@ -1163,7 +1352,7 @@ var RadarClient = class {
|
|
|
1163
1352
|
}
|
|
1164
1353
|
async cron(slug, fn) {
|
|
1165
1354
|
const checkInId = randomUUID2();
|
|
1166
|
-
const started =
|
|
1355
|
+
const started = performance4.now();
|
|
1167
1356
|
const execute = async () => {
|
|
1168
1357
|
await this.checkIn(slug, "in_progress", { checkInId });
|
|
1169
1358
|
try {
|
|
@@ -1183,22 +1372,28 @@ var RadarClient = class {
|
|
|
1183
1372
|
return createMiddleware(this);
|
|
1184
1373
|
}
|
|
1185
1374
|
shouldLogRequest(req) {
|
|
1186
|
-
return this.options.logRequests && !this.options.ignorePaths.includes(requestPath(req));
|
|
1375
|
+
return this.options.logRequests.enabled && !this.options.ignorePaths.includes(requestPath(req));
|
|
1187
1376
|
}
|
|
1188
1377
|
logHttpRequest(context, status) {
|
|
1189
1378
|
this.safely(() => {
|
|
1190
1379
|
const req = context.req;
|
|
1191
1380
|
if (!req) return;
|
|
1192
|
-
const level = status >= 500 ? "error" : status >= 400 ? "warn" : "info";
|
|
1193
1381
|
const route = requestRoute(req, context.route);
|
|
1382
|
+
const path = requestPath(req);
|
|
1383
|
+
const { include, exclude, sample } = this.options.logRequests;
|
|
1384
|
+
if (include.length > 0 && !include.some((pattern) => matchesRequest(pattern, path, route))) return;
|
|
1385
|
+
if (exclude.some((pattern) => matchesRequest(pattern, path, route))) return;
|
|
1386
|
+
if (sample < 1 && Math.random() >= sample) return;
|
|
1387
|
+
const level = status >= 500 ? "error" : status >= 400 ? "warn" : "info";
|
|
1194
1388
|
runWithContext(
|
|
1195
1389
|
context,
|
|
1196
1390
|
() => this.emitLog(level, "http.request", {
|
|
1197
1391
|
method: (req.method ?? "GET").toUpperCase(),
|
|
1198
1392
|
...route ? { route } : {},
|
|
1199
|
-
...this.options.requestDetail === "full" ? { path: redactPath(
|
|
1393
|
+
...this.options.requestDetail === "full" ? { path: redactPath(path, pathParams(req, path), this.options.redact) } : {},
|
|
1200
1394
|
status,
|
|
1201
|
-
durationMs: elapsedSince(context.startedAt)
|
|
1395
|
+
durationMs: elapsedSince(context.startedAt),
|
|
1396
|
+
...sample < 1 ? { sampleRate: sample } : {}
|
|
1202
1397
|
})
|
|
1203
1398
|
);
|
|
1204
1399
|
});
|
|
@@ -1213,6 +1408,8 @@ var RadarClient = class {
|
|
|
1213
1408
|
async close(timeoutMs = 2e3) {
|
|
1214
1409
|
if (this.closed) return;
|
|
1215
1410
|
await this.flush(timeoutMs);
|
|
1411
|
+
this.restoreFetch?.();
|
|
1412
|
+
this.restoreFetch = null;
|
|
1216
1413
|
this.closed = true;
|
|
1217
1414
|
this.transport?.stop();
|
|
1218
1415
|
}
|
|
@@ -1594,9 +1791,9 @@ function contextFor2(event, chooseRequestId) {
|
|
|
1594
1791
|
};
|
|
1595
1792
|
const route = routeName(event.route.id);
|
|
1596
1793
|
const chosen = chooseRequestId?.(event);
|
|
1597
|
-
return { requestId: requestIdFrom(chosen || event.request.headers.get("x-request-id")), startedAt:
|
|
1794
|
+
return { requestId: requestIdFrom(chosen || event.request.headers.get("x-request-id")), startedAt: performance5.now(), req, ...route ? { route } : {} };
|
|
1598
1795
|
}
|
|
1599
|
-
function
|
|
1796
|
+
function withRequestId2(response, requestId) {
|
|
1600
1797
|
try {
|
|
1601
1798
|
response.headers.set("x-request-id", requestId);
|
|
1602
1799
|
return response;
|
|
@@ -1628,7 +1825,7 @@ function radarHandle(options = {}) {
|
|
|
1628
1825
|
if (client.shouldLogRequest(req)) client.logHttpRequest(context, 500);
|
|
1629
1826
|
throw error;
|
|
1630
1827
|
}
|
|
1631
|
-
const tagged =
|
|
1828
|
+
const tagged = withRequestId2(response, context.requestId);
|
|
1632
1829
|
if (client.shouldLogRequest(req)) client.logHttpRequest(context, tagged.status);
|
|
1633
1830
|
return tagged;
|
|
1634
1831
|
});
|