@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.js
CHANGED
|
@@ -2422,7 +2422,7 @@ var init_event_streams = __esm({
|
|
|
2422
2422
|
|
|
2423
2423
|
// src/pages/spans-list-page.tsx
|
|
2424
2424
|
import { Box as Box22, Paper as Paper2 } from "@mui/material";
|
|
2425
|
-
import { useCallback as useCallback12, useEffect as useEffect22, useMemo as
|
|
2425
|
+
import { useCallback as useCallback12, useEffect as useEffect22, useMemo as useMemo13, useRef as useRef19, useState as useState22 } from "react";
|
|
2426
2426
|
|
|
2427
2427
|
// src/api/errors.ts
|
|
2428
2428
|
var AppInspectorDisabledError = class extends Error {
|
|
@@ -13116,7 +13116,7 @@ var ResponsiveTimestampCell = memo3(({ date }) => {
|
|
|
13116
13116
|
|
|
13117
13117
|
// src/dev-settings.tsx
|
|
13118
13118
|
import * as React5 from "react";
|
|
13119
|
-
var DEFAULT_DEV_SETTINGS = { requestTerms: "on", waterfallIssueBackgrounds: "on", waterfallLayout: "tree", waterfallStatusIcons: "first column" };
|
|
13119
|
+
var DEFAULT_DEV_SETTINGS = { requestTerms: "on", warningIcon: "iam shield", waterfallIssueBackgrounds: "on", waterfallLayout: "tree", waterfallStatusIcons: "first column" };
|
|
13120
13120
|
var DevSettingsContext = React5.createContext(DEFAULT_DEV_SETTINGS);
|
|
13121
13121
|
var useDevSettings = () => React5.useContext(DevSettingsContext);
|
|
13122
13122
|
|
|
@@ -15368,22 +15368,6 @@ ServiceCell.displayName = "ServiceCell";
|
|
|
15368
15368
|
import { Cancel as Cancel2, Error as Error2, GppBad } from "@mui/icons-material";
|
|
15369
15369
|
import { Box as Box3, Divider, Tooltip as Tooltip3, Typography as Typography3 } from "@mui/material";
|
|
15370
15370
|
|
|
15371
|
-
// src/types/error-levels.ts
|
|
15372
|
-
var ErrorLevel = {
|
|
15373
|
-
ERROR: 3,
|
|
15374
|
-
// General error
|
|
15375
|
-
IAM_PERMISSION: 5,
|
|
15376
|
-
// IAM permission issues
|
|
15377
|
-
OK: 2,
|
|
15378
|
-
// OK
|
|
15379
|
-
// Standard OTEL status codes
|
|
15380
|
-
UNSET: 1,
|
|
15381
|
-
// Unset
|
|
15382
|
-
// Extended custom levels
|
|
15383
|
-
WARNING: 4
|
|
15384
|
-
// Warning
|
|
15385
|
-
};
|
|
15386
|
-
|
|
15387
15371
|
// src/utils/iam-utils.ts
|
|
15388
15372
|
function determinePermissionStatus(payload) {
|
|
15389
15373
|
if (payload.explicit_deny_count && payload.explicit_deny_count > 0) {
|
|
@@ -15482,58 +15466,40 @@ var getIamSummary = (span) => {
|
|
|
15482
15466
|
return { denials, level: void 0 };
|
|
15483
15467
|
};
|
|
15484
15468
|
|
|
15485
|
-
// src/utils/
|
|
15486
|
-
var
|
|
15487
|
-
|
|
15488
|
-
|
|
15489
|
-
|
|
15490
|
-
|
|
15491
|
-
}
|
|
15492
|
-
case "iam_explicit_deny":
|
|
15493
|
-
case "iam_explicit_warn":
|
|
15494
|
-
case "iam_implicit_deny":
|
|
15495
|
-
case "iam_implicit_warn": {
|
|
15496
|
-
return ErrorLevel.IAM_PERMISSION;
|
|
15497
|
-
}
|
|
15498
|
-
default: {
|
|
15499
|
-
return ErrorLevel.OK;
|
|
15500
|
-
}
|
|
15501
|
-
}
|
|
15469
|
+
// src/utils/span-issues.ts
|
|
15470
|
+
var firstText = (...values) => values.find((value) => !!value) ?? void 0;
|
|
15471
|
+
var OTEL_STATUS_ERROR = 2;
|
|
15472
|
+
var getIamDenials = (span) => span.events.flatMap((event) => {
|
|
15473
|
+
if (!event.event_type?.toLowerCase().includes("iam") || typeof event.attributes?.payload !== "string") {
|
|
15474
|
+
return [];
|
|
15502
15475
|
}
|
|
15503
|
-
const
|
|
15504
|
-
|
|
15505
|
-
|
|
15506
|
-
|
|
15507
|
-
|
|
15508
|
-
|
|
15509
|
-
|
|
15510
|
-
|
|
15511
|
-
const
|
|
15512
|
-
|
|
15513
|
-
const
|
|
15514
|
-
|
|
15515
|
-
|
|
15476
|
+
const permission = parseIAMEvent(event.attributes.payload)?.permission;
|
|
15477
|
+
if (permission === "explicitly_denied") return ["explicit"];
|
|
15478
|
+
if (permission === "implicitly_denied") return ["implicit"];
|
|
15479
|
+
return [];
|
|
15480
|
+
});
|
|
15481
|
+
var getSpanIssues = (span) => {
|
|
15482
|
+
const status = span.operation_status;
|
|
15483
|
+
const iamDenied = status === "iam_explicit_deny" || status === "iam_implicit_deny";
|
|
15484
|
+
const iamWarned = status === "iam_explicit_warn" || status === "iam_implicit_warn";
|
|
15485
|
+
const errorMessages = (span.errors ?? []).filter((item) => item.level === "error");
|
|
15486
|
+
const warningMessages = (span.errors ?? []).filter((item) => item.level === "warning");
|
|
15487
|
+
const denials = getIamDenials(span);
|
|
15488
|
+
const unenforcedDenial = !iamDenied && (denials.length > 0 || span.attributes?.["localstack.has_iam_deny_event"] === true);
|
|
15489
|
+
const error = status === "error" || iamDenied || span.status_code === OTEL_STATUS_ERROR || errorMessages.length > 0;
|
|
15490
|
+
const warning2 = iamWarned || warningMessages.length > 0 || unenforcedDenial;
|
|
15491
|
+
const denialCount = unenforcedDenial ? Math.max(1, denials.length) : 0;
|
|
15492
|
+
return {
|
|
15493
|
+
error,
|
|
15494
|
+
errorType: error ? firstText(span.status_message, errorMessages[0]?.message) ?? (iamDenied ? "AccessDenied" : "Error") : void 0,
|
|
15495
|
+
warning: warning2,
|
|
15496
|
+
warningCount: warning2 ? Math.max(1, warningMessages.length + denialCount) : 0,
|
|
15497
|
+
warningType: warning2 ? firstText(warningMessages[0]?.message) ?? (unenforcedDenial ? `IAM ${denials[0] ?? "implicit"} deny` : iamWarned ? "IAM permission warning" : "Warning") : void 0
|
|
15498
|
+
};
|
|
15516
15499
|
};
|
|
15517
15500
|
|
|
15518
15501
|
// src/components/cells/status-cell.tsx
|
|
15519
15502
|
import { Fragment as Fragment2, jsx as jsx125, jsxs as jsxs120 } from "react/jsx-runtime";
|
|
15520
|
-
var StatusIcon = ({ errorLevel, operationStatus, spanStatusCode }) => {
|
|
15521
|
-
switch (errorLevel) {
|
|
15522
|
-
case ErrorLevel.ERROR: {
|
|
15523
|
-
return /* @__PURE__ */ jsx125(Cancel2, { sx: { color: "red" } });
|
|
15524
|
-
}
|
|
15525
|
-
case ErrorLevel.IAM_PERMISSION: {
|
|
15526
|
-
const isDenial = operationStatus ? operationStatus === "iam_explicit_deny" || operationStatus === "iam_implicit_deny" : spanStatusCode === 2;
|
|
15527
|
-
return /* @__PURE__ */ jsx125(GppBad, { sx: { color: isDenial ? "red" : "warning.main" } });
|
|
15528
|
-
}
|
|
15529
|
-
case ErrorLevel.WARNING: {
|
|
15530
|
-
return /* @__PURE__ */ jsx125(Error2, { sx: { color: "orange" } });
|
|
15531
|
-
}
|
|
15532
|
-
default: {
|
|
15533
|
-
return /* @__PURE__ */ jsx125(Fragment2, {});
|
|
15534
|
-
}
|
|
15535
|
-
}
|
|
15536
|
-
};
|
|
15537
15503
|
var SPAN_STATUS_LABELS = {
|
|
15538
15504
|
0: "Unset",
|
|
15539
15505
|
1: "OK",
|
|
@@ -15561,9 +15527,14 @@ var buildTooltipContent = (span) => {
|
|
|
15561
15527
|
] });
|
|
15562
15528
|
};
|
|
15563
15529
|
var StatusIconWithTooltip = ({ span }) => {
|
|
15564
|
-
const
|
|
15565
|
-
|
|
15566
|
-
|
|
15530
|
+
const { warningIcon } = useDevSettings();
|
|
15531
|
+
const { error, warning: warning2 } = getSpanIssues(span);
|
|
15532
|
+
if (!error && !warning2) return /* @__PURE__ */ jsx125(Fragment2, {});
|
|
15533
|
+
const iamLevel = getIamSummary(span).level;
|
|
15534
|
+
return /* @__PURE__ */ jsx125(Tooltip3, { title: buildTooltipContent(span), children: /* @__PURE__ */ jsxs120(Box3, { sx: { alignItems: "center", cursor: "default", display: "flex" }, children: [
|
|
15535
|
+
error && /* @__PURE__ */ jsx125(Box3, { "aria-label": "Error", role: "img", sx: { display: "flex" }, children: iamLevel === "error" ? /* @__PURE__ */ jsx125(GppBad, { sx: { color: "error.main" } }) : /* @__PURE__ */ jsx125(Cancel2, { sx: { color: "error.main" } }) }),
|
|
15536
|
+
warning2 && /* @__PURE__ */ jsx125(Box3, { "aria-label": "Warning", role: "img", sx: { display: "flex" }, children: iamLevel === "warning" && warningIcon === "iam shield" ? /* @__PURE__ */ jsx125(GppBad, { sx: { color: "warning.main" } }) : /* @__PURE__ */ jsx125(Error2, { sx: { color: "warning.main" } }) })
|
|
15537
|
+
] }) });
|
|
15567
15538
|
};
|
|
15568
15539
|
|
|
15569
15540
|
// src/components/spans-list/span-count-badge.tsx
|
|
@@ -16661,6 +16632,94 @@ var StatusMessage = ({
|
|
|
16661
16632
|
return /* @__PURE__ */ jsx130(Fragment6, {});
|
|
16662
16633
|
};
|
|
16663
16634
|
|
|
16635
|
+
// src/utils/span-parents.ts
|
|
16636
|
+
var resolveParents = (spans) => {
|
|
16637
|
+
const byId = new Map(spans.map((span) => [span.span_id, span]));
|
|
16638
|
+
const parentOf = /* @__PURE__ */ new Map();
|
|
16639
|
+
for (const span of spans) {
|
|
16640
|
+
const parent = span.parent_span_id === null ? void 0 : byId.get(span.parent_span_id);
|
|
16641
|
+
if (parent && parent.span_id !== span.span_id && parent.trace_id === span.trace_id) {
|
|
16642
|
+
parentOf.set(span.span_id, parent.span_id);
|
|
16643
|
+
}
|
|
16644
|
+
}
|
|
16645
|
+
const causes = /* @__PURE__ */ new Map();
|
|
16646
|
+
const addCause = (spanId, causeId) => {
|
|
16647
|
+
const list = causes.get(spanId);
|
|
16648
|
+
if (list) list.push(causeId);
|
|
16649
|
+
else causes.set(spanId, [causeId]);
|
|
16650
|
+
};
|
|
16651
|
+
for (const span of spans) {
|
|
16652
|
+
for (const causeId of span.outgoing_link_span_ids ?? []) addCause(span.span_id, causeId);
|
|
16653
|
+
for (const effectId of span.incoming_link_span_ids ?? []) addCause(effectId, span.span_id);
|
|
16654
|
+
}
|
|
16655
|
+
const isAncestorOrSelf = (candidateId, spanId) => {
|
|
16656
|
+
let current = spanId;
|
|
16657
|
+
for (let hops = 0; current !== void 0 && hops <= spans.length; hops++) {
|
|
16658
|
+
if (current === candidateId) return true;
|
|
16659
|
+
current = parentOf.get(current);
|
|
16660
|
+
}
|
|
16661
|
+
return false;
|
|
16662
|
+
};
|
|
16663
|
+
for (const span of spans) {
|
|
16664
|
+
if (parentOf.has(span.span_id)) continue;
|
|
16665
|
+
const cause = causes.get(span.span_id)?.find((causeId) => byId.has(causeId) && !isAncestorOrSelf(span.span_id, causeId));
|
|
16666
|
+
if (cause !== void 0) parentOf.set(span.span_id, cause);
|
|
16667
|
+
}
|
|
16668
|
+
return parentOf;
|
|
16669
|
+
};
|
|
16670
|
+
|
|
16671
|
+
// src/components/trace-panel/timeline-tree.ts
|
|
16672
|
+
var compareNano = (left, right) => {
|
|
16673
|
+
const difference = BigInt(left) - BigInt(right);
|
|
16674
|
+
if (difference === 0n) return 0;
|
|
16675
|
+
return difference < 0n ? -1 : 1;
|
|
16676
|
+
};
|
|
16677
|
+
var buildTraceTree = (spans) => {
|
|
16678
|
+
const nodes2 = new Map(spans.map((span) => [span.span_id, { children: [], span }]));
|
|
16679
|
+
const parentOf = resolveParents(spans);
|
|
16680
|
+
const roots = [];
|
|
16681
|
+
for (const [spanId, node] of nodes2) {
|
|
16682
|
+
const parent = parentOf.get(spanId);
|
|
16683
|
+
if (parent === void 0) roots.push(node);
|
|
16684
|
+
else nodes2.get(parent)?.children.push(node);
|
|
16685
|
+
}
|
|
16686
|
+
const byStart = (left, right) => compareNano(left.span.start_time_unix_nano, right.span.start_time_unix_nano);
|
|
16687
|
+
roots.sort(byStart);
|
|
16688
|
+
for (const node of nodes2.values()) node.children.sort(byStart);
|
|
16689
|
+
return { parentOf, roots };
|
|
16690
|
+
};
|
|
16691
|
+
var findRootSpan = (spans, parentOf, spanId) => {
|
|
16692
|
+
let current = spanId;
|
|
16693
|
+
for (let hops = 0; hops <= spans.length; hops++) {
|
|
16694
|
+
const parent = parentOf.get(current);
|
|
16695
|
+
if (parent === void 0) break;
|
|
16696
|
+
current = parent;
|
|
16697
|
+
}
|
|
16698
|
+
return spans.find((span) => span.span_id === current);
|
|
16699
|
+
};
|
|
16700
|
+
var findFirstSpan = (nodes2, predicate) => {
|
|
16701
|
+
for (const node of nodes2) {
|
|
16702
|
+
if (predicate(node.span.span_id)) return node.span;
|
|
16703
|
+
const found = findFirstSpan(node.children, predicate);
|
|
16704
|
+
if (found) return found;
|
|
16705
|
+
}
|
|
16706
|
+
return void 0;
|
|
16707
|
+
};
|
|
16708
|
+
var getTraceBounds = (spans) => {
|
|
16709
|
+
let start;
|
|
16710
|
+
let end;
|
|
16711
|
+
for (const span of spans) {
|
|
16712
|
+
const spanStart = BigInt(span.start_time_unix_nano);
|
|
16713
|
+
const spanEnd = span.end_time_unix_nano ? BigInt(span.end_time_unix_nano) : spanStart;
|
|
16714
|
+
if (start === void 0 || spanStart < start) start = spanStart;
|
|
16715
|
+
if (end === void 0 || spanEnd > end) end = spanEnd;
|
|
16716
|
+
}
|
|
16717
|
+
if (start === void 0 || end === void 0) {
|
|
16718
|
+
return { durationMs: 0, startNano: 0n };
|
|
16719
|
+
}
|
|
16720
|
+
return { durationMs: Number(end - start) / 1e6, startNano: start };
|
|
16721
|
+
};
|
|
16722
|
+
|
|
16664
16723
|
// src/components/trace-panel/trace-sidebar.tsx
|
|
16665
16724
|
import { Close as Close4 } from "@mui/icons-material";
|
|
16666
16725
|
import { Box as Box20, IconButton as IconButton8, ToggleButton as ToggleButton3, ToggleButtonGroup as ToggleButtonGroup3, Typography as Typography15 } from "@mui/material";
|
|
@@ -16780,38 +16839,6 @@ var getEventGroupsByType = (events) => {
|
|
|
16780
16839
|
return groups;
|
|
16781
16840
|
};
|
|
16782
16841
|
|
|
16783
|
-
// src/utils/span-issues.ts
|
|
16784
|
-
var firstText = (...values) => values.find((value) => !!value) ?? void 0;
|
|
16785
|
-
var OTEL_STATUS_ERROR = 2;
|
|
16786
|
-
var getIamDenials = (span) => span.events.flatMap((event) => {
|
|
16787
|
-
if (!event.event_type?.toLowerCase().includes("iam") || typeof event.attributes?.payload !== "string") {
|
|
16788
|
-
return [];
|
|
16789
|
-
}
|
|
16790
|
-
const permission = parseIAMEvent(event.attributes.payload)?.permission;
|
|
16791
|
-
if (permission === "explicitly_denied") return ["explicit"];
|
|
16792
|
-
if (permission === "implicitly_denied") return ["implicit"];
|
|
16793
|
-
return [];
|
|
16794
|
-
});
|
|
16795
|
-
var getSpanIssues = (span) => {
|
|
16796
|
-
const status = span.operation_status;
|
|
16797
|
-
const iamDenied = status === "iam_explicit_deny" || status === "iam_implicit_deny";
|
|
16798
|
-
const iamWarned = status === "iam_explicit_warn" || status === "iam_implicit_warn";
|
|
16799
|
-
const errorMessages = (span.errors ?? []).filter((item) => item.level === "error");
|
|
16800
|
-
const warningMessages = (span.errors ?? []).filter((item) => item.level === "warning");
|
|
16801
|
-
const denials = getIamDenials(span);
|
|
16802
|
-
const unenforcedDenial = !iamDenied && (denials.length > 0 || span.attributes?.["localstack.has_iam_deny_event"] === true);
|
|
16803
|
-
const error = status === "error" || iamDenied || span.status_code === OTEL_STATUS_ERROR || errorMessages.length > 0;
|
|
16804
|
-
const warning2 = iamWarned || warningMessages.length > 0 || unenforcedDenial;
|
|
16805
|
-
const denialCount = unenforcedDenial ? Math.max(1, denials.length) : 0;
|
|
16806
|
-
return {
|
|
16807
|
-
error,
|
|
16808
|
-
errorType: error ? firstText(span.status_message, errorMessages[0]?.message) ?? (iamDenied ? "AccessDenied" : "Error") : void 0,
|
|
16809
|
-
warning: warning2,
|
|
16810
|
-
warningCount: warning2 ? Math.max(1, warningMessages.length + denialCount) : 0,
|
|
16811
|
-
warningType: warning2 ? firstText(warningMessages[0]?.message) ?? (unenforcedDenial ? `IAM ${denials[0] ?? "implicit"} deny` : iamWarned ? "IAM permission warning" : "Warning") : void 0
|
|
16812
|
-
};
|
|
16813
|
-
};
|
|
16814
|
-
|
|
16815
16842
|
// src/utils/time.ts
|
|
16816
16843
|
function unixNanoToDate(unixNanoString) {
|
|
16817
16844
|
const milliseconds = unixNanoToMilliseconds(unixNanoString);
|
|
@@ -16860,7 +16887,7 @@ import { useEffect as useEffect12, useMemo as useMemo7, useRef as useRef8, useSt
|
|
|
16860
16887
|
import { Cancel as Cancel4, CheckCircle, Error as Error3, Info, RemoveCircle } from "@mui/icons-material";
|
|
16861
16888
|
import { Box as Box9 } from "@mui/material";
|
|
16862
16889
|
import { jsx as jsx132 } from "react/jsx-runtime";
|
|
16863
|
-
var
|
|
16890
|
+
var StatusIcon = ({ errorLevel }) => {
|
|
16864
16891
|
switch (errorLevel) {
|
|
16865
16892
|
case EventLevel.LevelError: {
|
|
16866
16893
|
return /* @__PURE__ */ jsx132(Cancel4, { sx: { color: "red" } });
|
|
@@ -18961,7 +18988,7 @@ var EventDetail = ({
|
|
|
18961
18988
|
const eventLevel = getEventLevelFromGroup(type);
|
|
18962
18989
|
return /* @__PURE__ */ jsxs129(Box14, { children: [
|
|
18963
18990
|
/* @__PURE__ */ jsxs129(Box14, { sx: { alignItems: "center", display: "flex", mb: 0.5 }, children: [
|
|
18964
|
-
/* @__PURE__ */ jsx137(
|
|
18991
|
+
/* @__PURE__ */ jsx137(StatusIcon, { errorLevel: eventLevel }),
|
|
18965
18992
|
/* @__PURE__ */ jsx137(Typography10, { color: "text.secondary", sx: { fontWeight: 600, ml: 0.5 }, variant: "caption", children: displayText })
|
|
18966
18993
|
] }),
|
|
18967
18994
|
/* @__PURE__ */ jsx137(Box14, { children: events.map((event) => /* @__PURE__ */ jsx137(Box14, { sx: { maxWidth: "100%", mb: 0.5 }, children: /* @__PURE__ */ jsx137(EventMessage, { event }) }, `${event.span_id}-${event.event_id}`)) })
|
|
@@ -31598,20 +31625,21 @@ import { Background, MarkerType, MiniMap, Position as Position2, ReactFlow, useE
|
|
|
31598
31625
|
import { useCallback as useCallback7, useEffect as useEffect16, useRef as useRef13, useState as useState15 } from "react";
|
|
31599
31626
|
|
|
31600
31627
|
// src/components/trace-graph/service-node.tsx
|
|
31601
|
-
import { Cancel as Cancel6, GppBad as GppBad2 } from "@mui/icons-material";
|
|
31628
|
+
import { Cancel as Cancel6, Error as ErrorIcon4, GppBad as GppBad2 } from "@mui/icons-material";
|
|
31602
31629
|
import { Box as Box17, Divider as Divider4, Stack as Stack5, Tooltip as Tooltip6, Typography as Typography13, useTheme as useTheme4 } from "@mui/material";
|
|
31603
31630
|
import { Handle, Position } from "@xyflow/react";
|
|
31604
31631
|
import "@xyflow/react/dist/style.css";
|
|
31605
31632
|
import "react";
|
|
31606
|
-
import { memo as memo11,
|
|
31633
|
+
import { memo as memo11, useRef as useRef12, useState as useState14 } from "react";
|
|
31607
31634
|
import { Fragment as Fragment11, jsx as jsx143, jsxs as jsxs132 } from "react/jsx-runtime";
|
|
31608
31635
|
var handleStyle = {
|
|
31609
31636
|
backgroundColor: "white",
|
|
31610
31637
|
borderColor: "lightgray",
|
|
31611
31638
|
opacity: 0
|
|
31612
31639
|
};
|
|
31613
|
-
var NodeContent = ({ event, expanded,
|
|
31640
|
+
var NodeContent = ({ event, expanded, iamLevel, issues }) => {
|
|
31614
31641
|
const theme = useTheme4();
|
|
31642
|
+
const { warningIcon } = useDevSettings();
|
|
31615
31643
|
return /* @__PURE__ */ jsxs132(Fragment11, { children: [
|
|
31616
31644
|
/* @__PURE__ */ jsx143(Handle, { position: Position.Left, style: handleStyle, type: "target" }),
|
|
31617
31645
|
/* @__PURE__ */ jsx143(Handle, { position: Position.Right, style: handleStyle, type: "source" }),
|
|
@@ -31666,8 +31694,8 @@ var NodeContent = ({ event, expanded, hasPermissionEvents, isError, isWarning })
|
|
|
31666
31694
|
width: "38px"
|
|
31667
31695
|
},
|
|
31668
31696
|
children: [
|
|
31669
|
-
|
|
31670
|
-
|
|
31697
|
+
issues.error && /* @__PURE__ */ jsx143(Tooltip6, { arrow: true, title: issues.errorType, children: /* @__PURE__ */ jsx143(Box17, { "aria-label": "Error", role: "img", sx: { display: "flex" }, children: iamLevel === "error" ? /* @__PURE__ */ jsx143(GppBad2, { sx: { color: theme.palette.error.main, fontSize: "16px" } }) : /* @__PURE__ */ jsx143(Cancel6, { sx: { color: theme.palette.error.main, fontSize: "16px" } }) }) }),
|
|
31698
|
+
issues.warning && /* @__PURE__ */ jsx143(Tooltip6, { arrow: true, title: issues.warningType, children: /* @__PURE__ */ jsx143(Box17, { "aria-label": "Warning", role: "img", sx: { display: "flex" }, children: iamLevel === "warning" && warningIcon === "iam shield" ? /* @__PURE__ */ jsx143(GppBad2, { sx: { color: theme.palette.warning.main, fontSize: "16px" } }) : /* @__PURE__ */ jsx143(ErrorIcon4, { sx: { color: theme.palette.warning.main, fontSize: "16px" } }) }) })
|
|
31671
31699
|
]
|
|
31672
31700
|
}
|
|
31673
31701
|
),
|
|
@@ -31690,17 +31718,9 @@ var ServiceNode = memo11(({ data, selected }) => {
|
|
|
31690
31718
|
const theme = useTheme4();
|
|
31691
31719
|
const [isHovered, setIsHovered] = useState14(false);
|
|
31692
31720
|
const nodeRef = useRef12(null);
|
|
31693
|
-
const
|
|
31694
|
-
const
|
|
31695
|
-
|
|
31696
|
-
(event) => event.event_type === "iam.policy_evaluation" && event.name === "iam.policy.denied"
|
|
31697
|
-
),
|
|
31698
|
-
[data.event.events]
|
|
31699
|
-
);
|
|
31700
|
-
const isError = operation_status ? operation_status === "error" || operation_status === "iam_explicit_deny" || operation_status === "iam_implicit_deny" : data.event.status_code === 2;
|
|
31701
|
-
const isWarning = operation_status ? operation_status === "iam_explicit_warn" || operation_status === "iam_implicit_warn" : !isError && data.event.status_code === 1 && hasPermissionEventsLegacy;
|
|
31702
|
-
const hasPermissionEvents = operation_status ? operation_status.startsWith("iam_") : hasPermissionEventsLegacy;
|
|
31703
|
-
const outlineColor = isError ? theme.palette.error.main : isWarning ? theme.palette.warning.main : void 0;
|
|
31721
|
+
const issues = getSpanIssues(data.event);
|
|
31722
|
+
const iamLevel = getIamSummary(data.event).level;
|
|
31723
|
+
const outlineColor = issues.error ? theme.palette.error.main : issues.warning ? theme.palette.warning.main : void 0;
|
|
31704
31724
|
const sharedBoxSx = {
|
|
31705
31725
|
backgroundColor: theme.palette.background.paper,
|
|
31706
31726
|
borderLeft: `3px solid ${outlineColor ?? "transparent"}`,
|
|
@@ -31709,7 +31729,7 @@ var ServiceNode = memo11(({ data, selected }) => {
|
|
|
31709
31729
|
minWidth: 140,
|
|
31710
31730
|
outline: selected ? `2px solid ${outlineColor ?? theme.palette.primary.main}` : `1px solid ${theme.palette.divider}`
|
|
31711
31731
|
};
|
|
31712
|
-
const contentProps = { event: data.event,
|
|
31732
|
+
const contentProps = { event: data.event, iamLevel, issues };
|
|
31713
31733
|
const handleMouseEnter = () => {
|
|
31714
31734
|
setIsHovered(true);
|
|
31715
31735
|
const xyNode = nodeRef.current?.closest(".react-flow__node");
|
|
@@ -32217,88 +32237,8 @@ function useLocalStorage(key, initialValue) {
|
|
|
32217
32237
|
return [storedValue, setValue];
|
|
32218
32238
|
}
|
|
32219
32239
|
|
|
32220
|
-
// src/utils/span-parents.ts
|
|
32221
|
-
var resolveParents = (spans) => {
|
|
32222
|
-
const byId = new Map(spans.map((span) => [span.span_id, span]));
|
|
32223
|
-
const parentOf = /* @__PURE__ */ new Map();
|
|
32224
|
-
for (const span of spans) {
|
|
32225
|
-
const parent = span.parent_span_id === null ? void 0 : byId.get(span.parent_span_id);
|
|
32226
|
-
if (parent && parent.span_id !== span.span_id && parent.trace_id === span.trace_id) {
|
|
32227
|
-
parentOf.set(span.span_id, parent.span_id);
|
|
32228
|
-
}
|
|
32229
|
-
}
|
|
32230
|
-
const causes = /* @__PURE__ */ new Map();
|
|
32231
|
-
const addCause = (spanId, causeId) => {
|
|
32232
|
-
const list = causes.get(spanId);
|
|
32233
|
-
if (list) list.push(causeId);
|
|
32234
|
-
else causes.set(spanId, [causeId]);
|
|
32235
|
-
};
|
|
32236
|
-
for (const span of spans) {
|
|
32237
|
-
for (const causeId of span.outgoing_link_span_ids ?? []) addCause(span.span_id, causeId);
|
|
32238
|
-
for (const effectId of span.incoming_link_span_ids ?? []) addCause(effectId, span.span_id);
|
|
32239
|
-
}
|
|
32240
|
-
const isAncestorOrSelf = (candidateId, spanId) => {
|
|
32241
|
-
let current = spanId;
|
|
32242
|
-
for (let hops = 0; current !== void 0 && hops <= spans.length; hops++) {
|
|
32243
|
-
if (current === candidateId) return true;
|
|
32244
|
-
current = parentOf.get(current);
|
|
32245
|
-
}
|
|
32246
|
-
return false;
|
|
32247
|
-
};
|
|
32248
|
-
for (const span of spans) {
|
|
32249
|
-
if (parentOf.has(span.span_id)) continue;
|
|
32250
|
-
const cause = causes.get(span.span_id)?.find((causeId) => byId.has(causeId) && !isAncestorOrSelf(span.span_id, causeId));
|
|
32251
|
-
if (cause !== void 0) parentOf.set(span.span_id, cause);
|
|
32252
|
-
}
|
|
32253
|
-
return parentOf;
|
|
32254
|
-
};
|
|
32255
|
-
|
|
32256
|
-
// src/components/trace-panel/timeline-tree.ts
|
|
32257
|
-
var compareNano = (left, right) => {
|
|
32258
|
-
const difference = BigInt(left) - BigInt(right);
|
|
32259
|
-
if (difference === 0n) return 0;
|
|
32260
|
-
return difference < 0n ? -1 : 1;
|
|
32261
|
-
};
|
|
32262
|
-
var buildTraceTree = (spans) => {
|
|
32263
|
-
const nodes2 = new Map(spans.map((span) => [span.span_id, { children: [], span }]));
|
|
32264
|
-
const parentOf = resolveParents(spans);
|
|
32265
|
-
const roots = [];
|
|
32266
|
-
for (const [spanId, node] of nodes2) {
|
|
32267
|
-
const parent = parentOf.get(spanId);
|
|
32268
|
-
if (parent === void 0) roots.push(node);
|
|
32269
|
-
else nodes2.get(parent)?.children.push(node);
|
|
32270
|
-
}
|
|
32271
|
-
const byStart = (left, right) => compareNano(left.span.start_time_unix_nano, right.span.start_time_unix_nano);
|
|
32272
|
-
roots.sort(byStart);
|
|
32273
|
-
for (const node of nodes2.values()) node.children.sort(byStart);
|
|
32274
|
-
return { parentOf, roots };
|
|
32275
|
-
};
|
|
32276
|
-
var findRootSpan = (spans, parentOf, spanId) => {
|
|
32277
|
-
let current = spanId;
|
|
32278
|
-
for (let hops = 0; hops <= spans.length; hops++) {
|
|
32279
|
-
const parent = parentOf.get(current);
|
|
32280
|
-
if (parent === void 0) break;
|
|
32281
|
-
current = parent;
|
|
32282
|
-
}
|
|
32283
|
-
return spans.find((span) => span.span_id === current);
|
|
32284
|
-
};
|
|
32285
|
-
var getTraceBounds = (spans) => {
|
|
32286
|
-
let start;
|
|
32287
|
-
let end;
|
|
32288
|
-
for (const span of spans) {
|
|
32289
|
-
const spanStart = BigInt(span.start_time_unix_nano);
|
|
32290
|
-
const spanEnd = span.end_time_unix_nano ? BigInt(span.end_time_unix_nano) : spanStart;
|
|
32291
|
-
if (start === void 0 || spanStart < start) start = spanStart;
|
|
32292
|
-
if (end === void 0 || spanEnd > end) end = spanEnd;
|
|
32293
|
-
}
|
|
32294
|
-
if (start === void 0 || end === void 0) {
|
|
32295
|
-
return { durationMs: 0, startNano: 0n };
|
|
32296
|
-
}
|
|
32297
|
-
return { durationMs: Number(end - start) / 1e6, startNano: start };
|
|
32298
|
-
};
|
|
32299
|
-
|
|
32300
32240
|
// src/components/trace-panel/waterfall.tsx
|
|
32301
|
-
import { AccountTreeOutlined, Cancel as Cancel7, Error as
|
|
32241
|
+
import { AccountTreeOutlined, Cancel as Cancel7, Error as ErrorIcon5, FormatListBulleted, KeyboardArrowDown as KeyboardArrowDown2, KeyboardArrowRight as KeyboardArrowRight2 } from "@mui/icons-material";
|
|
32302
32242
|
import { Box as Box19, ButtonBase, ToggleButton as ToggleButton2, ToggleButtonGroup as ToggleButtonGroup2, Typography as Typography14 } from "@mui/material";
|
|
32303
32243
|
import { alpha as alpha5 } from "@mui/material/styles";
|
|
32304
32244
|
import * as React124 from "react";
|
|
@@ -32382,7 +32322,7 @@ var flatten = (nodes2, collapsed, depth = 0, branches = [], parent) => nodes2.fl
|
|
|
32382
32322
|
var flattenAll = (nodes2) => flatten(nodes2, /* @__PURE__ */ new Set()).map((row) => ({ ...row, branches: [], depth: 0, last: true })).toSorted((left, right) => compareNano(left.node.span.start_time_unix_nano, right.node.span.start_time_unix_nano));
|
|
32383
32323
|
var StatusIcons = ({ error, warning: warning2 }) => /* @__PURE__ */ jsxs136(Fragment13, { children: [
|
|
32384
32324
|
error && /* @__PURE__ */ jsx147(Cancel7, { sx: { color: "error.main", fontSize: 14 } }),
|
|
32385
|
-
warning2 && /* @__PURE__ */ jsx147(
|
|
32325
|
+
warning2 && /* @__PURE__ */ jsx147(ErrorIcon5, { sx: { color: "warning.main", fontSize: 14 } })
|
|
32386
32326
|
] });
|
|
32387
32327
|
var Line = ({ height, left, top = 0, width = 1 }) => /* @__PURE__ */ jsx147(
|
|
32388
32328
|
Box19,
|
|
@@ -33596,18 +33536,23 @@ var SpansListPage = () => {
|
|
|
33596
33536
|
const [bannerDismissed, setBannerDismissed] = useState22(false);
|
|
33597
33537
|
const [order2, setOrder] = useLocalStorage("spans-order", "oldest_first");
|
|
33598
33538
|
const [selectedSpanId, setSelectedSpanId] = useState22();
|
|
33539
|
+
const getTreeSpans = useCallback12((rootSpanId2) => Object.entries(compute.rows).filter(([, row]) => row.rootSpanId === rootSpanId2).map(([spanId]) => getSpan(spanId)).filter((span) => span !== void 0), [compute.rows, getSpan]);
|
|
33540
|
+
const latestRef = useRef19({ compute, getTreeSpans });
|
|
33541
|
+
useEffect22(() => {
|
|
33542
|
+
latestRef.current = { compute, getTreeSpans };
|
|
33543
|
+
}, [compute, getTreeSpans]);
|
|
33599
33544
|
const navigateToSpan = useCallback12((span) => {
|
|
33600
|
-
|
|
33545
|
+
const { compute: { queryActive, rows }, getTreeSpans: getSpans } = latestRef.current;
|
|
33546
|
+
const rootSpanId2 = rows[span.span_id]?.rootSpanId;
|
|
33547
|
+
const firstMatch = queryActive && rootSpanId2 !== void 0 ? findFirstSpan(buildTraceTree(getSpans(rootSpanId2)).roots, (spanId) => rows[spanId]?.matches ?? false) : void 0;
|
|
33548
|
+
setSelectedSpanId(firstMatch?.span_id ?? span.span_id);
|
|
33601
33549
|
}, []);
|
|
33602
33550
|
const closeSidebar = useCallback12(() => {
|
|
33603
33551
|
setSelectedSpanId(void 0);
|
|
33604
33552
|
}, []);
|
|
33605
33553
|
const rootSpanId = selectedSpanId === void 0 ? void 0 : compute.rows[selectedSpanId]?.rootSpanId;
|
|
33606
|
-
const treeSpans =
|
|
33607
|
-
|
|
33608
|
-
return Object.entries(compute.rows).filter(([, row]) => row.rootSpanId === rootSpanId).map(([spanId]) => getSpan(spanId)).filter((span) => span !== void 0);
|
|
33609
|
-
}, [compute.rows, getSpan, rootSpanId]);
|
|
33610
|
-
const spanMatches = useMemo14(
|
|
33554
|
+
const treeSpans = useMemo13(() => rootSpanId === void 0 ? [] : getTreeSpans(rootSpanId), [getTreeSpans, rootSpanId]);
|
|
33555
|
+
const spanMatches = useMemo13(
|
|
33611
33556
|
() => compute.queryActive ? (spanId) => compute.rows[spanId]?.matches ?? false : void 0,
|
|
33612
33557
|
[compute]
|
|
33613
33558
|
);
|