@djangocfg/monitor 2.1.227 → 2.1.229

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.
Files changed (36) hide show
  1. package/README.md +2 -6
  2. package/dist/client.cjs +48 -26
  3. package/dist/client.cjs.map +1 -1
  4. package/dist/client.d.cts +31 -33
  5. package/dist/client.d.ts +31 -33
  6. package/dist/client.mjs +48 -26
  7. package/dist/client.mjs.map +1 -1
  8. package/dist/index.cjs +9 -10
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.cts +29 -33
  11. package/dist/index.d.ts +29 -33
  12. package/dist/index.mjs +9 -10
  13. package/dist/index.mjs.map +1 -1
  14. package/dist/server.cjs +10 -11
  15. package/dist/server.cjs.map +1 -1
  16. package/dist/server.d.cts +29 -33
  17. package/dist/server.d.ts +29 -33
  18. package/dist/server.mjs +10 -11
  19. package/dist/server.mjs.map +1 -1
  20. package/package.json +2 -2
  21. package/src/_api/generated/cfg_monitor/_utils/schemas/FrontendEventIngestRequest.schema.ts +5 -6
  22. package/src/_api/generated/cfg_monitor/_utils/schemas/IngestBatchRequest.schema.ts +2 -2
  23. package/src/_api/generated/cfg_monitor/enums.ts +14 -16
  24. package/src/_api/generated/cfg_monitor/monitor/client.ts +2 -1
  25. package/src/_api/generated/cfg_monitor/monitor/models.ts +16 -18
  26. package/src/_api/generated/cfg_monitor/schema.json +19 -27
  27. package/src/client/capture/console.ts +3 -1
  28. package/src/client/capture/js-errors.ts +7 -0
  29. package/src/client/capture/network.ts +1 -1
  30. package/src/client/capture/validation.ts +1 -1
  31. package/src/client/constants.ts +7 -0
  32. package/src/client/index.ts +2 -1
  33. package/src/client/store/index.ts +28 -2
  34. package/src/client/transport/ingest.ts +5 -9
  35. package/src/client/window.ts +3 -3
  36. package/src/server/index.ts +1 -1
package/dist/client.d.cts CHANGED
@@ -2,58 +2,55 @@ import * as react from 'react';
2
2
  import * as zustand_vanilla from 'zustand/vanilla';
3
3
 
4
4
  /**
5
- * * `ERROR` - Error
6
- * * `WARNING` - Warning
7
- * * `INFO` - Info
8
- * * `PAGE_VIEW` - Page View
9
- * * `PERFORMANCE` - Performance
10
- * * `NETWORK_ERROR` - Network Error
11
- * * `JS_ERROR` - JS Error
12
- * * `CONSOLE` - Console
5
+ * * `JS_ERROR` - JS_ERROR
6
+ * * `NETWORK_ERROR` - NETWORK_ERROR
7
+ * * `ERROR` - ERROR
8
+ * * `WARNING` - WARNING
9
+ * * `PAGE_VIEW` - PAGE_VIEW
10
+ * * `PERFORMANCE` - PERFORMANCE
11
+ * * `CONSOLE` - CONSOLE
13
12
  */
14
13
  declare enum FrontendEventIngestRequestEventType {
14
+ JS_ERROR = "JS_ERROR",
15
+ NETWORK_ERROR = "NETWORK_ERROR",
15
16
  ERROR = "ERROR",
16
17
  WARNING = "WARNING",
17
- INFO = "INFO",
18
18
  PAGE_VIEW = "PAGE_VIEW",
19
19
  PERFORMANCE = "PERFORMANCE",
20
- NETWORK_ERROR = "NETWORK_ERROR",
21
- JS_ERROR = "JS_ERROR",
22
20
  CONSOLE = "CONSOLE"
23
21
  }
24
22
  /**
25
- * * `error` - Error
26
- * * `warn` - Warning
27
- * * `info` - Info
28
- * * `debug` - Debug
23
+ * * `error` - error
24
+ * * `warning` - warning
25
+ * * `info` - info
26
+ * * `debug` - debug
29
27
  */
30
28
  declare enum FrontendEventIngestRequestLevel {
31
29
  ERROR = "error",
32
- WARN = "warn",
30
+ WARNING = "warning",
33
31
  INFO = "info",
34
32
  DEBUG = "debug"
35
33
  }
36
34
 
37
35
  /**
38
- * Validates a single event from the browser.
36
+ * Single browser event payload.
39
37
  *
40
38
  * Request model (no read-only fields).
41
39
  */
42
40
  interface FrontendEventIngestRequest {
43
- /** * `ERROR` - Error
44
- * `WARNING` - Warning
45
- * `INFO` - Info
46
- * `PAGE_VIEW` - Page View
47
- * `PERFORMANCE` - Performance
48
- * `NETWORK_ERROR` - Network Error
49
- * `JS_ERROR` - JS Error
50
- * `CONSOLE` - Console */
41
+ /** * `JS_ERROR` - JS_ERROR
42
+ * `NETWORK_ERROR` - NETWORK_ERROR
43
+ * `ERROR` - ERROR
44
+ * `WARNING` - WARNING
45
+ * `PAGE_VIEW` - PAGE_VIEW
46
+ * `PERFORMANCE` - PERFORMANCE
47
+ * `CONSOLE` - CONSOLE */
51
48
  event_type: FrontendEventIngestRequestEventType;
52
49
  message: string;
53
- /** * `error` - Error
54
- * `warn` - Warning
55
- * `info` - Info
56
- * `debug` - Debug */
50
+ /** * `error` - error
51
+ * `warning` - warning
52
+ * `info` - info
53
+ * `debug` - debug */
57
54
  level?: FrontendEventIngestRequestLevel;
58
55
  stack_trace?: string;
59
56
  url?: string;
@@ -61,13 +58,12 @@ interface FrontendEventIngestRequest {
61
58
  http_status?: number | null;
62
59
  http_method?: string;
63
60
  http_url?: string;
61
+ session_id?: string;
64
62
  user_agent?: string;
65
- session_id?: string | null;
66
- browser_fingerprint?: string;
63
+ build_id?: string;
64
+ environment?: string;
67
65
  extra?: Record<string, any>;
68
66
  project_name?: string;
69
- environment?: string;
70
- build_id?: string;
71
67
  }
72
68
 
73
69
  /**
@@ -146,6 +142,8 @@ interface MonitorState {
146
142
  config: MonitorConfig;
147
143
  buffer: FrontendEventIngestRequest[];
148
144
  initialized: boolean;
145
+ _consecutiveFailures: number;
146
+ _pausedUntil: number;
149
147
  push: (event: FrontendEventIngestRequest) => void;
150
148
  flush: (useBeacon?: boolean) => void;
151
149
  setConfig: (config: MonitorConfig) => void;
package/dist/client.d.ts CHANGED
@@ -2,58 +2,55 @@ import * as react from 'react';
2
2
  import * as zustand_vanilla from 'zustand/vanilla';
3
3
 
4
4
  /**
5
- * * `ERROR` - Error
6
- * * `WARNING` - Warning
7
- * * `INFO` - Info
8
- * * `PAGE_VIEW` - Page View
9
- * * `PERFORMANCE` - Performance
10
- * * `NETWORK_ERROR` - Network Error
11
- * * `JS_ERROR` - JS Error
12
- * * `CONSOLE` - Console
5
+ * * `JS_ERROR` - JS_ERROR
6
+ * * `NETWORK_ERROR` - NETWORK_ERROR
7
+ * * `ERROR` - ERROR
8
+ * * `WARNING` - WARNING
9
+ * * `PAGE_VIEW` - PAGE_VIEW
10
+ * * `PERFORMANCE` - PERFORMANCE
11
+ * * `CONSOLE` - CONSOLE
13
12
  */
14
13
  declare enum FrontendEventIngestRequestEventType {
14
+ JS_ERROR = "JS_ERROR",
15
+ NETWORK_ERROR = "NETWORK_ERROR",
15
16
  ERROR = "ERROR",
16
17
  WARNING = "WARNING",
17
- INFO = "INFO",
18
18
  PAGE_VIEW = "PAGE_VIEW",
19
19
  PERFORMANCE = "PERFORMANCE",
20
- NETWORK_ERROR = "NETWORK_ERROR",
21
- JS_ERROR = "JS_ERROR",
22
20
  CONSOLE = "CONSOLE"
23
21
  }
24
22
  /**
25
- * * `error` - Error
26
- * * `warn` - Warning
27
- * * `info` - Info
28
- * * `debug` - Debug
23
+ * * `error` - error
24
+ * * `warning` - warning
25
+ * * `info` - info
26
+ * * `debug` - debug
29
27
  */
30
28
  declare enum FrontendEventIngestRequestLevel {
31
29
  ERROR = "error",
32
- WARN = "warn",
30
+ WARNING = "warning",
33
31
  INFO = "info",
34
32
  DEBUG = "debug"
35
33
  }
36
34
 
37
35
  /**
38
- * Validates a single event from the browser.
36
+ * Single browser event payload.
39
37
  *
40
38
  * Request model (no read-only fields).
41
39
  */
42
40
  interface FrontendEventIngestRequest {
43
- /** * `ERROR` - Error
44
- * `WARNING` - Warning
45
- * `INFO` - Info
46
- * `PAGE_VIEW` - Page View
47
- * `PERFORMANCE` - Performance
48
- * `NETWORK_ERROR` - Network Error
49
- * `JS_ERROR` - JS Error
50
- * `CONSOLE` - Console */
41
+ /** * `JS_ERROR` - JS_ERROR
42
+ * `NETWORK_ERROR` - NETWORK_ERROR
43
+ * `ERROR` - ERROR
44
+ * `WARNING` - WARNING
45
+ * `PAGE_VIEW` - PAGE_VIEW
46
+ * `PERFORMANCE` - PERFORMANCE
47
+ * `CONSOLE` - CONSOLE */
51
48
  event_type: FrontendEventIngestRequestEventType;
52
49
  message: string;
53
- /** * `error` - Error
54
- * `warn` - Warning
55
- * `info` - Info
56
- * `debug` - Debug */
50
+ /** * `error` - error
51
+ * `warning` - warning
52
+ * `info` - info
53
+ * `debug` - debug */
57
54
  level?: FrontendEventIngestRequestLevel;
58
55
  stack_trace?: string;
59
56
  url?: string;
@@ -61,13 +58,12 @@ interface FrontendEventIngestRequest {
61
58
  http_status?: number | null;
62
59
  http_method?: string;
63
60
  http_url?: string;
61
+ session_id?: string;
64
62
  user_agent?: string;
65
- session_id?: string | null;
66
- browser_fingerprint?: string;
63
+ build_id?: string;
64
+ environment?: string;
67
65
  extra?: Record<string, any>;
68
66
  project_name?: string;
69
- environment?: string;
70
- build_id?: string;
71
67
  }
72
68
 
73
69
  /**
@@ -146,6 +142,8 @@ interface MonitorState {
146
142
  config: MonitorConfig;
147
143
  buffer: FrontendEventIngestRequest[];
148
144
  initialized: boolean;
145
+ _consecutiveFailures: number;
146
+ _pausedUntil: number;
149
147
  push: (event: FrontendEventIngestRequest) => void;
150
148
  flush: (useBeacon?: boolean) => void;
151
149
  setConfig: (config: MonitorConfig) => void;
package/dist/client.mjs CHANGED
@@ -325,7 +325,8 @@ var _Monitor = class _Monitor {
325
325
  /**
326
326
  * Ingest browser events
327
327
  *
328
- * Accepts a batch of up to 50 frontend events. No authentication required.
328
+ * Accepts a batch of up to 50 frontend events. No authentication required
329
+ * — anonymous visitors can send events.
329
330
  */
330
331
  async ingestCreate(data) {
331
332
  const response = await this.client.request("POST", "/cfg/monitor/ingest/", { body: data });
@@ -1103,19 +1104,18 @@ var MemoryStorageAdapter = _MemoryStorageAdapter;
1103
1104
 
1104
1105
  // src/_api/generated/cfg_monitor/enums.ts
1105
1106
  var FrontendEventIngestRequestEventType = /* @__PURE__ */ ((FrontendEventIngestRequestEventType2) => {
1107
+ FrontendEventIngestRequestEventType2["JS_ERROR"] = "JS_ERROR";
1108
+ FrontendEventIngestRequestEventType2["NETWORK_ERROR"] = "NETWORK_ERROR";
1106
1109
  FrontendEventIngestRequestEventType2["ERROR"] = "ERROR";
1107
1110
  FrontendEventIngestRequestEventType2["WARNING"] = "WARNING";
1108
- FrontendEventIngestRequestEventType2["INFO"] = "INFO";
1109
1111
  FrontendEventIngestRequestEventType2["PAGE_VIEW"] = "PAGE_VIEW";
1110
1112
  FrontendEventIngestRequestEventType2["PERFORMANCE"] = "PERFORMANCE";
1111
- FrontendEventIngestRequestEventType2["NETWORK_ERROR"] = "NETWORK_ERROR";
1112
- FrontendEventIngestRequestEventType2["JS_ERROR"] = "JS_ERROR";
1113
1113
  FrontendEventIngestRequestEventType2["CONSOLE"] = "CONSOLE";
1114
1114
  return FrontendEventIngestRequestEventType2;
1115
1115
  })(FrontendEventIngestRequestEventType || {});
1116
1116
  var FrontendEventIngestRequestLevel = /* @__PURE__ */ ((FrontendEventIngestRequestLevel2) => {
1117
1117
  FrontendEventIngestRequestLevel2["ERROR"] = "error";
1118
- FrontendEventIngestRequestLevel2["WARN"] = "warn";
1118
+ FrontendEventIngestRequestLevel2["WARNING"] = "warning";
1119
1119
  FrontendEventIngestRequestLevel2["INFO"] = "info";
1120
1120
  FrontendEventIngestRequestLevel2["DEBUG"] = "debug";
1121
1121
  return FrontendEventIngestRequestLevel2;
@@ -1133,13 +1133,12 @@ var FrontendEventIngestRequestSchema = z.object({
1133
1133
  http_status: z.number().int().nullable().optional(),
1134
1134
  http_method: z.string().max(10).optional(),
1135
1135
  http_url: z.string().max(2e3).optional(),
1136
+ session_id: z.string().max(64).optional(),
1136
1137
  user_agent: z.string().max(500).optional(),
1137
- session_id: z.string().regex(/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i).nullable().optional(),
1138
- browser_fingerprint: z.string().max(64).optional(),
1139
- extra: z.record(z.string(), z.any()).optional(),
1140
- project_name: z.string().max(100).optional(),
1138
+ build_id: z.string().max(100).optional(),
1141
1139
  environment: z.string().max(20).optional(),
1142
- build_id: z.string().max(100).optional()
1140
+ extra: z.record(z.string(), z.any()).optional(),
1141
+ project_name: z.string().max(100).optional()
1143
1142
  });
1144
1143
 
1145
1144
  // src/_api/generated/cfg_monitor/_utils/schemas/IngestBatchRequest.schema.ts
@@ -1326,23 +1325,24 @@ function syncBeaconBaseUrl() {
1326
1325
  __name(syncBeaconBaseUrl, "syncBeaconBaseUrl");
1327
1326
  async function sendBatch(batch, useBeacon = false) {
1328
1327
  if (batch.events.length === 0) return;
1329
- try {
1330
- if (useBeacon) {
1331
- syncBeaconBaseUrl();
1332
- await monitorApiBeacon.monitor.ingestCreate(batch);
1333
- } else {
1334
- await monitorApi.monitor.ingestCreate(batch);
1335
- }
1336
- } catch {
1328
+ if (useBeacon) {
1329
+ syncBeaconBaseUrl();
1330
+ await monitorApiBeacon.monitor.ingestCreate(batch);
1331
+ } else {
1332
+ await monitorApi.monitor.ingestCreate(batch);
1337
1333
  }
1338
1334
  }
1339
1335
  __name(sendBatch, "sendBatch");
1340
1336
 
1341
1337
  // src/client/store/index.ts
1338
+ var CIRCUIT_BREAKER_THRESHOLD = 3;
1339
+ var CIRCUIT_BREAKER_COOLDOWN_MS = 6e4;
1342
1340
  var monitorStore = createStore((set, get) => ({
1343
1341
  config: {},
1344
1342
  buffer: [],
1345
1343
  initialized: false,
1344
+ _consecutiveFailures: 0,
1345
+ _pausedUntil: 0,
1346
1346
  push(event) {
1347
1347
  const { config, buffer } = get();
1348
1348
  const maxSize = config.maxBufferSize ?? 20;
@@ -1368,23 +1368,40 @@ var monitorStore = createStore((set, get) => ({
1368
1368
  }
1369
1369
  },
1370
1370
  flush(useBeacon = false) {
1371
- const { buffer } = get();
1371
+ const { buffer, _pausedUntil } = get();
1372
1372
  if (buffer.length === 0) return;
1373
+ if (Date.now() < _pausedUntil) return;
1373
1374
  const batch = buffer.slice(0, 50);
1374
1375
  set({ buffer: buffer.slice(50) });
1375
- sendBatch({ events: batch }, useBeacon);
1376
+ sendBatch({ events: batch }, useBeacon).then(
1377
+ () => {
1378
+ set({ _consecutiveFailures: 0, _pausedUntil: 0 });
1379
+ },
1380
+ () => {
1381
+ const failures = get()._consecutiveFailures + 1;
1382
+ const pausedUntil = failures >= CIRCUIT_BREAKER_THRESHOLD ? Date.now() + CIRCUIT_BREAKER_COOLDOWN_MS : get()._pausedUntil;
1383
+ set({ _consecutiveFailures: failures, _pausedUntil: pausedUntil });
1384
+ }
1385
+ );
1376
1386
  },
1377
1387
  setConfig(config) {
1378
1388
  set({ config, initialized: true });
1379
1389
  }
1380
1390
  }));
1381
1391
 
1392
+ // src/client/constants.ts
1393
+ var MONITOR_INGEST_PATTERN = /cfg\/monitor\/ingest/;
1394
+
1382
1395
  // src/client/capture/js-errors.ts
1383
1396
  var MSG_MAX = 2e3;
1384
1397
  function truncate(s, max = MSG_MAX) {
1385
1398
  return s.length > max ? s.slice(0, max - 1) + "\u2026" : s;
1386
1399
  }
1387
1400
  __name(truncate, "truncate");
1401
+ function isMonitorOwnError(msg, stack) {
1402
+ return MONITOR_INGEST_PATTERN.test(msg) || MONITOR_INGEST_PATTERN.test(stack ?? "");
1403
+ }
1404
+ __name(isMonitorOwnError, "isMonitorOwnError");
1388
1405
  var HYDRATION_NOISE = [
1389
1406
  /hydration failed/i,
1390
1407
  /there was an error while hydrating/i,
@@ -1419,6 +1436,7 @@ function installJsErrorCapture() {
1419
1436
  const msg = truncate(typeof message === "string" ? message : String(message));
1420
1437
  if (isHydrationNoise(msg)) return;
1421
1438
  const stack = error?.stack ?? `at ${source}:${lineno}:${colno}`;
1439
+ if (isMonitorOwnError(msg, stack)) return;
1422
1440
  const url = window.location.href;
1423
1441
  const fingerprint = await computeFingerprint(msg, stack, url);
1424
1442
  if (isRecentlySent(fingerprint)) return;
@@ -1445,6 +1463,7 @@ function installJsErrorCapture() {
1445
1463
  const msg = truncate(reason instanceof Error ? reason.message : typeof reason === "string" ? reason : "Unhandled promise rejection");
1446
1464
  if (isHydrationNoise(msg)) return;
1447
1465
  const stack = reason instanceof Error ? reason.stack ?? "" : "";
1466
+ if (isMonitorOwnError(msg, stack)) return;
1448
1467
  const url = window.location.href;
1449
1468
  const fingerprint = await computeFingerprint(msg, stack, url);
1450
1469
  if (isRecentlySent(fingerprint)) return;
@@ -1477,7 +1496,7 @@ __name(installJsErrorCapture, "installJsErrorCapture");
1477
1496
 
1478
1497
  // src/client/capture/console.ts
1479
1498
  var levelMap = {
1480
- warn: "warn" /* WARN */,
1499
+ warn: "warning" /* WARNING */,
1481
1500
  error: "error" /* ERROR */
1482
1501
  };
1483
1502
  var typeMap = {
@@ -1506,6 +1525,7 @@ __name(stringify, "stringify");
1506
1525
  async function captureConsoleEvent(level, args) {
1507
1526
  try {
1508
1527
  const message = stringify(args);
1528
+ if (MONITOR_INGEST_PATTERN.test(message)) return;
1509
1529
  const url = typeof window !== "undefined" ? window.location.href : "";
1510
1530
  const fingerprint = await computeFingerprint(message, "", url);
1511
1531
  const { config } = monitorStore.getState();
@@ -1571,7 +1591,7 @@ function installValidationCapture() {
1571
1591
  const rawMsg = `Zod validation error in ${detail.operation}: ${detail.error?.message ?? "unknown"}`;
1572
1592
  monitorStore.getState().push({
1573
1593
  event_type: "WARNING" /* WARNING */,
1574
- level: "warn" /* WARN */,
1594
+ level: "warning" /* WARNING */,
1575
1595
  message: rawMsg.length > 500 ? rawMsg.slice(0, 499) + "\u2026" : rawMsg,
1576
1596
  url: window.location.href,
1577
1597
  http_method: detail.method,
@@ -1600,7 +1620,7 @@ async function monitoredFetch(input, init) {
1600
1620
  const { config } = monitorStore.getState();
1601
1621
  monitorStore.getState().push({
1602
1622
  event_type: "NETWORK_ERROR" /* NETWORK_ERROR */,
1603
- level: response.status >= 500 ? "error" /* ERROR */ : "warn" /* WARN */,
1623
+ level: response.status >= 500 ? "error" /* ERROR */ : "warning" /* WARNING */,
1604
1624
  message: `HTTP ${response.status} ${response.statusText} \u2014 ${method} ${url}`,
1605
1625
  url: typeof window !== "undefined" ? window.location.href : "",
1606
1626
  http_status: response.status,
@@ -1660,17 +1680,17 @@ function initWindowMonitor() {
1660
1680
  console.log("[monitor] error captured \u2192", message);
1661
1681
  },
1662
1682
  warn(message, extra) {
1663
- monitorStore.getState().push(makeEvent("WARNING" /* WARNING */, "warn" /* WARN */, message, extra));
1683
+ monitorStore.getState().push(makeEvent("WARNING" /* WARNING */, "warning" /* WARNING */, message, extra));
1664
1684
  console.log("[monitor] warn captured \u2192", message);
1665
1685
  },
1666
1686
  info(message, extra) {
1667
- monitorStore.getState().push(makeEvent("INFO" /* INFO */, "info" /* INFO */, message, extra));
1687
+ monitorStore.getState().push(makeEvent("WARNING" /* WARNING */, "info" /* INFO */, message, extra));
1668
1688
  console.log("[monitor] info captured \u2192", message);
1669
1689
  },
1670
1690
  network(status, method, url, extra) {
1671
1691
  const event = makeEvent(
1672
1692
  "NETWORK_ERROR" /* NETWORK_ERROR */,
1673
- status >= 500 ? "error" /* ERROR */ : "warn" /* WARN */,
1693
+ status >= 500 ? "error" /* ERROR */ : "warning" /* WARNING */,
1674
1694
  `${method} ${url} \u2192 ${status}`,
1675
1695
  extra
1676
1696
  );
@@ -1748,6 +1768,8 @@ var FrontendMonitor = {
1748
1768
  }
1749
1769
  };
1750
1770
  export {
1771
+ FrontendEventIngestRequestLevel as EventLevel,
1772
+ FrontendEventIngestRequestEventType as EventType,
1751
1773
  FrontendMonitor,
1752
1774
  MonitorProvider,
1753
1775
  getSessionId,