@kopai/ui 0.9.0 → 0.11.0
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 +187 -8
- package/dist/index.d.cts +20 -13
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +20 -12
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +187 -8
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -14
- package/src/components/observability/DynamicDashboard/DynamicDashboard.test.tsx +175 -1
- package/src/components/observability/MetricStat/index.tsx +12 -4
- package/src/components/observability/renderers/OtelMetricStat.tsx +40 -0
- package/src/components/observability/renderers/OtelTraceDetail.tsx +88 -2
- package/src/hooks/use-kopai-data.test.ts +31 -0
- package/src/hooks/use-kopai-data.ts +12 -5
- package/src/hooks/use-live-logs.test.ts +1 -0
- package/src/lib/__snapshots__/generate-prompt-instructions.test.ts.snap +1 -1
- package/src/lib/renderer.test.tsx +2 -0
- package/src/pages/observability.test.tsx +3 -0
- package/src/pages/observability.tsx +83 -1
- package/src/providers/kopai-provider.tsx +1 -0
package/dist/index.mjs
CHANGED
|
@@ -34,16 +34,20 @@ function fetchForDataSource(client, dataSource, signal) {
|
|
|
34
34
|
switch (dataSource.method) {
|
|
35
35
|
case "searchTracesPage": return client.searchTracesPage(dataSource.params, { signal });
|
|
36
36
|
case "searchLogsPage": return client.searchLogsPage(dataSource.params, { signal });
|
|
37
|
-
case "searchMetricsPage":
|
|
37
|
+
case "searchMetricsPage": {
|
|
38
|
+
const params = dataSource.params;
|
|
39
|
+
if (params.aggregate) return client.searchAggregatedMetrics({
|
|
40
|
+
...params,
|
|
41
|
+
aggregate: params.aggregate
|
|
42
|
+
}, { signal });
|
|
43
|
+
return client.searchMetricsPage(params, { signal });
|
|
44
|
+
}
|
|
38
45
|
case "getTrace": return client.getTrace(dataSource.params.traceId, { signal });
|
|
39
46
|
case "discoverMetrics": return client.discoverMetrics({ signal });
|
|
40
47
|
case "getServices": return client.getServices({ signal });
|
|
41
48
|
case "getOperations": return client.getOperations(dataSource.params.serviceName, { signal });
|
|
42
49
|
case "searchTraceSummariesPage": return client.searchTraceSummariesPage(dataSource.params, { signal });
|
|
43
|
-
default: {
|
|
44
|
-
const exhaustiveCheck = dataSource;
|
|
45
|
-
throw new Error(`Unknown method: ${exhaustiveCheck.method}`);
|
|
46
|
-
}
|
|
50
|
+
default: throw new Error(`Unknown method: ${dataSource.method}`);
|
|
47
51
|
}
|
|
48
52
|
}
|
|
49
53
|
function useKopaiData(dataSource) {
|
|
@@ -5700,8 +5704,11 @@ function buildStatData(rows) {
|
|
|
5700
5704
|
metricName
|
|
5701
5705
|
};
|
|
5702
5706
|
}
|
|
5703
|
-
function MetricStat({ rows, isLoading = false, error, label, formatValue = defaultFormatValue$1, showTimestamp = false, trend, trendValue, className = "", showSparkline = false, sparklinePoints = 20, sparklineHeight = 40, thresholds, colorBackground, colorValue = false }) {
|
|
5704
|
-
const
|
|
5707
|
+
function MetricStat({ rows, value: directValue, unit: directUnit, isLoading = false, error, label, formatValue = defaultFormatValue$1, showTimestamp = false, trend, trendValue, className = "", showSparkline = false, sparklinePoints = 20, sparklineHeight = 40, thresholds, colorBackground, colorValue = false }) {
|
|
5708
|
+
const statData = useMemo(() => buildStatData(rows), [rows]);
|
|
5709
|
+
const latestValue = directValue ?? statData.latestValue;
|
|
5710
|
+
const unit = directUnit ?? statData.unit;
|
|
5711
|
+
const { timestamp, dataPoints, metricName } = statData;
|
|
5705
5712
|
const sparklineData = useMemo(() => {
|
|
5706
5713
|
if (!showSparkline || dataPoints.length === 0) return [];
|
|
5707
5714
|
return dataPoints.slice(-sparklinePoints).map((dp) => ({ value: dp.value }));
|
|
@@ -6586,6 +6593,13 @@ function OtelMetricHistogram(props) {
|
|
|
6586
6593
|
}
|
|
6587
6594
|
//#endregion
|
|
6588
6595
|
//#region src/components/observability/renderers/OtelMetricStat.tsx
|
|
6596
|
+
const EMPTY_ROWS = [];
|
|
6597
|
+
const GROUPED_AGGREGATE_ERROR = /* @__PURE__ */ new Error("MetricStat cannot display grouped aggregates. Remove groupBy or use MetricTable.");
|
|
6598
|
+
function isAggregatedRequest(props) {
|
|
6599
|
+
const ds = props.element.dataSource;
|
|
6600
|
+
if (!ds || ds.method !== "searchMetricsPage" || !ds.params) return false;
|
|
6601
|
+
return !!ds.params.aggregate;
|
|
6602
|
+
}
|
|
6589
6603
|
function OtelMetricStat(props) {
|
|
6590
6604
|
if (!props.hasData) return /* @__PURE__ */ jsx("div", {
|
|
6591
6605
|
style: {
|
|
@@ -6594,6 +6608,24 @@ function OtelMetricStat(props) {
|
|
|
6594
6608
|
},
|
|
6595
6609
|
children: "No data source"
|
|
6596
6610
|
});
|
|
6611
|
+
if (isAggregatedRequest(props)) {
|
|
6612
|
+
const rows = props.data?.data ?? [];
|
|
6613
|
+
if (rows.length > 1) return /* @__PURE__ */ jsx(MetricStat, {
|
|
6614
|
+
rows: EMPTY_ROWS,
|
|
6615
|
+
error: GROUPED_AGGREGATE_ERROR,
|
|
6616
|
+
label: props.element.props.label ?? void 0,
|
|
6617
|
+
formatValue: formatOtelValue
|
|
6618
|
+
});
|
|
6619
|
+
return /* @__PURE__ */ jsx(MetricStat, {
|
|
6620
|
+
rows: EMPTY_ROWS,
|
|
6621
|
+
value: rows[0]?.value,
|
|
6622
|
+
isLoading: props.loading,
|
|
6623
|
+
error: props.error ?? void 0,
|
|
6624
|
+
label: props.element.props.label ?? void 0,
|
|
6625
|
+
showSparkline: false,
|
|
6626
|
+
formatValue: formatOtelValue
|
|
6627
|
+
});
|
|
6628
|
+
}
|
|
6597
6629
|
const response = props.data;
|
|
6598
6630
|
return /* @__PURE__ */ jsx(MetricStat, {
|
|
6599
6631
|
rows: response?.data ?? [],
|
|
@@ -6645,6 +6677,54 @@ function OtelMetricTimeSeries(props) {
|
|
|
6645
6677
|
}
|
|
6646
6678
|
//#endregion
|
|
6647
6679
|
//#region src/components/observability/renderers/OtelTraceDetail.tsx
|
|
6680
|
+
function isTraceSummariesSource(props) {
|
|
6681
|
+
return props.element.dataSource?.method === "searchTraceSummariesPage";
|
|
6682
|
+
}
|
|
6683
|
+
function TraceSummariesView({ data, loading, error }) {
|
|
6684
|
+
const [selectedTraceId, setSelectedTraceId] = useState(null);
|
|
6685
|
+
const client = useKopaiSDK();
|
|
6686
|
+
const response = data;
|
|
6687
|
+
const traces = useMemo(() => {
|
|
6688
|
+
const rows = response?.data;
|
|
6689
|
+
if (!Array.isArray(rows)) return [];
|
|
6690
|
+
return rows.map((row) => ({
|
|
6691
|
+
traceId: row.traceId,
|
|
6692
|
+
rootSpanName: row.rootSpanName,
|
|
6693
|
+
serviceName: row.rootServiceName,
|
|
6694
|
+
durationMs: parseInt(row.durationNs, 10) / 1e6,
|
|
6695
|
+
statusCode: row.errorCount > 0 ? "ERROR" : "OK",
|
|
6696
|
+
timestampMs: parseInt(row.startTimeNs, 10) / 1e6,
|
|
6697
|
+
spanCount: row.spanCount,
|
|
6698
|
+
services: row.services,
|
|
6699
|
+
errorCount: row.errorCount
|
|
6700
|
+
}));
|
|
6701
|
+
}, [response]);
|
|
6702
|
+
const { data: traceRows, isFetching: traceLoading, error: traceError } = useQuery({
|
|
6703
|
+
queryKey: [
|
|
6704
|
+
"kopai",
|
|
6705
|
+
"getTrace",
|
|
6706
|
+
selectedTraceId
|
|
6707
|
+
],
|
|
6708
|
+
queryFn: ({ signal }) => client.getTrace(selectedTraceId, { signal }),
|
|
6709
|
+
enabled: !!selectedTraceId
|
|
6710
|
+
});
|
|
6711
|
+
const handleBack = useCallback(() => setSelectedTraceId(null), []);
|
|
6712
|
+
if (selectedTraceId) return /* @__PURE__ */ jsx(TraceDetail, {
|
|
6713
|
+
traceId: selectedTraceId,
|
|
6714
|
+
rows: traceRows ?? [],
|
|
6715
|
+
isLoading: traceLoading,
|
|
6716
|
+
error: traceError ?? void 0,
|
|
6717
|
+
onBack: handleBack
|
|
6718
|
+
});
|
|
6719
|
+
return /* @__PURE__ */ jsx(TraceSearch, {
|
|
6720
|
+
services: [],
|
|
6721
|
+
service: "",
|
|
6722
|
+
traces,
|
|
6723
|
+
isLoading: loading,
|
|
6724
|
+
error: error ?? void 0,
|
|
6725
|
+
onSelectTrace: setSelectedTraceId
|
|
6726
|
+
});
|
|
6727
|
+
}
|
|
6648
6728
|
function OtelTraceDetail(props) {
|
|
6649
6729
|
if (!props.hasData) return /* @__PURE__ */ jsx("div", {
|
|
6650
6730
|
style: {
|
|
@@ -6653,7 +6733,13 @@ function OtelTraceDetail(props) {
|
|
|
6653
6733
|
},
|
|
6654
6734
|
children: "No data source"
|
|
6655
6735
|
});
|
|
6656
|
-
|
|
6736
|
+
if (isTraceSummariesSource(props)) return /* @__PURE__ */ jsx(TraceSummariesView, {
|
|
6737
|
+
data: props.data,
|
|
6738
|
+
loading: props.loading,
|
|
6739
|
+
error: props.error
|
|
6740
|
+
});
|
|
6741
|
+
const response = props.data;
|
|
6742
|
+
const rows = Array.isArray(response?.data) ? response.data : [];
|
|
6657
6743
|
const traceId = rows[0]?.TraceId ?? "";
|
|
6658
6744
|
return /* @__PURE__ */ jsx(TraceDetail, {
|
|
6659
6745
|
rows,
|
|
@@ -7391,6 +7477,9 @@ const METRICS_TREE = {
|
|
|
7391
7477
|
type: "Stack",
|
|
7392
7478
|
children: [
|
|
7393
7479
|
"heading",
|
|
7480
|
+
"ingestion-heading",
|
|
7481
|
+
"ingestion-grid",
|
|
7482
|
+
"discovery-heading",
|
|
7394
7483
|
"description",
|
|
7395
7484
|
"discovery-card"
|
|
7396
7485
|
],
|
|
@@ -7411,6 +7500,96 @@ const METRICS_TREE = {
|
|
|
7411
7500
|
level: "h2"
|
|
7412
7501
|
}
|
|
7413
7502
|
},
|
|
7503
|
+
"ingestion-heading": {
|
|
7504
|
+
key: "ingestion-heading",
|
|
7505
|
+
type: "Heading",
|
|
7506
|
+
children: [],
|
|
7507
|
+
parentKey: "root",
|
|
7508
|
+
props: {
|
|
7509
|
+
text: "OTEL Ingestion",
|
|
7510
|
+
level: "h3"
|
|
7511
|
+
}
|
|
7512
|
+
},
|
|
7513
|
+
"ingestion-grid": {
|
|
7514
|
+
key: "ingestion-grid",
|
|
7515
|
+
type: "Grid",
|
|
7516
|
+
children: ["card-bytes", "card-requests"],
|
|
7517
|
+
parentKey: "root",
|
|
7518
|
+
props: {
|
|
7519
|
+
columns: 2,
|
|
7520
|
+
gap: "md"
|
|
7521
|
+
}
|
|
7522
|
+
},
|
|
7523
|
+
"card-bytes": {
|
|
7524
|
+
key: "card-bytes",
|
|
7525
|
+
type: "Card",
|
|
7526
|
+
children: ["stat-bytes"],
|
|
7527
|
+
parentKey: "ingestion-grid",
|
|
7528
|
+
props: {
|
|
7529
|
+
title: "Total Bytes Ingested",
|
|
7530
|
+
description: null,
|
|
7531
|
+
padding: null
|
|
7532
|
+
}
|
|
7533
|
+
},
|
|
7534
|
+
"stat-bytes": {
|
|
7535
|
+
key: "stat-bytes",
|
|
7536
|
+
type: "MetricStat",
|
|
7537
|
+
children: [],
|
|
7538
|
+
parentKey: "card-bytes",
|
|
7539
|
+
dataSource: {
|
|
7540
|
+
method: "searchMetricsPage",
|
|
7541
|
+
params: {
|
|
7542
|
+
metricType: "Sum",
|
|
7543
|
+
metricName: "kopai.ingestion.bytes",
|
|
7544
|
+
aggregate: "sum"
|
|
7545
|
+
},
|
|
7546
|
+
refetchIntervalMs: 1e4
|
|
7547
|
+
},
|
|
7548
|
+
props: {
|
|
7549
|
+
label: "Bytes",
|
|
7550
|
+
showSparkline: false
|
|
7551
|
+
}
|
|
7552
|
+
},
|
|
7553
|
+
"card-requests": {
|
|
7554
|
+
key: "card-requests",
|
|
7555
|
+
type: "Card",
|
|
7556
|
+
children: ["stat-requests"],
|
|
7557
|
+
parentKey: "ingestion-grid",
|
|
7558
|
+
props: {
|
|
7559
|
+
title: "Total Requests",
|
|
7560
|
+
description: null,
|
|
7561
|
+
padding: null
|
|
7562
|
+
}
|
|
7563
|
+
},
|
|
7564
|
+
"stat-requests": {
|
|
7565
|
+
key: "stat-requests",
|
|
7566
|
+
type: "MetricStat",
|
|
7567
|
+
children: [],
|
|
7568
|
+
parentKey: "card-requests",
|
|
7569
|
+
dataSource: {
|
|
7570
|
+
method: "searchMetricsPage",
|
|
7571
|
+
params: {
|
|
7572
|
+
metricType: "Sum",
|
|
7573
|
+
metricName: "kopai.ingestion.requests",
|
|
7574
|
+
aggregate: "sum"
|
|
7575
|
+
},
|
|
7576
|
+
refetchIntervalMs: 1e4
|
|
7577
|
+
},
|
|
7578
|
+
props: {
|
|
7579
|
+
label: "Requests",
|
|
7580
|
+
showSparkline: false
|
|
7581
|
+
}
|
|
7582
|
+
},
|
|
7583
|
+
"discovery-heading": {
|
|
7584
|
+
key: "discovery-heading",
|
|
7585
|
+
type: "Heading",
|
|
7586
|
+
children: [],
|
|
7587
|
+
parentKey: "root",
|
|
7588
|
+
props: {
|
|
7589
|
+
text: "Discovered Metrics",
|
|
7590
|
+
level: "h3"
|
|
7591
|
+
}
|
|
7592
|
+
},
|
|
7414
7593
|
description: {
|
|
7415
7594
|
key: "description",
|
|
7416
7595
|
type: "Text",
|