@localstack/appinspector-ui 1.0.185 → 1.0.187
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/index.cjs +146 -201
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +152 -207
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -13103,7 +13103,7 @@ var ResponsiveTimestampCell = (0, import_react31.memo)(({ date }) => {
|
|
|
13103
13103
|
|
|
13104
13104
|
// src/dev-settings.tsx
|
|
13105
13105
|
var React5 = __toESM(require("react"), 1);
|
|
13106
|
-
var DEFAULT_DEV_SETTINGS = { requestTerms: "on", waterfallIssueBackgrounds: "on", waterfallLayout: "tree", waterfallStatusIcons: "first column" };
|
|
13106
|
+
var DEFAULT_DEV_SETTINGS = { requestTerms: "on", warningIcon: "iam shield", waterfallIssueBackgrounds: "on", waterfallLayout: "tree", waterfallStatusIcons: "first column" };
|
|
13107
13107
|
var DevSettingsContext = React5.createContext(DEFAULT_DEV_SETTINGS);
|
|
13108
13108
|
var useDevSettings = () => React5.useContext(DevSettingsContext);
|
|
13109
13109
|
|
|
@@ -15355,22 +15355,6 @@ ServiceCell.displayName = "ServiceCell";
|
|
|
15355
15355
|
var import_icons_material2 = require("@mui/icons-material");
|
|
15356
15356
|
var import_material5 = require("@mui/material");
|
|
15357
15357
|
|
|
15358
|
-
// src/types/error-levels.ts
|
|
15359
|
-
var ErrorLevel = {
|
|
15360
|
-
ERROR: 3,
|
|
15361
|
-
// General error
|
|
15362
|
-
IAM_PERMISSION: 5,
|
|
15363
|
-
// IAM permission issues
|
|
15364
|
-
OK: 2,
|
|
15365
|
-
// OK
|
|
15366
|
-
// Standard OTEL status codes
|
|
15367
|
-
UNSET: 1,
|
|
15368
|
-
// Unset
|
|
15369
|
-
// Extended custom levels
|
|
15370
|
-
WARNING: 4
|
|
15371
|
-
// Warning
|
|
15372
|
-
};
|
|
15373
|
-
|
|
15374
15358
|
// src/utils/iam-utils.ts
|
|
15375
15359
|
function determinePermissionStatus(payload) {
|
|
15376
15360
|
if (payload.explicit_deny_count && payload.explicit_deny_count > 0) {
|
|
@@ -15469,58 +15453,40 @@ var getIamSummary = (span) => {
|
|
|
15469
15453
|
return { denials, level: void 0 };
|
|
15470
15454
|
};
|
|
15471
15455
|
|
|
15472
|
-
// src/utils/
|
|
15473
|
-
var
|
|
15474
|
-
|
|
15475
|
-
|
|
15476
|
-
|
|
15477
|
-
|
|
15478
|
-
}
|
|
15479
|
-
case "iam_explicit_deny":
|
|
15480
|
-
case "iam_explicit_warn":
|
|
15481
|
-
case "iam_implicit_deny":
|
|
15482
|
-
case "iam_implicit_warn": {
|
|
15483
|
-
return ErrorLevel.IAM_PERMISSION;
|
|
15484
|
-
}
|
|
15485
|
-
default: {
|
|
15486
|
-
return ErrorLevel.OK;
|
|
15487
|
-
}
|
|
15488
|
-
}
|
|
15456
|
+
// src/utils/span-issues.ts
|
|
15457
|
+
var firstText = (...values) => values.find((value) => !!value) ?? void 0;
|
|
15458
|
+
var OTEL_STATUS_ERROR = 2;
|
|
15459
|
+
var getIamDenials = (span) => span.events.flatMap((event) => {
|
|
15460
|
+
if (!event.event_type?.toLowerCase().includes("iam") || typeof event.attributes?.payload !== "string") {
|
|
15461
|
+
return [];
|
|
15489
15462
|
}
|
|
15490
|
-
const
|
|
15491
|
-
|
|
15492
|
-
|
|
15493
|
-
|
|
15494
|
-
|
|
15495
|
-
|
|
15496
|
-
|
|
15497
|
-
|
|
15498
|
-
const
|
|
15499
|
-
|
|
15500
|
-
const
|
|
15501
|
-
|
|
15502
|
-
|
|
15463
|
+
const permission = parseIAMEvent(event.attributes.payload)?.permission;
|
|
15464
|
+
if (permission === "explicitly_denied") return ["explicit"];
|
|
15465
|
+
if (permission === "implicitly_denied") return ["implicit"];
|
|
15466
|
+
return [];
|
|
15467
|
+
});
|
|
15468
|
+
var getSpanIssues = (span) => {
|
|
15469
|
+
const status = span.operation_status;
|
|
15470
|
+
const iamDenied = status === "iam_explicit_deny" || status === "iam_implicit_deny";
|
|
15471
|
+
const iamWarned = status === "iam_explicit_warn" || status === "iam_implicit_warn";
|
|
15472
|
+
const errorMessages = (span.errors ?? []).filter((item) => item.level === "error");
|
|
15473
|
+
const warningMessages = (span.errors ?? []).filter((item) => item.level === "warning");
|
|
15474
|
+
const denials = getIamDenials(span);
|
|
15475
|
+
const unenforcedDenial = !iamDenied && (denials.length > 0 || span.attributes?.["localstack.has_iam_deny_event"] === true);
|
|
15476
|
+
const error = status === "error" || iamDenied || span.status_code === OTEL_STATUS_ERROR || errorMessages.length > 0;
|
|
15477
|
+
const warning2 = iamWarned || warningMessages.length > 0 || unenforcedDenial;
|
|
15478
|
+
const denialCount = unenforcedDenial ? Math.max(1, denials.length) : 0;
|
|
15479
|
+
return {
|
|
15480
|
+
error,
|
|
15481
|
+
errorType: error ? firstText(span.status_message, errorMessages[0]?.message) ?? (iamDenied ? "AccessDenied" : "Error") : void 0,
|
|
15482
|
+
warning: warning2,
|
|
15483
|
+
warningCount: warning2 ? Math.max(1, warningMessages.length + denialCount) : 0,
|
|
15484
|
+
warningType: warning2 ? firstText(warningMessages[0]?.message) ?? (unenforcedDenial ? `IAM ${denials[0] ?? "implicit"} deny` : iamWarned ? "IAM permission warning" : "Warning") : void 0
|
|
15485
|
+
};
|
|
15503
15486
|
};
|
|
15504
15487
|
|
|
15505
15488
|
// src/components/cells/status-cell.tsx
|
|
15506
15489
|
var import_jsx_runtime125 = require("react/jsx-runtime");
|
|
15507
|
-
var StatusIcon = ({ errorLevel, operationStatus, spanStatusCode }) => {
|
|
15508
|
-
switch (errorLevel) {
|
|
15509
|
-
case ErrorLevel.ERROR: {
|
|
15510
|
-
return /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_icons_material2.Cancel, { sx: { color: "red" } });
|
|
15511
|
-
}
|
|
15512
|
-
case ErrorLevel.IAM_PERMISSION: {
|
|
15513
|
-
const isDenial = operationStatus ? operationStatus === "iam_explicit_deny" || operationStatus === "iam_implicit_deny" : spanStatusCode === 2;
|
|
15514
|
-
return /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_icons_material2.GppBad, { sx: { color: isDenial ? "red" : "warning.main" } });
|
|
15515
|
-
}
|
|
15516
|
-
case ErrorLevel.WARNING: {
|
|
15517
|
-
return /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_icons_material2.Error, { sx: { color: "orange" } });
|
|
15518
|
-
}
|
|
15519
|
-
default: {
|
|
15520
|
-
return /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_jsx_runtime125.Fragment, {});
|
|
15521
|
-
}
|
|
15522
|
-
}
|
|
15523
|
-
};
|
|
15524
15490
|
var SPAN_STATUS_LABELS = {
|
|
15525
15491
|
0: "Unset",
|
|
15526
15492
|
1: "OK",
|
|
@@ -15548,9 +15514,14 @@ var buildTooltipContent = (span) => {
|
|
|
15548
15514
|
] });
|
|
15549
15515
|
};
|
|
15550
15516
|
var StatusIconWithTooltip = ({ span }) => {
|
|
15551
|
-
const
|
|
15552
|
-
|
|
15553
|
-
|
|
15517
|
+
const { warningIcon } = useDevSettings();
|
|
15518
|
+
const { error, warning: warning2 } = getSpanIssues(span);
|
|
15519
|
+
if (!error && !warning2) return /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_jsx_runtime125.Fragment, {});
|
|
15520
|
+
const iamLevel = getIamSummary(span).level;
|
|
15521
|
+
return /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_material5.Tooltip, { title: buildTooltipContent(span), children: /* @__PURE__ */ (0, import_jsx_runtime125.jsxs)(import_material5.Box, { sx: { alignItems: "center", cursor: "default", display: "flex" }, children: [
|
|
15522
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_material5.Box, { "aria-label": "Error", role: "img", sx: { display: "flex" }, children: iamLevel === "error" ? /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_icons_material2.GppBad, { sx: { color: "error.main" } }) : /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_icons_material2.Cancel, { sx: { color: "error.main" } }) }),
|
|
15523
|
+
warning2 && /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_material5.Box, { "aria-label": "Warning", role: "img", sx: { display: "flex" }, children: iamLevel === "warning" && warningIcon === "iam shield" ? /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_icons_material2.GppBad, { sx: { color: "warning.main" } }) : /* @__PURE__ */ (0, import_jsx_runtime125.jsx)(import_icons_material2.Error, { sx: { color: "warning.main" } }) })
|
|
15524
|
+
] }) });
|
|
15554
15525
|
};
|
|
15555
15526
|
|
|
15556
15527
|
// src/components/spans-list/span-count-badge.tsx
|
|
@@ -16635,6 +16606,94 @@ var StatusMessage = ({
|
|
|
16635
16606
|
return /* @__PURE__ */ (0, import_jsx_runtime130.jsx)(import_jsx_runtime130.Fragment, {});
|
|
16636
16607
|
};
|
|
16637
16608
|
|
|
16609
|
+
// src/utils/span-parents.ts
|
|
16610
|
+
var resolveParents = (spans) => {
|
|
16611
|
+
const byId = new Map(spans.map((span) => [span.span_id, span]));
|
|
16612
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
16613
|
+
for (const span of spans) {
|
|
16614
|
+
const parent = span.parent_span_id === null ? void 0 : byId.get(span.parent_span_id);
|
|
16615
|
+
if (parent && parent.span_id !== span.span_id && parent.trace_id === span.trace_id) {
|
|
16616
|
+
parentOf.set(span.span_id, parent.span_id);
|
|
16617
|
+
}
|
|
16618
|
+
}
|
|
16619
|
+
const causes = /* @__PURE__ */ new Map();
|
|
16620
|
+
const addCause = (spanId, causeId) => {
|
|
16621
|
+
const list = causes.get(spanId);
|
|
16622
|
+
if (list) list.push(causeId);
|
|
16623
|
+
else causes.set(spanId, [causeId]);
|
|
16624
|
+
};
|
|
16625
|
+
for (const span of spans) {
|
|
16626
|
+
for (const causeId of span.outgoing_link_span_ids ?? []) addCause(span.span_id, causeId);
|
|
16627
|
+
for (const effectId of span.incoming_link_span_ids ?? []) addCause(effectId, span.span_id);
|
|
16628
|
+
}
|
|
16629
|
+
const isAncestorOrSelf = (candidateId, spanId) => {
|
|
16630
|
+
let current = spanId;
|
|
16631
|
+
for (let hops = 0; current !== void 0 && hops <= spans.length; hops++) {
|
|
16632
|
+
if (current === candidateId) return true;
|
|
16633
|
+
current = parentOf.get(current);
|
|
16634
|
+
}
|
|
16635
|
+
return false;
|
|
16636
|
+
};
|
|
16637
|
+
for (const span of spans) {
|
|
16638
|
+
if (parentOf.has(span.span_id)) continue;
|
|
16639
|
+
const cause = causes.get(span.span_id)?.find((causeId) => byId.has(causeId) && !isAncestorOrSelf(span.span_id, causeId));
|
|
16640
|
+
if (cause !== void 0) parentOf.set(span.span_id, cause);
|
|
16641
|
+
}
|
|
16642
|
+
return parentOf;
|
|
16643
|
+
};
|
|
16644
|
+
|
|
16645
|
+
// src/components/trace-panel/timeline-tree.ts
|
|
16646
|
+
var compareNano = (left, right) => {
|
|
16647
|
+
const difference = BigInt(left) - BigInt(right);
|
|
16648
|
+
if (difference === 0n) return 0;
|
|
16649
|
+
return difference < 0n ? -1 : 1;
|
|
16650
|
+
};
|
|
16651
|
+
var buildTraceTree = (spans) => {
|
|
16652
|
+
const nodes2 = new Map(spans.map((span) => [span.span_id, { children: [], span }]));
|
|
16653
|
+
const parentOf = resolveParents(spans);
|
|
16654
|
+
const roots = [];
|
|
16655
|
+
for (const [spanId, node] of nodes2) {
|
|
16656
|
+
const parent = parentOf.get(spanId);
|
|
16657
|
+
if (parent === void 0) roots.push(node);
|
|
16658
|
+
else nodes2.get(parent)?.children.push(node);
|
|
16659
|
+
}
|
|
16660
|
+
const byStart = (left, right) => compareNano(left.span.start_time_unix_nano, right.span.start_time_unix_nano);
|
|
16661
|
+
roots.sort(byStart);
|
|
16662
|
+
for (const node of nodes2.values()) node.children.sort(byStart);
|
|
16663
|
+
return { parentOf, roots };
|
|
16664
|
+
};
|
|
16665
|
+
var findRootSpan = (spans, parentOf, spanId) => {
|
|
16666
|
+
let current = spanId;
|
|
16667
|
+
for (let hops = 0; hops <= spans.length; hops++) {
|
|
16668
|
+
const parent = parentOf.get(current);
|
|
16669
|
+
if (parent === void 0) break;
|
|
16670
|
+
current = parent;
|
|
16671
|
+
}
|
|
16672
|
+
return spans.find((span) => span.span_id === current);
|
|
16673
|
+
};
|
|
16674
|
+
var findFirstSpan = (nodes2, predicate) => {
|
|
16675
|
+
for (const node of nodes2) {
|
|
16676
|
+
if (predicate(node.span.span_id)) return node.span;
|
|
16677
|
+
const found = findFirstSpan(node.children, predicate);
|
|
16678
|
+
if (found) return found;
|
|
16679
|
+
}
|
|
16680
|
+
return void 0;
|
|
16681
|
+
};
|
|
16682
|
+
var getTraceBounds = (spans) => {
|
|
16683
|
+
let start;
|
|
16684
|
+
let end;
|
|
16685
|
+
for (const span of spans) {
|
|
16686
|
+
const spanStart = BigInt(span.start_time_unix_nano);
|
|
16687
|
+
const spanEnd = span.end_time_unix_nano ? BigInt(span.end_time_unix_nano) : spanStart;
|
|
16688
|
+
if (start === void 0 || spanStart < start) start = spanStart;
|
|
16689
|
+
if (end === void 0 || spanEnd > end) end = spanEnd;
|
|
16690
|
+
}
|
|
16691
|
+
if (start === void 0 || end === void 0) {
|
|
16692
|
+
return { durationMs: 0, startNano: 0n };
|
|
16693
|
+
}
|
|
16694
|
+
return { durationMs: Number(end - start) / 1e6, startNano: start };
|
|
16695
|
+
};
|
|
16696
|
+
|
|
16638
16697
|
// src/components/trace-panel/trace-sidebar.tsx
|
|
16639
16698
|
var import_icons_material15 = require("@mui/icons-material");
|
|
16640
16699
|
var import_material25 = require("@mui/material");
|
|
@@ -16754,38 +16813,6 @@ var getEventGroupsByType = (events) => {
|
|
|
16754
16813
|
return groups;
|
|
16755
16814
|
};
|
|
16756
16815
|
|
|
16757
|
-
// src/utils/span-issues.ts
|
|
16758
|
-
var firstText = (...values) => values.find((value) => !!value) ?? void 0;
|
|
16759
|
-
var OTEL_STATUS_ERROR = 2;
|
|
16760
|
-
var getIamDenials = (span) => span.events.flatMap((event) => {
|
|
16761
|
-
if (!event.event_type?.toLowerCase().includes("iam") || typeof event.attributes?.payload !== "string") {
|
|
16762
|
-
return [];
|
|
16763
|
-
}
|
|
16764
|
-
const permission = parseIAMEvent(event.attributes.payload)?.permission;
|
|
16765
|
-
if (permission === "explicitly_denied") return ["explicit"];
|
|
16766
|
-
if (permission === "implicitly_denied") return ["implicit"];
|
|
16767
|
-
return [];
|
|
16768
|
-
});
|
|
16769
|
-
var getSpanIssues = (span) => {
|
|
16770
|
-
const status = span.operation_status;
|
|
16771
|
-
const iamDenied = status === "iam_explicit_deny" || status === "iam_implicit_deny";
|
|
16772
|
-
const iamWarned = status === "iam_explicit_warn" || status === "iam_implicit_warn";
|
|
16773
|
-
const errorMessages = (span.errors ?? []).filter((item) => item.level === "error");
|
|
16774
|
-
const warningMessages = (span.errors ?? []).filter((item) => item.level === "warning");
|
|
16775
|
-
const denials = getIamDenials(span);
|
|
16776
|
-
const unenforcedDenial = !iamDenied && (denials.length > 0 || span.attributes?.["localstack.has_iam_deny_event"] === true);
|
|
16777
|
-
const error = status === "error" || iamDenied || span.status_code === OTEL_STATUS_ERROR || errorMessages.length > 0;
|
|
16778
|
-
const warning2 = iamWarned || warningMessages.length > 0 || unenforcedDenial;
|
|
16779
|
-
const denialCount = unenforcedDenial ? Math.max(1, denials.length) : 0;
|
|
16780
|
-
return {
|
|
16781
|
-
error,
|
|
16782
|
-
errorType: error ? firstText(span.status_message, errorMessages[0]?.message) ?? (iamDenied ? "AccessDenied" : "Error") : void 0,
|
|
16783
|
-
warning: warning2,
|
|
16784
|
-
warningCount: warning2 ? Math.max(1, warningMessages.length + denialCount) : 0,
|
|
16785
|
-
warningType: warning2 ? firstText(warningMessages[0]?.message) ?? (unenforcedDenial ? `IAM ${denials[0] ?? "implicit"} deny` : iamWarned ? "IAM permission warning" : "Warning") : void 0
|
|
16786
|
-
};
|
|
16787
|
-
};
|
|
16788
|
-
|
|
16789
16816
|
// src/utils/time.ts
|
|
16790
16817
|
function unixNanoToDate(unixNanoString) {
|
|
16791
16818
|
const milliseconds = unixNanoToMilliseconds(unixNanoString);
|
|
@@ -16834,7 +16861,7 @@ var import_react44 = require("react");
|
|
|
16834
16861
|
var import_icons_material8 = require("@mui/icons-material");
|
|
16835
16862
|
var import_material12 = require("@mui/material");
|
|
16836
16863
|
var import_jsx_runtime132 = require("react/jsx-runtime");
|
|
16837
|
-
var
|
|
16864
|
+
var StatusIcon = ({ errorLevel }) => {
|
|
16838
16865
|
switch (errorLevel) {
|
|
16839
16866
|
case EventLevel.LevelError: {
|
|
16840
16867
|
return /* @__PURE__ */ (0, import_jsx_runtime132.jsx)(import_icons_material8.Cancel, { sx: { color: "red" } });
|
|
@@ -18935,7 +18962,7 @@ var EventDetail = ({
|
|
|
18935
18962
|
const eventLevel = getEventLevelFromGroup(type);
|
|
18936
18963
|
return /* @__PURE__ */ (0, import_jsx_runtime137.jsxs)(import_material17.Box, { children: [
|
|
18937
18964
|
/* @__PURE__ */ (0, import_jsx_runtime137.jsxs)(import_material17.Box, { sx: { alignItems: "center", display: "flex", mb: 0.5 }, children: [
|
|
18938
|
-
/* @__PURE__ */ (0, import_jsx_runtime137.jsx)(
|
|
18965
|
+
/* @__PURE__ */ (0, import_jsx_runtime137.jsx)(StatusIcon, { errorLevel: eventLevel }),
|
|
18939
18966
|
/* @__PURE__ */ (0, import_jsx_runtime137.jsx)(import_material17.Typography, { color: "text.secondary", sx: { fontWeight: 600, ml: 0.5 }, variant: "caption", children: displayText })
|
|
18940
18967
|
] }),
|
|
18941
18968
|
/* @__PURE__ */ (0, import_jsx_runtime137.jsx)(import_material17.Box, { children: events.map((event) => /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(import_material17.Box, { sx: { maxWidth: "100%", mb: 0.5 }, children: /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(EventMessage, { event }) }, `${event.span_id}-${event.event_id}`)) })
|
|
@@ -31584,8 +31611,9 @@ var handleStyle = {
|
|
|
31584
31611
|
borderColor: "lightgray",
|
|
31585
31612
|
opacity: 0
|
|
31586
31613
|
};
|
|
31587
|
-
var NodeContent = ({ event, expanded,
|
|
31614
|
+
var NodeContent = ({ event, expanded, iamLevel, issues }) => {
|
|
31588
31615
|
const theme = (0, import_material20.useTheme)();
|
|
31616
|
+
const { warningIcon } = useDevSettings();
|
|
31589
31617
|
return /* @__PURE__ */ (0, import_jsx_runtime143.jsxs)(import_jsx_runtime143.Fragment, { children: [
|
|
31590
31618
|
/* @__PURE__ */ (0, import_jsx_runtime143.jsx)(import_react52.Handle, { position: import_react52.Position.Left, style: handleStyle, type: "target" }),
|
|
31591
31619
|
/* @__PURE__ */ (0, import_jsx_runtime143.jsx)(import_react52.Handle, { position: import_react52.Position.Right, style: handleStyle, type: "source" }),
|
|
@@ -31640,8 +31668,8 @@ var NodeContent = ({ event, expanded, hasPermissionEvents, isError, isWarning })
|
|
|
31640
31668
|
width: "38px"
|
|
31641
31669
|
},
|
|
31642
31670
|
children: [
|
|
31643
|
-
|
|
31644
|
-
|
|
31671
|
+
issues.error && /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(import_material20.Tooltip, { arrow: true, title: issues.errorType, children: /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(import_material20.Box, { "aria-label": "Error", role: "img", sx: { display: "flex" }, children: iamLevel === "error" ? /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(import_icons_material12.GppBad, { sx: { color: theme.palette.error.main, fontSize: "16px" } }) : /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(import_icons_material12.Cancel, { sx: { color: theme.palette.error.main, fontSize: "16px" } }) }) }),
|
|
31672
|
+
issues.warning && /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(import_material20.Tooltip, { arrow: true, title: issues.warningType, children: /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(import_material20.Box, { "aria-label": "Warning", role: "img", sx: { display: "flex" }, children: iamLevel === "warning" && warningIcon === "iam shield" ? /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(import_icons_material12.GppBad, { sx: { color: theme.palette.warning.main, fontSize: "16px" } }) : /* @__PURE__ */ (0, import_jsx_runtime143.jsx)(import_icons_material12.Error, { sx: { color: theme.palette.warning.main, fontSize: "16px" } }) }) })
|
|
31645
31673
|
]
|
|
31646
31674
|
}
|
|
31647
31675
|
),
|
|
@@ -31664,17 +31692,9 @@ var ServiceNode = (0, import_react53.memo)(({ data, selected }) => {
|
|
|
31664
31692
|
const theme = (0, import_material20.useTheme)();
|
|
31665
31693
|
const [isHovered, setIsHovered] = (0, import_react53.useState)(false);
|
|
31666
31694
|
const nodeRef = (0, import_react53.useRef)(null);
|
|
31667
|
-
const
|
|
31668
|
-
const
|
|
31669
|
-
|
|
31670
|
-
(event) => event.event_type === "iam.policy_evaluation" && event.name === "iam.policy.denied"
|
|
31671
|
-
),
|
|
31672
|
-
[data.event.events]
|
|
31673
|
-
);
|
|
31674
|
-
const isError = operation_status ? operation_status === "error" || operation_status === "iam_explicit_deny" || operation_status === "iam_implicit_deny" : data.event.status_code === 2;
|
|
31675
|
-
const isWarning = operation_status ? operation_status === "iam_explicit_warn" || operation_status === "iam_implicit_warn" : !isError && data.event.status_code === 1 && hasPermissionEventsLegacy;
|
|
31676
|
-
const hasPermissionEvents = operation_status ? operation_status.startsWith("iam_") : hasPermissionEventsLegacy;
|
|
31677
|
-
const outlineColor = isError ? theme.palette.error.main : isWarning ? theme.palette.warning.main : void 0;
|
|
31695
|
+
const issues = getSpanIssues(data.event);
|
|
31696
|
+
const iamLevel = getIamSummary(data.event).level;
|
|
31697
|
+
const outlineColor = issues.error ? theme.palette.error.main : issues.warning ? theme.palette.warning.main : void 0;
|
|
31678
31698
|
const sharedBoxSx = {
|
|
31679
31699
|
backgroundColor: theme.palette.background.paper,
|
|
31680
31700
|
borderLeft: `3px solid ${outlineColor ?? "transparent"}`,
|
|
@@ -31683,7 +31703,7 @@ var ServiceNode = (0, import_react53.memo)(({ data, selected }) => {
|
|
|
31683
31703
|
minWidth: 140,
|
|
31684
31704
|
outline: selected ? `2px solid ${outlineColor ?? theme.palette.primary.main}` : `1px solid ${theme.palette.divider}`
|
|
31685
31705
|
};
|
|
31686
|
-
const contentProps = { event: data.event,
|
|
31706
|
+
const contentProps = { event: data.event, iamLevel, issues };
|
|
31687
31707
|
const handleMouseEnter = () => {
|
|
31688
31708
|
setIsHovered(true);
|
|
31689
31709
|
const xyNode = nodeRef.current?.closest(".react-flow__node");
|
|
@@ -32191,86 +32211,6 @@ function useLocalStorage(key, initialValue) {
|
|
|
32191
32211
|
return [storedValue, setValue];
|
|
32192
32212
|
}
|
|
32193
32213
|
|
|
32194
|
-
// src/utils/span-parents.ts
|
|
32195
|
-
var resolveParents = (spans) => {
|
|
32196
|
-
const byId = new Map(spans.map((span) => [span.span_id, span]));
|
|
32197
|
-
const parentOf = /* @__PURE__ */ new Map();
|
|
32198
|
-
for (const span of spans) {
|
|
32199
|
-
const parent = span.parent_span_id === null ? void 0 : byId.get(span.parent_span_id);
|
|
32200
|
-
if (parent && parent.span_id !== span.span_id && parent.trace_id === span.trace_id) {
|
|
32201
|
-
parentOf.set(span.span_id, parent.span_id);
|
|
32202
|
-
}
|
|
32203
|
-
}
|
|
32204
|
-
const causes = /* @__PURE__ */ new Map();
|
|
32205
|
-
const addCause = (spanId, causeId) => {
|
|
32206
|
-
const list = causes.get(spanId);
|
|
32207
|
-
if (list) list.push(causeId);
|
|
32208
|
-
else causes.set(spanId, [causeId]);
|
|
32209
|
-
};
|
|
32210
|
-
for (const span of spans) {
|
|
32211
|
-
for (const causeId of span.outgoing_link_span_ids ?? []) addCause(span.span_id, causeId);
|
|
32212
|
-
for (const effectId of span.incoming_link_span_ids ?? []) addCause(effectId, span.span_id);
|
|
32213
|
-
}
|
|
32214
|
-
const isAncestorOrSelf = (candidateId, spanId) => {
|
|
32215
|
-
let current = spanId;
|
|
32216
|
-
for (let hops = 0; current !== void 0 && hops <= spans.length; hops++) {
|
|
32217
|
-
if (current === candidateId) return true;
|
|
32218
|
-
current = parentOf.get(current);
|
|
32219
|
-
}
|
|
32220
|
-
return false;
|
|
32221
|
-
};
|
|
32222
|
-
for (const span of spans) {
|
|
32223
|
-
if (parentOf.has(span.span_id)) continue;
|
|
32224
|
-
const cause = causes.get(span.span_id)?.find((causeId) => byId.has(causeId) && !isAncestorOrSelf(span.span_id, causeId));
|
|
32225
|
-
if (cause !== void 0) parentOf.set(span.span_id, cause);
|
|
32226
|
-
}
|
|
32227
|
-
return parentOf;
|
|
32228
|
-
};
|
|
32229
|
-
|
|
32230
|
-
// src/components/trace-panel/timeline-tree.ts
|
|
32231
|
-
var compareNano = (left, right) => {
|
|
32232
|
-
const difference = BigInt(left) - BigInt(right);
|
|
32233
|
-
if (difference === 0n) return 0;
|
|
32234
|
-
return difference < 0n ? -1 : 1;
|
|
32235
|
-
};
|
|
32236
|
-
var buildTraceTree = (spans) => {
|
|
32237
|
-
const nodes2 = new Map(spans.map((span) => [span.span_id, { children: [], span }]));
|
|
32238
|
-
const parentOf = resolveParents(spans);
|
|
32239
|
-
const roots = [];
|
|
32240
|
-
for (const [spanId, node] of nodes2) {
|
|
32241
|
-
const parent = parentOf.get(spanId);
|
|
32242
|
-
if (parent === void 0) roots.push(node);
|
|
32243
|
-
else nodes2.get(parent)?.children.push(node);
|
|
32244
|
-
}
|
|
32245
|
-
const byStart = (left, right) => compareNano(left.span.start_time_unix_nano, right.span.start_time_unix_nano);
|
|
32246
|
-
roots.sort(byStart);
|
|
32247
|
-
for (const node of nodes2.values()) node.children.sort(byStart);
|
|
32248
|
-
return { parentOf, roots };
|
|
32249
|
-
};
|
|
32250
|
-
var findRootSpan = (spans, parentOf, spanId) => {
|
|
32251
|
-
let current = spanId;
|
|
32252
|
-
for (let hops = 0; hops <= spans.length; hops++) {
|
|
32253
|
-
const parent = parentOf.get(current);
|
|
32254
|
-
if (parent === void 0) break;
|
|
32255
|
-
current = parent;
|
|
32256
|
-
}
|
|
32257
|
-
return spans.find((span) => span.span_id === current);
|
|
32258
|
-
};
|
|
32259
|
-
var getTraceBounds = (spans) => {
|
|
32260
|
-
let start;
|
|
32261
|
-
let end;
|
|
32262
|
-
for (const span of spans) {
|
|
32263
|
-
const spanStart = BigInt(span.start_time_unix_nano);
|
|
32264
|
-
const spanEnd = span.end_time_unix_nano ? BigInt(span.end_time_unix_nano) : spanStart;
|
|
32265
|
-
if (start === void 0 || spanStart < start) start = spanStart;
|
|
32266
|
-
if (end === void 0 || spanEnd > end) end = spanEnd;
|
|
32267
|
-
}
|
|
32268
|
-
if (start === void 0 || end === void 0) {
|
|
32269
|
-
return { durationMs: 0, startNano: 0n };
|
|
32270
|
-
}
|
|
32271
|
-
return { durationMs: Number(end - start) / 1e6, startNano: start };
|
|
32272
|
-
};
|
|
32273
|
-
|
|
32274
32214
|
// src/components/trace-panel/waterfall.tsx
|
|
32275
32215
|
var import_icons_material14 = require("@mui/icons-material");
|
|
32276
32216
|
var import_material24 = require("@mui/material");
|
|
@@ -33570,17 +33510,22 @@ var SpansListPage = () => {
|
|
|
33570
33510
|
const [bannerDismissed, setBannerDismissed] = (0, import_react65.useState)(false);
|
|
33571
33511
|
const [order2, setOrder] = useLocalStorage("spans-order", "oldest_first");
|
|
33572
33512
|
const [selectedSpanId, setSelectedSpanId] = (0, import_react65.useState)();
|
|
33513
|
+
const getTreeSpans = (0, import_react65.useCallback)((rootSpanId2) => Object.entries(compute.rows).filter(([, row]) => row.rootSpanId === rootSpanId2).map(([spanId]) => getSpan(spanId)).filter((span) => span !== void 0), [compute.rows, getSpan]);
|
|
33514
|
+
const latestRef = (0, import_react65.useRef)({ compute, getTreeSpans });
|
|
33515
|
+
(0, import_react65.useEffect)(() => {
|
|
33516
|
+
latestRef.current = { compute, getTreeSpans };
|
|
33517
|
+
}, [compute, getTreeSpans]);
|
|
33573
33518
|
const navigateToSpan = (0, import_react65.useCallback)((span) => {
|
|
33574
|
-
|
|
33519
|
+
const { compute: { queryActive, rows }, getTreeSpans: getSpans } = latestRef.current;
|
|
33520
|
+
const rootSpanId2 = rows[span.span_id]?.rootSpanId;
|
|
33521
|
+
const firstMatch = queryActive && rootSpanId2 !== void 0 ? findFirstSpan(buildTraceTree(getSpans(rootSpanId2)).roots, (spanId) => rows[spanId]?.matches ?? false) : void 0;
|
|
33522
|
+
setSelectedSpanId(firstMatch?.span_id ?? span.span_id);
|
|
33575
33523
|
}, []);
|
|
33576
33524
|
const closeSidebar = (0, import_react65.useCallback)(() => {
|
|
33577
33525
|
setSelectedSpanId(void 0);
|
|
33578
33526
|
}, []);
|
|
33579
33527
|
const rootSpanId = selectedSpanId === void 0 ? void 0 : compute.rows[selectedSpanId]?.rootSpanId;
|
|
33580
|
-
const treeSpans = (0, import_react65.useMemo)(() =>
|
|
33581
|
-
if (rootSpanId === void 0) return [];
|
|
33582
|
-
return Object.entries(compute.rows).filter(([, row]) => row.rootSpanId === rootSpanId).map(([spanId]) => getSpan(spanId)).filter((span) => span !== void 0);
|
|
33583
|
-
}, [compute.rows, getSpan, rootSpanId]);
|
|
33528
|
+
const treeSpans = (0, import_react65.useMemo)(() => rootSpanId === void 0 ? [] : getTreeSpans(rootSpanId), [getTreeSpans, rootSpanId]);
|
|
33584
33529
|
const spanMatches = (0, import_react65.useMemo)(
|
|
33585
33530
|
() => compute.queryActive ? (spanId) => compute.rows[spanId]?.matches ?? false : void 0,
|
|
33586
33531
|
[compute]
|