@djangocfg/monitor 2.1.236 → 2.1.238
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/dist/client.cjs +90 -14
- package/dist/client.cjs.map +1 -1
- package/dist/client.mjs +90 -14
- package/dist/client.mjs.map +1 -1
- package/package.json +2 -2
- package/src/client/capture/console.ts +17 -0
- package/src/client/capture/network.ts +36 -13
- package/src/client/capture/validation.ts +19 -0
- package/src/client/store/index.ts +31 -0
package/dist/client.cjs
CHANGED
|
@@ -1364,11 +1364,32 @@ __name(sendBatch, "sendBatch");
|
|
|
1364
1364
|
// src/client/utils/env.ts
|
|
1365
1365
|
var isDevelopment = process.env.NODE_ENV === "development";
|
|
1366
1366
|
var isProduction = !isDevelopment;
|
|
1367
|
-
var MONITOR_VERSION = "2.1.
|
|
1367
|
+
var MONITOR_VERSION = "2.1.238";
|
|
1368
1368
|
|
|
1369
1369
|
// src/client/store/index.ts
|
|
1370
1370
|
var CIRCUIT_BREAKER_THRESHOLD = 3;
|
|
1371
1371
|
var CIRCUIT_BREAKER_COOLDOWN_MS = 6e4;
|
|
1372
|
+
var STORE_DEDUP_TTL = 5e3;
|
|
1373
|
+
var STORE_DEDUP_MAX = 200;
|
|
1374
|
+
var _recentPushKeys = /* @__PURE__ */ new Map();
|
|
1375
|
+
function _pushDedupeKey(event) {
|
|
1376
|
+
const msg = (event.message ?? "").slice(0, 100);
|
|
1377
|
+
return `${event.event_type}:${event.level}:${msg}:${event.http_url ?? event.url ?? ""}`;
|
|
1378
|
+
}
|
|
1379
|
+
__name(_pushDedupeKey, "_pushDedupeKey");
|
|
1380
|
+
function _isRecentPush(key) {
|
|
1381
|
+
const now = Date.now();
|
|
1382
|
+
const last = _recentPushKeys.get(key);
|
|
1383
|
+
if (last !== void 0 && now - last < STORE_DEDUP_TTL) return true;
|
|
1384
|
+
_recentPushKeys.set(key, now);
|
|
1385
|
+
if (_recentPushKeys.size > STORE_DEDUP_MAX) {
|
|
1386
|
+
for (const [k, ts] of _recentPushKeys) {
|
|
1387
|
+
if (now - ts > STORE_DEDUP_TTL) _recentPushKeys.delete(k);
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1390
|
+
return false;
|
|
1391
|
+
}
|
|
1392
|
+
__name(_isRecentPush, "_isRecentPush");
|
|
1372
1393
|
var monitorStore = (0, import_vanilla.createStore)((set, get) => ({
|
|
1373
1394
|
config: {},
|
|
1374
1395
|
buffer: [],
|
|
@@ -1376,6 +1397,8 @@ var monitorStore = (0, import_vanilla.createStore)((set, get) => ({
|
|
|
1376
1397
|
_consecutiveFailures: 0,
|
|
1377
1398
|
_pausedUntil: 0,
|
|
1378
1399
|
push(event) {
|
|
1400
|
+
const dedupeKey = _pushDedupeKey(event);
|
|
1401
|
+
if (_isRecentPush(dedupeKey)) return;
|
|
1379
1402
|
const { config, buffer } = get();
|
|
1380
1403
|
const maxSize = config.maxBufferSize ?? 20;
|
|
1381
1404
|
const sanitized = {
|
|
@@ -1537,6 +1560,20 @@ var typeMap = {
|
|
|
1537
1560
|
error: "ERROR" /* ERROR */
|
|
1538
1561
|
};
|
|
1539
1562
|
var ARG_MAX = 500;
|
|
1563
|
+
var CONSOLE_DEDUP_TTL = 5 * 60 * 1e3;
|
|
1564
|
+
var recentConsoleFingerprints = /* @__PURE__ */ new Map();
|
|
1565
|
+
function isRecentConsole(fingerprint) {
|
|
1566
|
+
const now = Date.now();
|
|
1567
|
+
const last = recentConsoleFingerprints.get(fingerprint);
|
|
1568
|
+
if (last !== void 0 && now - last < CONSOLE_DEDUP_TTL) return true;
|
|
1569
|
+
recentConsoleFingerprints.set(fingerprint, now);
|
|
1570
|
+
if (recentConsoleFingerprints.size > 100) {
|
|
1571
|
+
const oldest = [...recentConsoleFingerprints.entries()].sort((a, b) => a[1] - b[1])[0];
|
|
1572
|
+
recentConsoleFingerprints.delete(oldest[0]);
|
|
1573
|
+
}
|
|
1574
|
+
return false;
|
|
1575
|
+
}
|
|
1576
|
+
__name(isRecentConsole, "isRecentConsole");
|
|
1540
1577
|
function stringifyArg(a) {
|
|
1541
1578
|
let s;
|
|
1542
1579
|
if (typeof a === "string") s = a;
|
|
@@ -1561,6 +1598,7 @@ async function captureConsoleEvent(level, args) {
|
|
|
1561
1598
|
if (MONITOR_INGEST_PATTERN.test(message)) return;
|
|
1562
1599
|
const url = typeof window !== "undefined" ? window.location.href : "";
|
|
1563
1600
|
const fingerprint = await computeFingerprint(message, "", url);
|
|
1601
|
+
if (isRecentConsole(fingerprint)) return;
|
|
1564
1602
|
const { config } = monitorStore.getState();
|
|
1565
1603
|
monitorStore.getState().push({
|
|
1566
1604
|
event_type: typeMap[level],
|
|
@@ -1613,6 +1651,21 @@ function installConsoleCapture() {
|
|
|
1613
1651
|
__name(installConsoleCapture, "installConsoleCapture");
|
|
1614
1652
|
|
|
1615
1653
|
// src/client/capture/validation.ts
|
|
1654
|
+
var VALIDATION_DEDUP_TTL = 1e4;
|
|
1655
|
+
var recentValidations = /* @__PURE__ */ new Map();
|
|
1656
|
+
function isRecentValidation(key) {
|
|
1657
|
+
const now = Date.now();
|
|
1658
|
+
const last = recentValidations.get(key);
|
|
1659
|
+
if (last !== void 0 && now - last < VALIDATION_DEDUP_TTL) return true;
|
|
1660
|
+
recentValidations.set(key, now);
|
|
1661
|
+
if (recentValidations.size > 50) {
|
|
1662
|
+
for (const [k, ts] of recentValidations) {
|
|
1663
|
+
if (now - ts > VALIDATION_DEDUP_TTL) recentValidations.delete(k);
|
|
1664
|
+
}
|
|
1665
|
+
}
|
|
1666
|
+
return false;
|
|
1667
|
+
}
|
|
1668
|
+
__name(isRecentValidation, "isRecentValidation");
|
|
1616
1669
|
function installValidationCapture() {
|
|
1617
1670
|
if (typeof window === "undefined") return () => {
|
|
1618
1671
|
};
|
|
@@ -1620,6 +1673,8 @@ function installValidationCapture() {
|
|
|
1620
1673
|
if (!(event instanceof CustomEvent)) return;
|
|
1621
1674
|
try {
|
|
1622
1675
|
const detail = event.detail;
|
|
1676
|
+
const dedupeKey = `${detail.operation}:${detail.path}:${detail.method}`;
|
|
1677
|
+
if (isRecentValidation(dedupeKey)) return;
|
|
1623
1678
|
const { config } = monitorStore.getState();
|
|
1624
1679
|
const rawMsg = `Zod validation error in ${detail.operation}: ${detail.error?.message ?? "unknown"}`;
|
|
1625
1680
|
monitorStore.getState().push({
|
|
@@ -1644,12 +1699,29 @@ function installValidationCapture() {
|
|
|
1644
1699
|
__name(installValidationCapture, "installValidationCapture");
|
|
1645
1700
|
|
|
1646
1701
|
// src/client/capture/network.ts
|
|
1702
|
+
var NETWORK_DEDUP_TTL = 5e3;
|
|
1703
|
+
var recentNetworkErrors = /* @__PURE__ */ new Map();
|
|
1704
|
+
function isRecentNetwork(key) {
|
|
1705
|
+
const now = Date.now();
|
|
1706
|
+
const last = recentNetworkErrors.get(key);
|
|
1707
|
+
if (last !== void 0 && now - last < NETWORK_DEDUP_TTL) return true;
|
|
1708
|
+
recentNetworkErrors.set(key, now);
|
|
1709
|
+
if (recentNetworkErrors.size > 100) {
|
|
1710
|
+
for (const [k, ts] of recentNetworkErrors) {
|
|
1711
|
+
if (now - ts > NETWORK_DEDUP_TTL) recentNetworkErrors.delete(k);
|
|
1712
|
+
}
|
|
1713
|
+
}
|
|
1714
|
+
return false;
|
|
1715
|
+
}
|
|
1716
|
+
__name(isRecentNetwork, "isRecentNetwork");
|
|
1647
1717
|
async function monitoredFetch(input, init) {
|
|
1648
1718
|
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
1649
1719
|
const method = (init?.method ?? "GET").toUpperCase();
|
|
1650
1720
|
try {
|
|
1651
1721
|
const response = await fetch(input, init);
|
|
1652
1722
|
if (!response.ok) {
|
|
1723
|
+
const netKey = `${response.status}:${method}:${url}`;
|
|
1724
|
+
if (isRecentNetwork(netKey)) return response;
|
|
1653
1725
|
const { config } = monitorStore.getState();
|
|
1654
1726
|
monitorStore.getState().push({
|
|
1655
1727
|
event_type: "NETWORK_ERROR" /* NETWORK_ERROR */,
|
|
@@ -1667,19 +1739,23 @@ async function monitoredFetch(input, init) {
|
|
|
1667
1739
|
}
|
|
1668
1740
|
return response;
|
|
1669
1741
|
} catch (err) {
|
|
1670
|
-
const
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1742
|
+
const errMsg = err instanceof Error ? err.message : "network-error";
|
|
1743
|
+
const netKey = `err:${errMsg.slice(0, 50)}:${method}:${url}`;
|
|
1744
|
+
if (!isRecentNetwork(netKey)) {
|
|
1745
|
+
const { config } = monitorStore.getState();
|
|
1746
|
+
monitorStore.getState().push({
|
|
1747
|
+
event_type: "NETWORK_ERROR" /* NETWORK_ERROR */,
|
|
1748
|
+
level: "error" /* ERROR */,
|
|
1749
|
+
message: err instanceof Error ? err.message : `Network error \u2014 ${method} ${url}`,
|
|
1750
|
+
url: typeof window !== "undefined" ? window.location.href : "",
|
|
1751
|
+
http_method: method,
|
|
1752
|
+
http_url: url,
|
|
1753
|
+
session_id: getSessionId(),
|
|
1754
|
+
user_agent: typeof navigator !== "undefined" ? navigator.userAgent : "",
|
|
1755
|
+
project_name: config.project,
|
|
1756
|
+
environment: config.environment
|
|
1757
|
+
});
|
|
1758
|
+
}
|
|
1683
1759
|
throw err;
|
|
1684
1760
|
}
|
|
1685
1761
|
}
|