@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
package/dist/nest/index.js
CHANGED
|
@@ -78,10 +78,10 @@ function requestIdFrom(incoming) {
|
|
|
78
78
|
// src/client.ts
|
|
79
79
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
80
80
|
import { hostname } from "os";
|
|
81
|
-
import { performance as
|
|
81
|
+
import { performance as performance4 } from "perf_hooks";
|
|
82
82
|
|
|
83
83
|
// src/express.ts
|
|
84
|
-
import { performance } from "perf_hooks";
|
|
84
|
+
import { performance as performance2 } from "perf_hooks";
|
|
85
85
|
|
|
86
86
|
// src/redact.ts
|
|
87
87
|
import { createHash, createHmac, randomBytes } from "crypto";
|
|
@@ -279,9 +279,18 @@ function requestPath(req) {
|
|
|
279
279
|
const end = url.indexOf("?");
|
|
280
280
|
return end >= 0 ? url.slice(0, end) : url;
|
|
281
281
|
}
|
|
282
|
+
function matchesRequest(pattern, path, route) {
|
|
283
|
+
const candidates = route === void 0 ? [path] : [path, route];
|
|
284
|
+
if (pattern instanceof RegExp) return candidates.some((value) => value.search(pattern) !== -1);
|
|
285
|
+
const prefix = pattern.endsWith("/") ? pattern : `${pattern}/`;
|
|
286
|
+
return candidates.some((value) => value === pattern || value.startsWith(prefix));
|
|
287
|
+
}
|
|
282
288
|
function requestRoute(req, route) {
|
|
283
289
|
if (route) return route;
|
|
284
|
-
|
|
290
|
+
if (typeof req.route?.path !== "string") return void 0;
|
|
291
|
+
const base = typeof req.baseUrl === "string" ? req.baseUrl.replace(/\/+$/, "") : "";
|
|
292
|
+
if (!base) return req.route.path;
|
|
293
|
+
return req.route.path === "/" ? base : `${base}${req.route.path}`;
|
|
285
294
|
}
|
|
286
295
|
var ROUTE_PARAM = /^:([A-Za-z_$][\w$]*)/;
|
|
287
296
|
function pathSegments(value) {
|
|
@@ -401,7 +410,7 @@ function createMiddleware(logger) {
|
|
|
401
410
|
let context;
|
|
402
411
|
try {
|
|
403
412
|
const requestId = requestIdFrom(headerValue(req.headers["x-request-id"]));
|
|
404
|
-
context = { requestId, startedAt:
|
|
413
|
+
context = { requestId, startedAt: performance2.now(), req };
|
|
405
414
|
res.setHeader("x-request-id", requestId);
|
|
406
415
|
if (logger.shouldLogRequest(req)) res.once("finish", () => logger.logHttpRequest(context, res.statusCode));
|
|
407
416
|
} catch {
|
|
@@ -415,6 +424,25 @@ function createMiddleware(logger) {
|
|
|
415
424
|
// src/options.ts
|
|
416
425
|
var DEFAULT_ENDPOINT = "https://radar-ingest.oconde.dev";
|
|
417
426
|
var LEVELS = ["debug", "info", "warn", "error"];
|
|
427
|
+
function patterns(value) {
|
|
428
|
+
if (!Array.isArray(value)) return [];
|
|
429
|
+
return value.flatMap((item) => {
|
|
430
|
+
if (item instanceof RegExp) return [item];
|
|
431
|
+
if (typeof item === "string" && item.trim() !== "") return [item.trim()];
|
|
432
|
+
return [];
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
function resolveTraceFetch(value) {
|
|
436
|
+
if (!value) return { enabled: false, propagateTo: [], ignore: [] };
|
|
437
|
+
if (value === true) return { enabled: true, propagateTo: [], ignore: [] };
|
|
438
|
+
return { enabled: true, propagateTo: patterns(value.propagateTo), ignore: patterns(value.ignore) };
|
|
439
|
+
}
|
|
440
|
+
function resolveLogRequests(value) {
|
|
441
|
+
if (value === false) return { enabled: false, include: [], exclude: [], sample: 1 };
|
|
442
|
+
if (value === void 0 || value === true || typeof value !== "object" || value === null) return { enabled: true, include: [], exclude: [], sample: 1 };
|
|
443
|
+
const sample = typeof value.sample === "number" && Number.isFinite(value.sample) && value.sample >= 0 && value.sample <= 1 ? value.sample : 1;
|
|
444
|
+
return { enabled: true, include: patterns(value.include), exclude: patterns(value.exclude), sample };
|
|
445
|
+
}
|
|
418
446
|
function resolveOptions(options = {}, env = process.env) {
|
|
419
447
|
const key = options.key?.trim() || void 0;
|
|
420
448
|
return {
|
|
@@ -427,9 +455,10 @@ function resolveOptions(options = {}, env = process.env) {
|
|
|
427
455
|
minLevel: options.minLevel && LEVELS.includes(options.minLevel) ? options.minLevel : "info",
|
|
428
456
|
redact: options.redact === "none" ? "none" : "mask",
|
|
429
457
|
requestDetail: options.requestDetail === "route" ? "route" : "full",
|
|
430
|
-
logRequests: options.logRequests
|
|
458
|
+
logRequests: resolveLogRequests(options.logRequests),
|
|
431
459
|
ignorePaths: options.ignorePaths ?? ["/healthz", "/health"],
|
|
432
460
|
captureUnhandled: options.captureUnhandled ?? true,
|
|
461
|
+
traceFetch: resolveTraceFetch(options.traceFetch),
|
|
433
462
|
debug: options.debug ?? false
|
|
434
463
|
};
|
|
435
464
|
}
|
|
@@ -497,6 +526,7 @@ var IDENTIFIER = "[A-Za-z_$][\\w$]*";
|
|
|
497
526
|
var MAX_LINES_UP = 400;
|
|
498
527
|
var MAX_HEADER_LINES = 6;
|
|
499
528
|
var MAX_NAME_LENGTH = 100;
|
|
529
|
+
var MAX_COMMENT_LINES = 40;
|
|
500
530
|
var CONTROL_BLOCK = /^\s*(?:\}\s*)?(?:if|else|for|while|do|switch|try|catch|finally|with)\b/;
|
|
501
531
|
var CLASS_BODY = new RegExp(`\\bclass\\s+${IDENTIFIER}`);
|
|
502
532
|
var MARKUP_BOUNDARY = /<\/?(?:script|style|template)\b/i;
|
|
@@ -509,8 +539,58 @@ var NAME_PATTERNS = [
|
|
|
509
539
|
];
|
|
510
540
|
var METHOD_PATTERN = new RegExp(`^\\s*(?:(?:export|default|public|private|protected|static|async|override|readonly|get|set)\\s+)*\\*?\\s*(${IDENTIFIER})\\s*(?:<[^>]*>)?\\s*\\([^]*\\)\\s*(?::\\s*[^{]+)?$`);
|
|
511
541
|
var ANONYMOUS_FUNCTION = /\bfunction\b|=>/;
|
|
512
|
-
|
|
513
|
-
|
|
542
|
+
var STRING_LITERAL = /(["'`])(?:\\.|(?!\1)[^\\])*\1/g;
|
|
543
|
+
function lineCommentAt(text, from) {
|
|
544
|
+
for (let index = text.indexOf("//", from); index >= 0; index = text.indexOf("//", index + 1)) {
|
|
545
|
+
if (index === 0 || text[index - 1] !== ":") return index;
|
|
546
|
+
}
|
|
547
|
+
return -1;
|
|
548
|
+
}
|
|
549
|
+
function blockCommentAt(text, from) {
|
|
550
|
+
for (let index = text.indexOf("/*", from); index >= 0; index = text.indexOf("/*", index + 1)) {
|
|
551
|
+
if (index === 0 || text[index - 1] !== "\\") return index;
|
|
552
|
+
}
|
|
553
|
+
return -1;
|
|
554
|
+
}
|
|
555
|
+
function stripComments(text, insideComment, closesLater) {
|
|
556
|
+
let code = "";
|
|
557
|
+
let position = 0;
|
|
558
|
+
let inside = insideComment;
|
|
559
|
+
while (position < text.length) {
|
|
560
|
+
if (inside) {
|
|
561
|
+
const end = text.indexOf("*/", position);
|
|
562
|
+
if (end < 0) return { code, insideComment: true };
|
|
563
|
+
inside = false;
|
|
564
|
+
position = end + 2;
|
|
565
|
+
continue;
|
|
566
|
+
}
|
|
567
|
+
const block = blockCommentAt(text, position);
|
|
568
|
+
const line = lineCommentAt(text, position);
|
|
569
|
+
if (line >= 0 && (block < 0 || line < block)) return { code: code + text.slice(position, line), insideComment: false };
|
|
570
|
+
if (block < 0) return { code: code + text.slice(position), insideComment: false };
|
|
571
|
+
if (text.indexOf("*/", block + 2) < 0 && !closesLater()) {
|
|
572
|
+
code += text.slice(position, block + 2);
|
|
573
|
+
position = block + 2;
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
code += text.slice(position, block);
|
|
577
|
+
inside = true;
|
|
578
|
+
position = block + 2;
|
|
579
|
+
}
|
|
580
|
+
return { code, insideComment: inside };
|
|
581
|
+
}
|
|
582
|
+
function codeLines(lines, from, start, column) {
|
|
583
|
+
const plain = lines.slice(from, start + 1).map((line) => line.replace(STRING_LITERAL, '""'));
|
|
584
|
+
const closesWithin = (index) => plain.slice(index + 1, index + 1 + MAX_COMMENT_LINES).some((line) => line.includes("*/"));
|
|
585
|
+
const result = [];
|
|
586
|
+
let insideComment = false;
|
|
587
|
+
for (let index = 0; index < plain.length; index++) {
|
|
588
|
+
const text = index === plain.length - 1 && column ? (lines[start] ?? "").slice(0, Math.max(0, column - 1)).replace(STRING_LITERAL, '""') : plain[index] ?? "";
|
|
589
|
+
const stripped = stripComments(text, insideComment, () => closesWithin(index));
|
|
590
|
+
insideComment = stripped.insideComment;
|
|
591
|
+
result.push(stripped.code);
|
|
592
|
+
}
|
|
593
|
+
return result;
|
|
514
594
|
}
|
|
515
595
|
function parenBalance(text) {
|
|
516
596
|
let balance = 0;
|
|
@@ -520,17 +600,17 @@ function parenBalance(text) {
|
|
|
520
600
|
}
|
|
521
601
|
return balance;
|
|
522
602
|
}
|
|
523
|
-
function headerOf(
|
|
603
|
+
function headerOf(code, index, prefix) {
|
|
524
604
|
let header = prefix;
|
|
525
605
|
for (let previous = index - 1; previous >= 0 && previous >= index - MAX_HEADER_LINES; previous--) {
|
|
526
606
|
if (header.trim() !== "" && parenBalance(header) >= 0) break;
|
|
527
|
-
header = `${
|
|
607
|
+
header = `${code[previous] ?? ""} ${header}`;
|
|
528
608
|
}
|
|
529
609
|
return header;
|
|
530
610
|
}
|
|
531
611
|
function nameIn(header) {
|
|
532
|
-
const
|
|
533
|
-
for (const pattern of
|
|
612
|
+
const patterns2 = ANONYMOUS_FUNCTION.test(header) ? NAME_PATTERNS : [...NAME_PATTERNS, METHOD_PATTERN];
|
|
613
|
+
for (const pattern of patterns2) {
|
|
534
614
|
const name = pattern.exec(header)?.[1];
|
|
535
615
|
if (name && !KEYWORDS.has(name)) return name.slice(0, MAX_NAME_LENGTH);
|
|
536
616
|
}
|
|
@@ -539,11 +619,12 @@ function nameIn(header) {
|
|
|
539
619
|
function enclosingFunctionName(lines, line, column) {
|
|
540
620
|
const start = line - 1;
|
|
541
621
|
if (start < 0 || start >= lines.length) return void 0;
|
|
622
|
+
const from = Math.max(0, start - MAX_LINES_UP - MAX_HEADER_LINES);
|
|
623
|
+
const cleaned = codeLines(lines, from, start, column);
|
|
542
624
|
let depth = 0;
|
|
543
625
|
for (let index = start; index >= 0 && index >= start - MAX_LINES_UP; index--) {
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
const code = codeOnly(index === start && column ? raw.slice(0, Math.max(0, column - 1)) : raw);
|
|
626
|
+
if (index < start && MARKUP_BOUNDARY.test(lines[index] ?? "")) return void 0;
|
|
627
|
+
const code = cleaned[index - from] ?? "";
|
|
547
628
|
for (let position = code.length - 1; position >= 0; position--) {
|
|
548
629
|
const char = code[position];
|
|
549
630
|
if (char === "}") {
|
|
@@ -553,7 +634,7 @@ function enclosingFunctionName(lines, line, column) {
|
|
|
553
634
|
depth -= 1;
|
|
554
635
|
continue;
|
|
555
636
|
}
|
|
556
|
-
const header = headerOf(
|
|
637
|
+
const header = headerOf(cleaned, index - from, code.slice(0, position));
|
|
557
638
|
if (CLASS_BODY.test(header)) return void 0;
|
|
558
639
|
if (CONTROL_BLOCK.test(header)) continue;
|
|
559
640
|
const name = nameIn(header);
|
|
@@ -795,20 +876,118 @@ function safeStringify(value) {
|
|
|
795
876
|
}
|
|
796
877
|
}
|
|
797
878
|
|
|
798
|
-
// src/transport.ts
|
|
799
|
-
import { promisify } from "util";
|
|
800
|
-
import { gzip } from "zlib";
|
|
801
|
-
|
|
802
879
|
// src/util.ts
|
|
803
|
-
import { performance as
|
|
880
|
+
import { performance as performance3 } from "perf_hooks";
|
|
804
881
|
function describeError(error) {
|
|
805
882
|
return error instanceof Error ? error.message : String(error);
|
|
806
883
|
}
|
|
807
884
|
function elapsedSince(startedAt) {
|
|
808
|
-
return Math.round(
|
|
885
|
+
return Math.round(performance3.now() - startedAt);
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
// src/trace-fetch.ts
|
|
889
|
+
var WRAPPED = /* @__PURE__ */ Symbol.for("@oconde/radar.fetch");
|
|
890
|
+
var REQUEST_ID_HEADER = "x-request-id";
|
|
891
|
+
var UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
892
|
+
var TELEGRAM_BOT = /^bot\d{5,}:[\w-]{20,}$/;
|
|
893
|
+
var TOKEN_LIKE = /^[\w\-.~+=]{20,}$/;
|
|
894
|
+
function secretSegment(segment) {
|
|
895
|
+
if (UUID.test(segment)) return false;
|
|
896
|
+
if (TELEGRAM_BOT.test(segment) || looksLikeCredential(segment)) return true;
|
|
897
|
+
return TOKEN_LIKE.test(segment) && /[A-Za-z]/.test(segment) && /\d/.test(segment);
|
|
898
|
+
}
|
|
899
|
+
function outboundPath(pathname, mode) {
|
|
900
|
+
if (mode === "none") return pathname;
|
|
901
|
+
return pathname.split("/").map((segment) => {
|
|
902
|
+
let decoded = segment;
|
|
903
|
+
try {
|
|
904
|
+
decoded = decodeURIComponent(segment);
|
|
905
|
+
} catch {
|
|
906
|
+
decoded = segment;
|
|
907
|
+
}
|
|
908
|
+
return secretSegment(decoded) ? maskValue(decoded, false) : segment;
|
|
909
|
+
}).join("/");
|
|
910
|
+
}
|
|
911
|
+
function failureOf(error) {
|
|
912
|
+
const message = describeError(error);
|
|
913
|
+
const cause = error instanceof Error ? error.cause : void 0;
|
|
914
|
+
const detail = typeof cause?.code === "string" ? cause.code : typeof cause?.message === "string" ? cause.message : "";
|
|
915
|
+
return detail && !message.includes(detail) ? `${message} (${detail})` : message;
|
|
916
|
+
}
|
|
917
|
+
function urlOf(input) {
|
|
918
|
+
try {
|
|
919
|
+
if (typeof input === "string") return new URL(input);
|
|
920
|
+
if (input instanceof URL) return input;
|
|
921
|
+
return new URL(input.url);
|
|
922
|
+
} catch {
|
|
923
|
+
return null;
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
function originOf(value) {
|
|
927
|
+
try {
|
|
928
|
+
return new URL(value).origin;
|
|
929
|
+
} catch {
|
|
930
|
+
return null;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
function hostMatches(url, host) {
|
|
934
|
+
const wanted = host.trim().toLowerCase();
|
|
935
|
+
if (wanted.startsWith(".")) return url.hostname.toLowerCase().endsWith(wanted);
|
|
936
|
+
return url.host.toLowerCase() === wanted || url.hostname.toLowerCase() === wanted;
|
|
937
|
+
}
|
|
938
|
+
function targets(url, target) {
|
|
939
|
+
if (target instanceof RegExp) return url.host.search(target) !== -1;
|
|
940
|
+
return hostMatches(url, target);
|
|
941
|
+
}
|
|
942
|
+
function ignored(url, target) {
|
|
943
|
+
if (target instanceof RegExp) return `${url.host}${url.pathname}`.search(target) !== -1;
|
|
944
|
+
return hostMatches(url, target);
|
|
945
|
+
}
|
|
946
|
+
function isPlainObject(value) {
|
|
947
|
+
if (value === null || typeof value !== "object") return false;
|
|
948
|
+
const prototype = Object.getPrototypeOf(value);
|
|
949
|
+
return prototype === Object.prototype || prototype === null;
|
|
950
|
+
}
|
|
951
|
+
function withRequestId(input, init, requestId) {
|
|
952
|
+
const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : void 0));
|
|
953
|
+
if (headers.has(REQUEST_ID_HEADER)) return [input, init];
|
|
954
|
+
headers.set(REQUEST_ID_HEADER, requestId);
|
|
955
|
+
if (init === void 0 || isPlainObject(init)) return [input, { ...init, headers }];
|
|
956
|
+
return [new Request(input, init), { headers }];
|
|
957
|
+
}
|
|
958
|
+
function traceFetch(config) {
|
|
959
|
+
const current = globalThis.fetch;
|
|
960
|
+
if (typeof current !== "function" || current[WRAPPED]) return () => void 0;
|
|
961
|
+
const original = current;
|
|
962
|
+
const radarOrigin = originOf(config.endpoint);
|
|
963
|
+
const traced = async (input, init) => {
|
|
964
|
+
const url = urlOf(input);
|
|
965
|
+
if (!url || url.origin === radarOrigin || url.protocol !== "http:" && url.protocol !== "https:") return original(input, init);
|
|
966
|
+
const method = (init?.method ?? (input instanceof Request ? input.method : "GET")).toUpperCase();
|
|
967
|
+
const context = currentContext();
|
|
968
|
+
const [nextInput, nextInit] = context && config.propagateTo.some((target) => targets(url, target)) ? withRequestId(input, init, context.requestId) : [input, init];
|
|
969
|
+
if (config.ignore?.some((target) => ignored(url, target))) return original(nextInput, nextInit);
|
|
970
|
+
const attrs = { method, host: url.host, path: outboundPath(url.pathname, config.redact) };
|
|
971
|
+
const started = performance.now();
|
|
972
|
+
try {
|
|
973
|
+
const response = await original(nextInput, nextInit);
|
|
974
|
+
config.record(response.status >= 500 ? "error" : response.status >= 400 ? "warn" : "info", { ...attrs, status: response.status, durationMs: elapsedSince(started) });
|
|
975
|
+
return response;
|
|
976
|
+
} catch (error) {
|
|
977
|
+
config.record("error", { ...attrs, error: failureOf(error), durationMs: elapsedSince(started) });
|
|
978
|
+
throw error;
|
|
979
|
+
}
|
|
980
|
+
};
|
|
981
|
+
Object.defineProperty(traced, WRAPPED, { value: original });
|
|
982
|
+
globalThis.fetch = traced;
|
|
983
|
+
return () => {
|
|
984
|
+
if (globalThis.fetch === traced) globalThis.fetch = original;
|
|
985
|
+
};
|
|
809
986
|
}
|
|
810
987
|
|
|
811
988
|
// src/transport.ts
|
|
989
|
+
import { promisify } from "util";
|
|
990
|
+
import { gzip } from "zlib";
|
|
812
991
|
var gzipAsync = promisify(gzip);
|
|
813
992
|
var MAX_BATCH_BYTES = 9e5;
|
|
814
993
|
var GZIP_THRESHOLD_BYTES = 8192;
|
|
@@ -1036,7 +1215,7 @@ function withTimeout(promise, ms) {
|
|
|
1036
1215
|
|
|
1037
1216
|
// src/version.ts
|
|
1038
1217
|
var SDK_NAME = "@oconde/radar";
|
|
1039
|
-
var SDK_VERSION = true ? "0.
|
|
1218
|
+
var SDK_VERSION = true ? "0.4.1" : "0.0.0-dev";
|
|
1040
1219
|
|
|
1041
1220
|
// src/client.ts
|
|
1042
1221
|
var MAX_CHECK_IN_DURATION_MS = 7 * 864e5;
|
|
@@ -1048,6 +1227,7 @@ var RadarClient = class {
|
|
|
1048
1227
|
initialized = false;
|
|
1049
1228
|
closed = false;
|
|
1050
1229
|
captured = /* @__PURE__ */ new WeakSet();
|
|
1230
|
+
restoreFetch = null;
|
|
1051
1231
|
get isEnabled() {
|
|
1052
1232
|
return this.transport !== null && !this.closed;
|
|
1053
1233
|
}
|
|
@@ -1075,6 +1255,15 @@ var RadarClient = class {
|
|
|
1075
1255
|
});
|
|
1076
1256
|
}
|
|
1077
1257
|
if (this.options.captureUnhandled && (this.transport || this.options.console)) installProcessHandlers(this);
|
|
1258
|
+
if (this.options.traceFetch.enabled && (this.transport || this.options.console)) {
|
|
1259
|
+
this.restoreFetch = traceFetch({
|
|
1260
|
+
endpoint: this.options.endpoint,
|
|
1261
|
+
propagateTo: this.options.traceFetch.propagateTo,
|
|
1262
|
+
ignore: this.options.traceFetch.ignore,
|
|
1263
|
+
redact: this.options.redact,
|
|
1264
|
+
record: (level, attrs) => this.safely(() => this.emitLog(level, "http.client", attrs))
|
|
1265
|
+
});
|
|
1266
|
+
}
|
|
1078
1267
|
} catch (error) {
|
|
1079
1268
|
this.debugWarn(`radar.init falhou: ${describeError(error)}`);
|
|
1080
1269
|
}
|
|
@@ -1118,7 +1307,7 @@ var RadarClient = class {
|
|
|
1118
1307
|
}
|
|
1119
1308
|
async track(name, fn, data) {
|
|
1120
1309
|
const execute = async () => {
|
|
1121
|
-
const started =
|
|
1310
|
+
const started = performance4.now();
|
|
1122
1311
|
try {
|
|
1123
1312
|
const result = await fn();
|
|
1124
1313
|
this.info(name, { ...data, durationMs: elapsedSince(started), ok: true });
|
|
@@ -1130,10 +1319,10 @@ var RadarClient = class {
|
|
|
1130
1319
|
}
|
|
1131
1320
|
};
|
|
1132
1321
|
if (currentContext()) return execute();
|
|
1133
|
-
return runWithContext({ requestId: randomUUID2(), startedAt:
|
|
1322
|
+
return runWithContext({ requestId: randomUUID2(), startedAt: performance4.now() }, execute);
|
|
1134
1323
|
}
|
|
1135
1324
|
withContext(fn, options = {}) {
|
|
1136
|
-
return runWithContext({ requestId: requestIdFrom(options.requestId), startedAt:
|
|
1325
|
+
return runWithContext({ requestId: requestIdFrom(options.requestId), startedAt: performance4.now() }, fn);
|
|
1137
1326
|
}
|
|
1138
1327
|
async checkIn(slug, status, options = {}) {
|
|
1139
1328
|
try {
|
|
@@ -1161,7 +1350,7 @@ var RadarClient = class {
|
|
|
1161
1350
|
}
|
|
1162
1351
|
async cron(slug, fn) {
|
|
1163
1352
|
const checkInId = randomUUID2();
|
|
1164
|
-
const started =
|
|
1353
|
+
const started = performance4.now();
|
|
1165
1354
|
const execute = async () => {
|
|
1166
1355
|
await this.checkIn(slug, "in_progress", { checkInId });
|
|
1167
1356
|
try {
|
|
@@ -1181,22 +1370,28 @@ var RadarClient = class {
|
|
|
1181
1370
|
return createMiddleware(this);
|
|
1182
1371
|
}
|
|
1183
1372
|
shouldLogRequest(req) {
|
|
1184
|
-
return this.options.logRequests && !this.options.ignorePaths.includes(requestPath(req));
|
|
1373
|
+
return this.options.logRequests.enabled && !this.options.ignorePaths.includes(requestPath(req));
|
|
1185
1374
|
}
|
|
1186
1375
|
logHttpRequest(context, status) {
|
|
1187
1376
|
this.safely(() => {
|
|
1188
1377
|
const req = context.req;
|
|
1189
1378
|
if (!req) return;
|
|
1190
|
-
const level = status >= 500 ? "error" : status >= 400 ? "warn" : "info";
|
|
1191
1379
|
const route = requestRoute(req, context.route);
|
|
1380
|
+
const path = requestPath(req);
|
|
1381
|
+
const { include, exclude, sample } = this.options.logRequests;
|
|
1382
|
+
if (include.length > 0 && !include.some((pattern) => matchesRequest(pattern, path, route))) return;
|
|
1383
|
+
if (exclude.some((pattern) => matchesRequest(pattern, path, route))) return;
|
|
1384
|
+
if (sample < 1 && Math.random() >= sample) return;
|
|
1385
|
+
const level = status >= 500 ? "error" : status >= 400 ? "warn" : "info";
|
|
1192
1386
|
runWithContext(
|
|
1193
1387
|
context,
|
|
1194
1388
|
() => this.emitLog(level, "http.request", {
|
|
1195
1389
|
method: (req.method ?? "GET").toUpperCase(),
|
|
1196
1390
|
...route ? { route } : {},
|
|
1197
|
-
...this.options.requestDetail === "full" ? { path: redactPath(
|
|
1391
|
+
...this.options.requestDetail === "full" ? { path: redactPath(path, pathParams(req, path), this.options.redact) } : {},
|
|
1198
1392
|
status,
|
|
1199
|
-
durationMs: elapsedSince(context.startedAt)
|
|
1393
|
+
durationMs: elapsedSince(context.startedAt),
|
|
1394
|
+
...sample < 1 ? { sampleRate: sample } : {}
|
|
1200
1395
|
})
|
|
1201
1396
|
);
|
|
1202
1397
|
});
|
|
@@ -1211,6 +1406,8 @@ var RadarClient = class {
|
|
|
1211
1406
|
async close(timeoutMs = 2e3) {
|
|
1212
1407
|
if (this.closed) return;
|
|
1213
1408
|
await this.flush(timeoutMs);
|
|
1409
|
+
this.restoreFetch?.();
|
|
1410
|
+
this.restoreFetch = null;
|
|
1214
1411
|
this.closed = true;
|
|
1215
1412
|
this.transport?.stop();
|
|
1216
1413
|
}
|