@flanksource/clicky-ui 0.3.56 → 0.3.58
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/components/ErrorWrapper.cjs +15 -4
- package/dist/components/ErrorWrapper.cjs.map +1 -1
- package/dist/components/ErrorWrapper.d.ts +7 -0
- package/dist/components/ErrorWrapper.d.ts.map +1 -1
- package/dist/components/ErrorWrapper.js +15 -4
- package/dist/components/ErrorWrapper.js.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptLayerStrip.cjs +6 -3
- package/dist/data/ai/PromptCatalog/PromptLayerStrip.cjs.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptLayerStrip.js +6 -3
- package/dist/data/ai/PromptCatalog/PromptLayerStrip.js.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPage.cjs +2 -1
- package/dist/data/ai/PromptCatalog/PromptPage.cjs.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPage.d.ts.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPage.js +2 -1
- package/dist/data/ai/PromptCatalog/PromptPage.js.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPageHeader.cjs +9 -6
- package/dist/data/ai/PromptCatalog/PromptPageHeader.cjs.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPageHeader.d.ts.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPageHeader.js +9 -6
- package/dist/data/ai/PromptCatalog/PromptPageHeader.js.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.cjs +3 -3
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.cjs.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.d.ts +2 -1
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.d.ts.map +1 -1
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.js +3 -3
- package/dist/data/ai/PromptCatalog/PromptPageSaveBar.js.map +1 -1
- package/dist/data/ai/PromptCatalog/prompt-page-model.cjs +4 -3
- package/dist/data/ai/PromptCatalog/prompt-page-model.cjs.map +1 -1
- package/dist/data/ai/PromptCatalog/prompt-page-model.d.ts +1 -1
- package/dist/data/ai/PromptCatalog/prompt-page-model.d.ts.map +1 -1
- package/dist/data/ai/PromptCatalog/prompt-page-model.js +4 -3
- package/dist/data/ai/PromptCatalog/prompt-page-model.js.map +1 -1
- package/dist/data/ai/PromptCatalog/types.d.ts +1 -0
- package/dist/data/ai/PromptCatalog/types.d.ts.map +1 -1
- package/dist/data/traces/index.d.ts +7 -0
- package/dist/data/traces/index.d.ts.map +1 -1
- package/dist/data/traces/otel/OperationList.cjs +64 -0
- package/dist/data/traces/otel/OperationList.cjs.map +1 -0
- package/dist/data/traces/otel/OperationList.d.ts +10 -0
- package/dist/data/traces/otel/OperationList.d.ts.map +1 -0
- package/dist/data/traces/otel/OperationList.js +64 -0
- package/dist/data/traces/otel/OperationList.js.map +1 -0
- package/dist/data/traces/otel/OtelTraceDetail.cjs +781 -0
- package/dist/data/traces/otel/OtelTraceDetail.cjs.map +1 -0
- package/dist/data/traces/otel/OtelTraceDetail.d.ts +7 -0
- package/dist/data/traces/otel/OtelTraceDetail.d.ts.map +1 -0
- package/dist/data/traces/otel/OtelTraceDetail.js +781 -0
- package/dist/data/traces/otel/OtelTraceDetail.js.map +1 -0
- package/dist/data/traces/otel/OtelTraceSearch.cjs +145 -0
- package/dist/data/traces/otel/OtelTraceSearch.cjs.map +1 -0
- package/dist/data/traces/otel/OtelTraceSearch.d.ts +16 -0
- package/dist/data/traces/otel/OtelTraceSearch.d.ts.map +1 -0
- package/dist/data/traces/otel/OtelTraceSearch.js +145 -0
- package/dist/data/traces/otel/OtelTraceSearch.js.map +1 -0
- package/dist/data/traces/otel/OtelTraceTable.cjs +47 -0
- package/dist/data/traces/otel/OtelTraceTable.cjs.map +1 -0
- package/dist/data/traces/otel/OtelTraceTable.d.ts +12 -0
- package/dist/data/traces/otel/OtelTraceTable.d.ts.map +1 -0
- package/dist/data/traces/otel/OtelTraceTable.js +47 -0
- package/dist/data/traces/otel/OtelTraceTable.js.map +1 -0
- package/dist/data/traces/otel/QueryBar.cjs +158 -0
- package/dist/data/traces/otel/QueryBar.cjs.map +1 -0
- package/dist/data/traces/otel/QueryBar.d.ts +12 -0
- package/dist/data/traces/otel/QueryBar.d.ts.map +1 -0
- package/dist/data/traces/otel/QueryBar.js +158 -0
- package/dist/data/traces/otel/QueryBar.js.map +1 -0
- package/dist/data/traces/otel/SpanCards.cjs +264 -0
- package/dist/data/traces/otel/SpanCards.cjs.map +1 -0
- package/dist/data/traces/otel/SpanCards.d.ts +17 -0
- package/dist/data/traces/otel/SpanCards.d.ts.map +1 -0
- package/dist/data/traces/otel/SpanCards.js +261 -0
- package/dist/data/traces/otel/SpanCards.js.map +1 -0
- package/dist/data/traces/otel/SpanCategory.cjs +18 -0
- package/dist/data/traces/otel/SpanCategory.cjs.map +1 -0
- package/dist/data/traces/otel/SpanCategory.d.ts +7 -0
- package/dist/data/traces/otel/SpanCategory.d.ts.map +1 -0
- package/dist/data/traces/otel/SpanCategory.js +18 -0
- package/dist/data/traces/otel/SpanCategory.js.map +1 -0
- package/dist/data/traces/otel/TraceResults.cjs +195 -0
- package/dist/data/traces/otel/TraceResults.cjs.map +1 -0
- package/dist/data/traces/otel/TraceResults.d.ts +19 -0
- package/dist/data/traces/otel/TraceResults.d.ts.map +1 -0
- package/dist/data/traces/otel/TraceResults.js +193 -0
- package/dist/data/traces/otel/TraceResults.js.map +1 -0
- package/dist/data/traces/otel/api.cjs +36 -0
- package/dist/data/traces/otel/api.cjs.map +1 -0
- package/dist/data/traces/otel/api.d.ts +87 -0
- package/dist/data/traces/otel/api.d.ts.map +1 -0
- package/dist/data/traces/otel/api.js +33 -0
- package/dist/data/traces/otel/api.js.map +1 -0
- package/dist/data/traces/otel/fixtures.d.ts +4 -0
- package/dist/data/traces/otel/fixtures.d.ts.map +1 -0
- package/dist/data/traces/otel/metrics.cjs +7 -0
- package/dist/data/traces/otel/metrics.cjs.map +1 -0
- package/dist/data/traces/otel/metrics.d.ts +2 -0
- package/dist/data/traces/otel/metrics.d.ts.map +1 -0
- package/dist/data/traces/otel/metrics.js +7 -0
- package/dist/data/traces/otel/metrics.js.map +1 -0
- package/dist/data/traces/otel/model.cjs +167 -0
- package/dist/data/traces/otel/model.cjs.map +1 -0
- package/dist/data/traces/otel/model.d.ts +81 -0
- package/dist/data/traces/otel/model.d.ts.map +1 -0
- package/dist/data/traces/otel/model.js +154 -0
- package/dist/data/traces/otel/model.js.map +1 -0
- package/dist/data/traces/otel/query.cjs +90 -0
- package/dist/data/traces/otel/query.cjs.map +1 -0
- package/dist/data/traces/otel/query.d.ts +20 -0
- package/dist/data/traces/otel/query.d.ts.map +1 -0
- package/dist/data/traces/otel/query.js +86 -0
- package/dist/data/traces/otel/query.js.map +1 -0
- package/dist/data/traces/otel/result-model.cjs +25 -0
- package/dist/data/traces/otel/result-model.cjs.map +1 -0
- package/dist/data/traces/otel/result-model.d.ts +5 -0
- package/dist/data/traces/otel/result-model.d.ts.map +1 -0
- package/dist/data/traces/otel/result-model.js +24 -0
- package/dist/data/traces/otel/result-model.js.map +1 -0
- package/dist/data/traces/otel/source.cjs +11 -0
- package/dist/data/traces/otel/source.cjs.map +1 -0
- package/dist/data/traces/otel/source.d.ts +5 -0
- package/dist/data/traces/otel/source.d.ts.map +1 -0
- package/dist/data/traces/otel/source.js +10 -0
- package/dist/data/traces/otel/source.js.map +1 -0
- package/dist/data/traces/otel/span-traces.cjs +39 -0
- package/dist/data/traces/otel/span-traces.cjs.map +1 -0
- package/dist/data/traces/otel/span-traces.d.ts +3 -0
- package/dist/data/traces/otel/span-traces.d.ts.map +1 -0
- package/dist/data/traces/otel/span-traces.js +39 -0
- package/dist/data/traces/otel/span-traces.js.map +1 -0
- package/dist/data/version-info.cjs +3 -3
- package/dist/data/version-info.js +3 -3
- package/dist/data.cjs +11 -0
- package/dist/data.js +6 -1
- package/dist/index.cjs +11 -0
- package/dist/index.js +6 -1
- package/dist/profiles/editor/profileEditorSections.cjs +4 -0
- package/dist/profiles/editor/profileEditorSections.cjs.map +1 -1
- package/dist/profiles/editor/profileEditorSections.d.ts.map +1 -1
- package/dist/profiles/editor/profileEditorSections.js +4 -0
- package/dist/profiles/editor/profileEditorSections.js.map +1 -1
- package/dist/rpc/CommandForm.cjs +1 -1
- package/dist/rpc/CommandForm.cjs.map +1 -1
- package/dist/rpc/CommandForm.js +1 -1
- package/dist/rpc/CommandForm.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpanCards.cjs","names":["num","StatStrip","metric","Properties","category","duration","selfTimeMs","_Fragment","useState","CodeBlock","Button","Icon","UiSqlQuery","Tinted","UiDatabase","CATEGORY_COLOR"],"sources":["../../../../src/data/traces/otel/SpanCards.tsx"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport { Button } from \"../../../components\";\nimport { CodeBlock } from \"../../CodeBlock\";\nimport { Properties } from \"../../Properties\";\nimport { StatStrip } from \"../../StatStrip\";\nimport { Icon } from \"../../Icon\";\nimport { UiDatabase, UiSqlQuery } from \"../../../icons\";\nimport { Tinted } from \"./SpanCategory\";\nimport { CATEGORY_COLOR, category, duration, num, selfTimeMs, type Span, type TraceIndex } from \"./model\";\nimport { metric } from \"./metrics\";\nconst attr = (span: Span, key: string) => span.attributes?.[key];\n\nexport function AgentCard({ index, span }: { index: TraceIndex; span: Span }) {\n const cost = num(attr(span, \"captain.cost_usd\"));\n const budget = num(attr(span, \"captain.budget.cost_usd\"));\n const kids = index.children.get(span.spanId) ?? [];\n return (\n <div className=\"space-y-3\">\n <StatStrip\n columns={3}\n items={[\n { label: \"Iterations\", value: `${attr(span, \"captain.iterations\") ?? \"—\"} / ${attr(span, \"captain.max_iterations\") ?? \"—\"}` },\n { label: \"Stopped\", value: String(attr(span, \"captain.stop_reason\") ?? \"—\"), tone: attr(span, \"captain.verified\") === true ? \"success\" : \"warning\", sub: attr(span, \"captain.verified\") === true ? \"verified\" : \"not verified\" },\n { label: \"Cost\", value: metric(cost, value => `$${value.toFixed(5)}`), sub: budget && cost !== undefined ? `${((cost / budget) * 100).toFixed(3)}% of $${budget}` : \"budget unavailable\" },\n ]}\n />\n <Properties items={[\n { key: \"Prompt\", value: String(attr(span, \"gen_ai.agent.name\") ?? \"—\") },\n { key: \"Scope\", value: String(attr(span, \"captain.scope\") ?? \"—\") },\n { key: \"Children\", value: `${kids.length} spans · ${kids.filter(k => category(k) === \"llm\").length} LLM · ${kids.filter(k => category(k) === \"db\").length} DB` },\n { key: \"Self-time\", value: `${duration(selfTimeMs(index, span))} not covered by a child span` },\n ]} />\n </div>\n );\n}\n\nexport function LlmCard({ span }: { span: Span }) {\n const n = (key: string) => num(attr(span, key));\n const requested = attr(span, \"gen_ai.request.model\");\n const served = attr(span, \"gen_ai.response.model\");\n const output = n(\"gen_ai.usage.output_tokens\");\n const outRate = output !== undefined && span.durationMs > 0 ? output / (span.durationMs / 1000) : undefined;\n return (\n <div className=\"space-y-3\">\n <p className=\"text-sm\">\n <span className=\"text-muted-foreground\">{String(attr(span, \"gen_ai.provider.name\") ?? \"—\")} · </span>\n <code>{String(requested ?? \"—\")}</code>\n {served !== undefined && served !== requested && <> → <code>{String(served ?? \"—\")}</code></>}\n <span className=\"text-muted-foreground\"> · {String(attr(span, \"captain.mode\") ?? \"—\")} · {String(attr(span, \"captain.prompt.source\") ?? \"—\")}</span>\n </p>\n <StatStrip\n columns={4}\n items={[\n { label: \"Input\", value: metric(n(\"gen_ai.usage.input_tokens\")), sub: `${metric(n(\"gen_ai.usage.cache_read.input_tokens\"))} cached` },\n { label: \"Output\", value: metric(n(\"gen_ai.usage.output_tokens\")), sub: `${metric(n(\"gen_ai.usage.reasoning_tokens\"))} reasoning` },\n { label: \"Throughput\", value: metric(outRate, value => value.toFixed(0)), sub: \"output tok/s\" },\n { label: \"Cost\", value: metric(n(\"captain.cost_usd\"), value => `$${value.toFixed(5)}`) },\n ]}\n />\n </div>\n );\n}\n\nconst PREVIEW_CHARS = 1200;\n\nexport function DbCard({ span }: { span: Span }) {\n const statement = String(attr(span, \"db.statement\") ?? \"\");\n const [full, setFull] = useState(false);\n useEffect(() => setFull(false), [span.spanId]);\n const clipped = statement.length > PREVIEW_CHARS && !full;\n return (\n <div className=\"space-y-3\">\n <p className=\"text-sm\"><span className=\"text-muted-foreground\">{String(attr(span, \"db.system\"))} · </span><code>{String(attr(span, \"db.sql.table\") ?? \"no table\")}</code></p>\n <StatStrip\n columns={2}\n items={[\n { label: \"Rows affected\", value: String(attr(span, \"db.rows_affected\") ?? \"—\") },\n { label: \"Statement\", value: `${(statement.length / 1024).toFixed(statement.length > 10240 ? 0 : 1)} KB`, sub: span.operation.replace(\"gorm.\", \"\"), tone: statement.length > 10240 ? \"warning\" : \"neutral\" },\n ]}\n />\n <div className=\"space-y-1\">\n <CodeBlock language=\"sql\" source={clipped ? `${statement.slice(0, PREVIEW_CHARS)} …` : statement} copyable />\n {statement.length > PREVIEW_CHARS && (\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setFull(on => !on)}>\n <Icon icon={UiSqlQuery} className=\"mr-1\" />\n {full ? \"Clip statement\" : `Show all ${statement.length.toLocaleString()} characters`}\n </Button>\n )}\n </div>\n </div>\n );\n}\n\nexport function GroupDetail({ index, spans, onSelect }: { index: TraceIndex; spans: Span[]; onSelect: (id: string) => void }) {\n const busy = spans.reduce((total, span) => total + span.durationMs, 0);\n const tables = new Map<string, { calls: number; ms: number }>();\n for (const span of spans) {\n const key = String(attr(span, \"db.sql.table\") ?? \"—\");\n const entry = tables.get(key) ?? { calls: 0, ms: 0 };\n tables.set(key, { calls: entry.calls + 1, ms: entry.ms + span.durationMs });\n }\n const slowest = [...spans].sort((a, b) => b.durationMs - a.durationMs)[0]!;\n return (\n <div className=\"space-y-4\">\n <h3 className=\"flex items-center gap-2 text-base font-semibold\"><Tinted icon={UiDatabase} color={CATEGORY_COLOR.db} />{spans.length} consecutive database calls</h3>\n <StatStrip\n columns={3}\n items={[\n { label: \"Busy\", value: duration(busy), sub: `over ${duration(index.offsetMs(spans.at(-1)!) + spans.at(-1)!.durationMs - index.offsetMs(spans[0]!))} wall` },\n { label: \"Tables\", value: String(tables.size) },\n { label: \"Slowest\", value: duration(slowest.durationMs), sub: `${slowest.operation.replace(\"gorm.\", \"\")} ${String(attr(slowest, \"db.sql.table\"))}` },\n ]}\n />\n <table className=\"w-full text-xs\">\n <thead className=\"border-b border-border text-left text-muted-foreground\">\n <tr><th className=\"py-1 font-medium\">Call</th><th className=\"py-1 font-medium\">Table</th><th className=\"py-1 text-right font-medium\">Rows</th><th className=\"py-1 text-right font-medium\">Duration</th></tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {spans.map(span => (\n <tr key={span.spanId} className=\"cursor-pointer hover:bg-muted\" onClick={() => onSelect(span.spanId)}>\n <td className=\"py-1\">{span.operation.replace(\"gorm.\", \"\")}</td>\n <td className=\"py-1 text-muted-foreground\">{String(attr(span, \"db.sql.table\") ?? \"—\")}</td>\n <td className=\"py-1 text-right tabular-nums\">{String(attr(span, \"db.rows_affected\") ?? \"\")}</td>\n <td className=\"py-1 text-right tabular-nums\">{duration(span.durationMs)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Span, TraceIndex } from './model.js';
|
|
2
|
+
export declare function AgentCard({ index, span }: {
|
|
3
|
+
index: TraceIndex;
|
|
4
|
+
span: Span;
|
|
5
|
+
}): import("react").JSX.Element;
|
|
6
|
+
export declare function LlmCard({ span }: {
|
|
7
|
+
span: Span;
|
|
8
|
+
}): import("react").JSX.Element;
|
|
9
|
+
export declare function DbCard({ span }: {
|
|
10
|
+
span: Span;
|
|
11
|
+
}): import("react").JSX.Element;
|
|
12
|
+
export declare function GroupDetail({ index, spans, onSelect }: {
|
|
13
|
+
index: TraceIndex;
|
|
14
|
+
spans: Span[];
|
|
15
|
+
onSelect: (id: string) => void;
|
|
16
|
+
}): import("react").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=SpanCards.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpanCards.d.ts","sourceRoot":"","sources":["../../../../src/data/traces/otel/SpanCards.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAuD,KAAK,IAAI,EAAE,KAAK,UAAU,EAAE,MAAM,SAAS,CAAC;AAI1G,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,IAAI,CAAA;CAAE,+BAsB3E;AAED,wBAAgB,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,+BAyB/C;AAID,wBAAgB,MAAM,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,+BA0B9C;AAED,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE;IAAE,KAAK,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,IAAI,EAAE,CAAC;IAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,+BAqC3H"}
|
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
import { UiSqlQuery } from "../../../icons/components/UiSqlQuery.js";
|
|
2
|
+
import { UiDatabase } from "../../../icons/components/UiDatabase.js";
|
|
3
|
+
import { Icon } from "../../Icon.js";
|
|
4
|
+
import { Button } from "../../../components/button.js";
|
|
5
|
+
import { Properties } from "../../Properties.js";
|
|
6
|
+
import { CodeBlock } from "../../CodeBlock.js";
|
|
7
|
+
import { StatStrip } from "../../StatStrip.js";
|
|
8
|
+
import { Tinted } from "./SpanCategory.js";
|
|
9
|
+
import { CATEGORY_COLOR, category, duration, num, selfTimeMs } from "./model.js";
|
|
10
|
+
import { metric } from "./metrics.js";
|
|
11
|
+
import { useEffect, useState } from "react";
|
|
12
|
+
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
13
|
+
// src/data/traces/otel/SpanCards.tsx
|
|
14
|
+
var attr = (span, key) => span.attributes?.[key];
|
|
15
|
+
function AgentCard({ index, span }) {
|
|
16
|
+
const cost = num(attr(span, "captain.cost_usd"));
|
|
17
|
+
const budget = num(attr(span, "captain.budget.cost_usd"));
|
|
18
|
+
const kids = index.children.get(span.spanId) ?? [];
|
|
19
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
20
|
+
className: "space-y-3",
|
|
21
|
+
children: [/* @__PURE__ */ jsx(StatStrip, {
|
|
22
|
+
columns: 3,
|
|
23
|
+
items: [
|
|
24
|
+
{
|
|
25
|
+
label: "Iterations",
|
|
26
|
+
value: `${attr(span, "captain.iterations") ?? "—"} / ${attr(span, "captain.max_iterations") ?? "—"}`
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
label: "Stopped",
|
|
30
|
+
value: String(attr(span, "captain.stop_reason") ?? "—"),
|
|
31
|
+
tone: attr(span, "captain.verified") === true ? "success" : "warning",
|
|
32
|
+
sub: attr(span, "captain.verified") === true ? "verified" : "not verified"
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
label: "Cost",
|
|
36
|
+
value: metric(cost, (value) => `$${value.toFixed(5)}`),
|
|
37
|
+
sub: budget && cost !== void 0 ? `${(cost / budget * 100).toFixed(3)}% of $${budget}` : "budget unavailable"
|
|
38
|
+
}
|
|
39
|
+
]
|
|
40
|
+
}), /* @__PURE__ */ jsx(Properties, { items: [
|
|
41
|
+
{
|
|
42
|
+
key: "Prompt",
|
|
43
|
+
value: String(attr(span, "gen_ai.agent.name") ?? "—")
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
key: "Scope",
|
|
47
|
+
value: String(attr(span, "captain.scope") ?? "—")
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
key: "Children",
|
|
51
|
+
value: `${kids.length} spans · ${kids.filter((k) => category(k) === "llm").length} LLM · ${kids.filter((k) => category(k) === "db").length} DB`
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
key: "Self-time",
|
|
55
|
+
value: `${duration(selfTimeMs(index, span))} not covered by a child span`
|
|
56
|
+
}
|
|
57
|
+
] })]
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function LlmCard({ span }) {
|
|
61
|
+
const n = (key) => num(attr(span, key));
|
|
62
|
+
const requested = attr(span, "gen_ai.request.model");
|
|
63
|
+
const served = attr(span, "gen_ai.response.model");
|
|
64
|
+
const output = n("gen_ai.usage.output_tokens");
|
|
65
|
+
const outRate = output !== void 0 && span.durationMs > 0 ? output / (span.durationMs / 1e3) : void 0;
|
|
66
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
67
|
+
className: "space-y-3",
|
|
68
|
+
children: [/* @__PURE__ */ jsxs("p", {
|
|
69
|
+
className: "text-sm",
|
|
70
|
+
children: [
|
|
71
|
+
/* @__PURE__ */ jsxs("span", {
|
|
72
|
+
className: "text-muted-foreground",
|
|
73
|
+
children: [String(attr(span, "gen_ai.provider.name") ?? "—"), " · "]
|
|
74
|
+
}),
|
|
75
|
+
/* @__PURE__ */ jsx("code", { children: String(requested ?? "—") }),
|
|
76
|
+
served !== void 0 && served !== requested && /* @__PURE__ */ jsxs(Fragment$1, { children: [" → ", /* @__PURE__ */ jsx("code", { children: String(served ?? "—") })] }),
|
|
77
|
+
/* @__PURE__ */ jsxs("span", {
|
|
78
|
+
className: "text-muted-foreground",
|
|
79
|
+
children: [
|
|
80
|
+
" · ",
|
|
81
|
+
String(attr(span, "captain.mode") ?? "—"),
|
|
82
|
+
" · ",
|
|
83
|
+
String(attr(span, "captain.prompt.source") ?? "—")
|
|
84
|
+
]
|
|
85
|
+
})
|
|
86
|
+
]
|
|
87
|
+
}), /* @__PURE__ */ jsx(StatStrip, {
|
|
88
|
+
columns: 4,
|
|
89
|
+
items: [
|
|
90
|
+
{
|
|
91
|
+
label: "Input",
|
|
92
|
+
value: metric(n("gen_ai.usage.input_tokens")),
|
|
93
|
+
sub: `${metric(n("gen_ai.usage.cache_read.input_tokens"))} cached`
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
label: "Output",
|
|
97
|
+
value: metric(n("gen_ai.usage.output_tokens")),
|
|
98
|
+
sub: `${metric(n("gen_ai.usage.reasoning_tokens"))} reasoning`
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
label: "Throughput",
|
|
102
|
+
value: metric(outRate, (value) => value.toFixed(0)),
|
|
103
|
+
sub: "output tok/s"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
label: "Cost",
|
|
107
|
+
value: metric(n("captain.cost_usd"), (value) => `$${value.toFixed(5)}`)
|
|
108
|
+
}
|
|
109
|
+
]
|
|
110
|
+
})]
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
var PREVIEW_CHARS = 1200;
|
|
114
|
+
function DbCard({ span }) {
|
|
115
|
+
const statement = String(attr(span, "db.statement") ?? "");
|
|
116
|
+
const [full, setFull] = useState(false);
|
|
117
|
+
useEffect(() => setFull(false), [span.spanId]);
|
|
118
|
+
const clipped = statement.length > PREVIEW_CHARS && !full;
|
|
119
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
120
|
+
className: "space-y-3",
|
|
121
|
+
children: [
|
|
122
|
+
/* @__PURE__ */ jsxs("p", {
|
|
123
|
+
className: "text-sm",
|
|
124
|
+
children: [/* @__PURE__ */ jsxs("span", {
|
|
125
|
+
className: "text-muted-foreground",
|
|
126
|
+
children: [String(attr(span, "db.system")), " · "]
|
|
127
|
+
}), /* @__PURE__ */ jsx("code", { children: String(attr(span, "db.sql.table") ?? "no table") })]
|
|
128
|
+
}),
|
|
129
|
+
/* @__PURE__ */ jsx(StatStrip, {
|
|
130
|
+
columns: 2,
|
|
131
|
+
items: [{
|
|
132
|
+
label: "Rows affected",
|
|
133
|
+
value: String(attr(span, "db.rows_affected") ?? "—")
|
|
134
|
+
}, {
|
|
135
|
+
label: "Statement",
|
|
136
|
+
value: `${(statement.length / 1024).toFixed(statement.length > 10240 ? 0 : 1)} KB`,
|
|
137
|
+
sub: span.operation.replace("gorm.", ""),
|
|
138
|
+
tone: statement.length > 10240 ? "warning" : "neutral"
|
|
139
|
+
}]
|
|
140
|
+
}),
|
|
141
|
+
/* @__PURE__ */ jsxs("div", {
|
|
142
|
+
className: "space-y-1",
|
|
143
|
+
children: [/* @__PURE__ */ jsx(CodeBlock, {
|
|
144
|
+
language: "sql",
|
|
145
|
+
source: clipped ? `${statement.slice(0, PREVIEW_CHARS)} …` : statement,
|
|
146
|
+
copyable: true
|
|
147
|
+
}), statement.length > PREVIEW_CHARS && /* @__PURE__ */ jsxs(Button, {
|
|
148
|
+
size: "sm",
|
|
149
|
+
variant: "ghost",
|
|
150
|
+
onClick: () => setFull((on) => !on),
|
|
151
|
+
children: [/* @__PURE__ */ jsx(Icon, {
|
|
152
|
+
icon: UiSqlQuery,
|
|
153
|
+
className: "mr-1"
|
|
154
|
+
}), full ? "Clip statement" : `Show all ${statement.length.toLocaleString()} characters`]
|
|
155
|
+
})]
|
|
156
|
+
})
|
|
157
|
+
]
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
function GroupDetail({ index, spans, onSelect }) {
|
|
161
|
+
const busy = spans.reduce((total, span) => total + span.durationMs, 0);
|
|
162
|
+
const tables = /* @__PURE__ */ new Map();
|
|
163
|
+
for (const span of spans) {
|
|
164
|
+
const key = String(attr(span, "db.sql.table") ?? "—");
|
|
165
|
+
const entry = tables.get(key) ?? {
|
|
166
|
+
calls: 0,
|
|
167
|
+
ms: 0
|
|
168
|
+
};
|
|
169
|
+
tables.set(key, {
|
|
170
|
+
calls: entry.calls + 1,
|
|
171
|
+
ms: entry.ms + span.durationMs
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
const slowest = [...spans].sort((a, b) => b.durationMs - a.durationMs)[0];
|
|
175
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
176
|
+
className: "space-y-4",
|
|
177
|
+
children: [
|
|
178
|
+
/* @__PURE__ */ jsxs("h3", {
|
|
179
|
+
className: "flex items-center gap-2 text-base font-semibold",
|
|
180
|
+
children: [
|
|
181
|
+
/* @__PURE__ */ jsx(Tinted, {
|
|
182
|
+
icon: UiDatabase,
|
|
183
|
+
color: CATEGORY_COLOR.db
|
|
184
|
+
}),
|
|
185
|
+
spans.length,
|
|
186
|
+
" consecutive database calls"
|
|
187
|
+
]
|
|
188
|
+
}),
|
|
189
|
+
/* @__PURE__ */ jsx(StatStrip, {
|
|
190
|
+
columns: 3,
|
|
191
|
+
items: [
|
|
192
|
+
{
|
|
193
|
+
label: "Busy",
|
|
194
|
+
value: duration(busy),
|
|
195
|
+
sub: `over ${duration(index.offsetMs(spans.at(-1)) + spans.at(-1).durationMs - index.offsetMs(spans[0]))} wall`
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
label: "Tables",
|
|
199
|
+
value: String(tables.size)
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
label: "Slowest",
|
|
203
|
+
value: duration(slowest.durationMs),
|
|
204
|
+
sub: `${slowest.operation.replace("gorm.", "")} ${String(attr(slowest, "db.sql.table"))}`
|
|
205
|
+
}
|
|
206
|
+
]
|
|
207
|
+
}),
|
|
208
|
+
/* @__PURE__ */ jsxs("table", {
|
|
209
|
+
className: "w-full text-xs",
|
|
210
|
+
children: [/* @__PURE__ */ jsx("thead", {
|
|
211
|
+
className: "border-b border-border text-left text-muted-foreground",
|
|
212
|
+
children: /* @__PURE__ */ jsxs("tr", { children: [
|
|
213
|
+
/* @__PURE__ */ jsx("th", {
|
|
214
|
+
className: "py-1 font-medium",
|
|
215
|
+
children: "Call"
|
|
216
|
+
}),
|
|
217
|
+
/* @__PURE__ */ jsx("th", {
|
|
218
|
+
className: "py-1 font-medium",
|
|
219
|
+
children: "Table"
|
|
220
|
+
}),
|
|
221
|
+
/* @__PURE__ */ jsx("th", {
|
|
222
|
+
className: "py-1 text-right font-medium",
|
|
223
|
+
children: "Rows"
|
|
224
|
+
}),
|
|
225
|
+
/* @__PURE__ */ jsx("th", {
|
|
226
|
+
className: "py-1 text-right font-medium",
|
|
227
|
+
children: "Duration"
|
|
228
|
+
})
|
|
229
|
+
] })
|
|
230
|
+
}), /* @__PURE__ */ jsx("tbody", {
|
|
231
|
+
className: "divide-y divide-border",
|
|
232
|
+
children: spans.map((span) => /* @__PURE__ */ jsxs("tr", {
|
|
233
|
+
className: "cursor-pointer hover:bg-muted",
|
|
234
|
+
onClick: () => onSelect(span.spanId),
|
|
235
|
+
children: [
|
|
236
|
+
/* @__PURE__ */ jsx("td", {
|
|
237
|
+
className: "py-1",
|
|
238
|
+
children: span.operation.replace("gorm.", "")
|
|
239
|
+
}),
|
|
240
|
+
/* @__PURE__ */ jsx("td", {
|
|
241
|
+
className: "py-1 text-muted-foreground",
|
|
242
|
+
children: String(attr(span, "db.sql.table") ?? "—")
|
|
243
|
+
}),
|
|
244
|
+
/* @__PURE__ */ jsx("td", {
|
|
245
|
+
className: "py-1 text-right tabular-nums",
|
|
246
|
+
children: String(attr(span, "db.rows_affected") ?? "")
|
|
247
|
+
}),
|
|
248
|
+
/* @__PURE__ */ jsx("td", {
|
|
249
|
+
className: "py-1 text-right tabular-nums",
|
|
250
|
+
children: duration(span.durationMs)
|
|
251
|
+
})
|
|
252
|
+
]
|
|
253
|
+
}, span.spanId))
|
|
254
|
+
})]
|
|
255
|
+
})
|
|
256
|
+
]
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
export { AgentCard, DbCard, GroupDetail, LlmCard };
|
|
260
|
+
|
|
261
|
+
//# sourceMappingURL=SpanCards.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpanCards.js","names":["_Fragment"],"sources":["../../../../src/data/traces/otel/SpanCards.tsx"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport { Button } from \"../../../components\";\nimport { CodeBlock } from \"../../CodeBlock\";\nimport { Properties } from \"../../Properties\";\nimport { StatStrip } from \"../../StatStrip\";\nimport { Icon } from \"../../Icon\";\nimport { UiDatabase, UiSqlQuery } from \"../../../icons\";\nimport { Tinted } from \"./SpanCategory\";\nimport { CATEGORY_COLOR, category, duration, num, selfTimeMs, type Span, type TraceIndex } from \"./model\";\nimport { metric } from \"./metrics\";\nconst attr = (span: Span, key: string) => span.attributes?.[key];\n\nexport function AgentCard({ index, span }: { index: TraceIndex; span: Span }) {\n const cost = num(attr(span, \"captain.cost_usd\"));\n const budget = num(attr(span, \"captain.budget.cost_usd\"));\n const kids = index.children.get(span.spanId) ?? [];\n return (\n <div className=\"space-y-3\">\n <StatStrip\n columns={3}\n items={[\n { label: \"Iterations\", value: `${attr(span, \"captain.iterations\") ?? \"—\"} / ${attr(span, \"captain.max_iterations\") ?? \"—\"}` },\n { label: \"Stopped\", value: String(attr(span, \"captain.stop_reason\") ?? \"—\"), tone: attr(span, \"captain.verified\") === true ? \"success\" : \"warning\", sub: attr(span, \"captain.verified\") === true ? \"verified\" : \"not verified\" },\n { label: \"Cost\", value: metric(cost, value => `$${value.toFixed(5)}`), sub: budget && cost !== undefined ? `${((cost / budget) * 100).toFixed(3)}% of $${budget}` : \"budget unavailable\" },\n ]}\n />\n <Properties items={[\n { key: \"Prompt\", value: String(attr(span, \"gen_ai.agent.name\") ?? \"—\") },\n { key: \"Scope\", value: String(attr(span, \"captain.scope\") ?? \"—\") },\n { key: \"Children\", value: `${kids.length} spans · ${kids.filter(k => category(k) === \"llm\").length} LLM · ${kids.filter(k => category(k) === \"db\").length} DB` },\n { key: \"Self-time\", value: `${duration(selfTimeMs(index, span))} not covered by a child span` },\n ]} />\n </div>\n );\n}\n\nexport function LlmCard({ span }: { span: Span }) {\n const n = (key: string) => num(attr(span, key));\n const requested = attr(span, \"gen_ai.request.model\");\n const served = attr(span, \"gen_ai.response.model\");\n const output = n(\"gen_ai.usage.output_tokens\");\n const outRate = output !== undefined && span.durationMs > 0 ? output / (span.durationMs / 1000) : undefined;\n return (\n <div className=\"space-y-3\">\n <p className=\"text-sm\">\n <span className=\"text-muted-foreground\">{String(attr(span, \"gen_ai.provider.name\") ?? \"—\")} · </span>\n <code>{String(requested ?? \"—\")}</code>\n {served !== undefined && served !== requested && <> → <code>{String(served ?? \"—\")}</code></>}\n <span className=\"text-muted-foreground\"> · {String(attr(span, \"captain.mode\") ?? \"—\")} · {String(attr(span, \"captain.prompt.source\") ?? \"—\")}</span>\n </p>\n <StatStrip\n columns={4}\n items={[\n { label: \"Input\", value: metric(n(\"gen_ai.usage.input_tokens\")), sub: `${metric(n(\"gen_ai.usage.cache_read.input_tokens\"))} cached` },\n { label: \"Output\", value: metric(n(\"gen_ai.usage.output_tokens\")), sub: `${metric(n(\"gen_ai.usage.reasoning_tokens\"))} reasoning` },\n { label: \"Throughput\", value: metric(outRate, value => value.toFixed(0)), sub: \"output tok/s\" },\n { label: \"Cost\", value: metric(n(\"captain.cost_usd\"), value => `$${value.toFixed(5)}`) },\n ]}\n />\n </div>\n );\n}\n\nconst PREVIEW_CHARS = 1200;\n\nexport function DbCard({ span }: { span: Span }) {\n const statement = String(attr(span, \"db.statement\") ?? \"\");\n const [full, setFull] = useState(false);\n useEffect(() => setFull(false), [span.spanId]);\n const clipped = statement.length > PREVIEW_CHARS && !full;\n return (\n <div className=\"space-y-3\">\n <p className=\"text-sm\"><span className=\"text-muted-foreground\">{String(attr(span, \"db.system\"))} · </span><code>{String(attr(span, \"db.sql.table\") ?? \"no table\")}</code></p>\n <StatStrip\n columns={2}\n items={[\n { label: \"Rows affected\", value: String(attr(span, \"db.rows_affected\") ?? \"—\") },\n { label: \"Statement\", value: `${(statement.length / 1024).toFixed(statement.length > 10240 ? 0 : 1)} KB`, sub: span.operation.replace(\"gorm.\", \"\"), tone: statement.length > 10240 ? \"warning\" : \"neutral\" },\n ]}\n />\n <div className=\"space-y-1\">\n <CodeBlock language=\"sql\" source={clipped ? `${statement.slice(0, PREVIEW_CHARS)} …` : statement} copyable />\n {statement.length > PREVIEW_CHARS && (\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setFull(on => !on)}>\n <Icon icon={UiSqlQuery} className=\"mr-1\" />\n {full ? \"Clip statement\" : `Show all ${statement.length.toLocaleString()} characters`}\n </Button>\n )}\n </div>\n </div>\n );\n}\n\nexport function GroupDetail({ index, spans, onSelect }: { index: TraceIndex; spans: Span[]; onSelect: (id: string) => void }) {\n const busy = spans.reduce((total, span) => total + span.durationMs, 0);\n const tables = new Map<string, { calls: number; ms: number }>();\n for (const span of spans) {\n const key = String(attr(span, \"db.sql.table\") ?? \"—\");\n const entry = tables.get(key) ?? { calls: 0, ms: 0 };\n tables.set(key, { calls: entry.calls + 1, ms: entry.ms + span.durationMs });\n }\n const slowest = [...spans].sort((a, b) => b.durationMs - a.durationMs)[0]!;\n return (\n <div className=\"space-y-4\">\n <h3 className=\"flex items-center gap-2 text-base font-semibold\"><Tinted icon={UiDatabase} color={CATEGORY_COLOR.db} />{spans.length} consecutive database calls</h3>\n <StatStrip\n columns={3}\n items={[\n { label: \"Busy\", value: duration(busy), sub: `over ${duration(index.offsetMs(spans.at(-1)!) + spans.at(-1)!.durationMs - index.offsetMs(spans[0]!))} wall` },\n { label: \"Tables\", value: String(tables.size) },\n { label: \"Slowest\", value: duration(slowest.durationMs), sub: `${slowest.operation.replace(\"gorm.\", \"\")} ${String(attr(slowest, \"db.sql.table\"))}` },\n ]}\n />\n <table className=\"w-full text-xs\">\n <thead className=\"border-b border-border text-left text-muted-foreground\">\n <tr><th className=\"py-1 font-medium\">Call</th><th className=\"py-1 font-medium\">Table</th><th className=\"py-1 text-right font-medium\">Rows</th><th className=\"py-1 text-right font-medium\">Duration</th></tr>\n </thead>\n <tbody className=\"divide-y divide-border\">\n {spans.map(span => (\n <tr key={span.spanId} className=\"cursor-pointer hover:bg-muted\" onClick={() => onSelect(span.spanId)}>\n <td className=\"py-1\">{span.operation.replace(\"gorm.\", \"\")}</td>\n <td className=\"py-1 text-muted-foreground\">{String(attr(span, \"db.sql.table\") ?? \"—\")}</td>\n <td className=\"py-1 text-right tabular-nums\">{String(attr(span, \"db.rows_affected\") ?? \"\")}</td>\n <td className=\"py-1 text-right tabular-nums\">{duration(span.durationMs)}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const require_Icon = require("../../Icon.cjs");
|
|
2
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
3
|
+
// src/data/traces/otel/SpanCategory.tsx
|
|
4
|
+
function Tinted({ icon, color, label }) {
|
|
5
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
6
|
+
className: "inline-flex shrink-0",
|
|
7
|
+
style: { color },
|
|
8
|
+
...label ? {
|
|
9
|
+
role: "img",
|
|
10
|
+
"aria-label": label,
|
|
11
|
+
title: label
|
|
12
|
+
} : {},
|
|
13
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_Icon.Icon, { icon })
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
exports.Tinted = Tinted;
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=SpanCategory.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpanCategory.cjs","names":["Icon"],"sources":["../../../../src/data/traces/otel/SpanCategory.tsx"],"sourcesContent":["import { Icon } from \"../../Icon\";\nimport { UiClock } from \"../../../icons\";\nexport function Tinted({ icon, color, label }: { icon: typeof UiClock; color: string; label?: string }) {\n return <span className=\"inline-flex shrink-0\" style={{ color }} {...(label ? { role: \"img\", \"aria-label\": label, title: label } : {})}><Icon icon={icon} /></span>;\n}\n"],"mappings":";;;AAEA,SAAgB,OAAO,EAAE,MAAM,OAAO,SAAkE;CACtG,OAAO,iBAAA,GAAA,kBAAA,IAAA,CAAC,QAAD;EAAM,WAAU;EAAuB,OAAO,EAAE,MAAM;EAAG,GAAK,QAAQ;GAAE,MAAM;GAAO,cAAc;GAAO,OAAO;EAAM,IAAI,CAAC;EAAI,UAAA,iBAAA,GAAA,kBAAA,IAAA,CAACA,aAAAA,MAAD,EAAY,KAAO,CAAA;CAAO,CAAA;AACnK"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpanCategory.d.ts","sourceRoot":"","sources":["../../../../src/data/traces/otel/SpanCategory.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,wBAAgB,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;IAAE,IAAI,EAAE,OAAO,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,+BAErG"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Icon } from "../../Icon.js";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
// src/data/traces/otel/SpanCategory.tsx
|
|
4
|
+
function Tinted({ icon, color, label }) {
|
|
5
|
+
return /* @__PURE__ */ jsx("span", {
|
|
6
|
+
className: "inline-flex shrink-0",
|
|
7
|
+
style: { color },
|
|
8
|
+
...label ? {
|
|
9
|
+
role: "img",
|
|
10
|
+
"aria-label": label,
|
|
11
|
+
title: label
|
|
12
|
+
} : {},
|
|
13
|
+
children: /* @__PURE__ */ jsx(Icon, { icon })
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
export { Tinted };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=SpanCategory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SpanCategory.js","names":[],"sources":["../../../../src/data/traces/otel/SpanCategory.tsx"],"sourcesContent":["import { Icon } from \"../../Icon\";\nimport { UiClock } from \"../../../icons\";\nexport function Tinted({ icon, color, label }: { icon: typeof UiClock; color: string; label?: string }) {\n return <span className=\"inline-flex shrink-0\" style={{ color }} {...(label ? { role: \"img\", \"aria-label\": label, title: label } : {})}><Icon icon={icon} /></span>;\n}\n"],"mappings":";;;AAEA,SAAgB,OAAO,EAAE,MAAM,OAAO,SAAkE;CACtG,OAAO,oBAAC,QAAD;EAAM,WAAU;EAAuB,OAAO,EAAE,MAAM;EAAG,GAAK,QAAQ;GAAE,MAAM;GAAO,cAAc;GAAO,OAAO;EAAM,IAAI,CAAC;EAAI,UAAA,oBAAC,MAAD,EAAY,KAAO,CAAA;CAAO,CAAA;AACnK"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
const require_Badge = require("../../Badge.cjs");
|
|
2
|
+
const require_DataTable = require("../../DataTable.cjs");
|
|
3
|
+
const require_api = require("./api.cjs");
|
|
4
|
+
const require_query = require("./query.cjs");
|
|
5
|
+
const require_result_model = require("./result-model.cjs");
|
|
6
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
7
|
+
// src/data/traces/otel/TraceResults.tsx
|
|
8
|
+
var startMs = (trace) => Date.parse(trace.startedAt);
|
|
9
|
+
var clock = (ms) => new Date(ms).toLocaleTimeString([], {
|
|
10
|
+
hour: "2-digit",
|
|
11
|
+
minute: "2-digit",
|
|
12
|
+
second: "2-digit"
|
|
13
|
+
});
|
|
14
|
+
function ResultSummary({ result }) {
|
|
15
|
+
const shown = result.traces.length;
|
|
16
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
17
|
+
className: "text-sm text-muted-foreground",
|
|
18
|
+
children: [
|
|
19
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
20
|
+
className: "font-medium text-foreground",
|
|
21
|
+
children: shown
|
|
22
|
+
}),
|
|
23
|
+
" ",
|
|
24
|
+
shown === 1 ? "trace" : "traces",
|
|
25
|
+
shown < result.total ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
26
|
+
" · the ",
|
|
27
|
+
shown,
|
|
28
|
+
" newest of ",
|
|
29
|
+
result.total.toLocaleString(),
|
|
30
|
+
". Narrow the window or operation to see older ones"
|
|
31
|
+
] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: " · all in the window" })
|
|
32
|
+
]
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/** Each trace by when it started and how long it took, dot size by span count. */
|
|
36
|
+
function Scatter({ traces, onOpen }) {
|
|
37
|
+
const starts = traces.map(startMs);
|
|
38
|
+
const t0 = Math.min(...starts);
|
|
39
|
+
const span = Math.max(...starts) - t0;
|
|
40
|
+
const slowest = Math.max(...traces.map((trace) => trace.durationMs)) || 1;
|
|
41
|
+
const step = require_result_model.niceStep(slowest, 4);
|
|
42
|
+
const top = Math.ceil(slowest * 1.05 / step) * step;
|
|
43
|
+
const yTicks = Array.from({ length: Math.round(top / step) + 1 }, (_, i) => i * step);
|
|
44
|
+
const xTicks = span === 0 ? [.5] : [
|
|
45
|
+
0,
|
|
46
|
+
.25,
|
|
47
|
+
.5,
|
|
48
|
+
.75,
|
|
49
|
+
1
|
|
50
|
+
];
|
|
51
|
+
const x = (ms) => span === 0 ? .5 : (ms - t0) / span;
|
|
52
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("figure", {
|
|
53
|
+
className: "rounded-lg border border-border p-density-2",
|
|
54
|
+
"aria-label": "Duration over time",
|
|
55
|
+
children: [
|
|
56
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("figcaption", {
|
|
57
|
+
className: "mb-1 flex items-center gap-3 text-xs text-muted-foreground",
|
|
58
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
59
|
+
className: "font-medium text-foreground",
|
|
60
|
+
children: "Duration over time"
|
|
61
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "dot size = span count · click to open" })]
|
|
62
|
+
}),
|
|
63
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
64
|
+
className: "relative ml-[4.5rem] mr-2 mt-3.5 h-[180px]",
|
|
65
|
+
children: [yTicks.map((y) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
66
|
+
className: "absolute inset-x-0 border-t border-border/60",
|
|
67
|
+
style: { bottom: `${y / top * 100}%` },
|
|
68
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
69
|
+
className: "absolute right-full -translate-y-1/2 whitespace-nowrap pr-1.5 text-xs tabular-nums text-muted-foreground",
|
|
70
|
+
children: y === 0 ? "0" : require_api.duration(y)
|
|
71
|
+
})
|
|
72
|
+
}, y)), traces.map((trace) => {
|
|
73
|
+
const size = 6 + Math.log2(trace.spanCount) * 1.6;
|
|
74
|
+
const label = `${require_query.shortOperation(trace.operation)}, ${require_api.duration(trace.durationMs)}, ${trace.spanCount} spans at ${clock(startMs(trace))}`;
|
|
75
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
76
|
+
type: "button",
|
|
77
|
+
"aria-label": label,
|
|
78
|
+
title: label,
|
|
79
|
+
onClick: () => onOpen(trace.traceId),
|
|
80
|
+
className: `absolute -translate-x-1/2 translate-y-1/2 rounded-full opacity-75 hover:ring-2 hover:ring-ring ${trace.errors > 0 ? "bg-destructive" : trace.spanCount > 1 ? "bg-primary" : "bg-muted-foreground"}`,
|
|
81
|
+
style: {
|
|
82
|
+
left: `${x(startMs(trace)) * 100}%`,
|
|
83
|
+
bottom: `${trace.durationMs / top * 100}%`,
|
|
84
|
+
width: size,
|
|
85
|
+
height: size
|
|
86
|
+
}
|
|
87
|
+
}, trace.traceId);
|
|
88
|
+
})]
|
|
89
|
+
}),
|
|
90
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
91
|
+
className: "relative ml-[4.5rem] mr-2 mt-1 h-4 text-xs tabular-nums text-muted-foreground",
|
|
92
|
+
children: xTicks.map((fraction, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
93
|
+
className: `absolute whitespace-nowrap ${xTicks.length > 1 && i === 0 ? "" : xTicks.length > 1 && i === xTicks.length - 1 ? "-translate-x-full" : "-translate-x-1/2"}`,
|
|
94
|
+
style: { left: `${fraction * 100}%` },
|
|
95
|
+
children: clock(t0 + fraction * span)
|
|
96
|
+
}, fraction))
|
|
97
|
+
})
|
|
98
|
+
]
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/** The traces, newest first: what ran, when, how long against the slowest, and its span count. */
|
|
102
|
+
function ResultTable({ traces, href, onOpen, now, tableProps = {} }) {
|
|
103
|
+
const slowest = Math.max(1, ...traces.map((trace) => trace.durationMs));
|
|
104
|
+
const columns = [
|
|
105
|
+
{
|
|
106
|
+
key: "operation",
|
|
107
|
+
label: "Trace",
|
|
108
|
+
grow: true,
|
|
109
|
+
minWidth: 320,
|
|
110
|
+
render: (_, trace) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
111
|
+
className: "flex min-w-0 items-center gap-2",
|
|
112
|
+
title: trace.operation,
|
|
113
|
+
children: [
|
|
114
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
115
|
+
className: "shrink-0 font-medium",
|
|
116
|
+
children: require_query.shortOperation(trace.operation) || trace.traceId
|
|
117
|
+
}),
|
|
118
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
|
|
119
|
+
className: "text-xs text-muted-foreground",
|
|
120
|
+
children: trace.traceId.slice(0, 8)
|
|
121
|
+
}),
|
|
122
|
+
trace.services.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
123
|
+
className: "truncate text-xs text-muted-foreground",
|
|
124
|
+
children: trace.services.join(" → ")
|
|
125
|
+
}),
|
|
126
|
+
trace.errors > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_Badge.Badge, {
|
|
127
|
+
size: "sm",
|
|
128
|
+
tone: "danger",
|
|
129
|
+
variant: "soft",
|
|
130
|
+
children: [
|
|
131
|
+
trace.errors,
|
|
132
|
+
" ",
|
|
133
|
+
trace.errors === 1 ? "error" : "errors"
|
|
134
|
+
]
|
|
135
|
+
})
|
|
136
|
+
]
|
|
137
|
+
})
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
key: "startedAt",
|
|
141
|
+
label: "Started",
|
|
142
|
+
render: (_, trace) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
143
|
+
className: "whitespace-nowrap tabular-nums",
|
|
144
|
+
children: [
|
|
145
|
+
clock(startMs(trace)),
|
|
146
|
+
" ",
|
|
147
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
148
|
+
className: "text-muted-foreground",
|
|
149
|
+
children: require_result_model.ago(now - startMs(trace))
|
|
150
|
+
})
|
|
151
|
+
]
|
|
152
|
+
})
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
key: "durationMs",
|
|
156
|
+
label: "Duration",
|
|
157
|
+
render: (_, trace) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
158
|
+
className: "flex items-center gap-2",
|
|
159
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
160
|
+
className: "relative h-1.5 w-24 rounded-full bg-muted",
|
|
161
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
162
|
+
className: "absolute inset-y-0 left-0 rounded-full bg-primary",
|
|
163
|
+
style: { width: `${trace.durationMs / slowest * 100}%` }
|
|
164
|
+
})
|
|
165
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
166
|
+
className: "tabular-nums",
|
|
167
|
+
children: require_api.duration(trace.durationMs)
|
|
168
|
+
})]
|
|
169
|
+
})
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
key: "spanCount",
|
|
173
|
+
label: "Spans",
|
|
174
|
+
align: "right"
|
|
175
|
+
}
|
|
176
|
+
];
|
|
177
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
178
|
+
className: "flex h-[28rem] min-h-0 flex-col",
|
|
179
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_DataTable.DataTable, {
|
|
180
|
+
...tableProps,
|
|
181
|
+
data: traces,
|
|
182
|
+
columns,
|
|
183
|
+
getRowId: (trace) => trace.traceId,
|
|
184
|
+
autoFilter: false,
|
|
185
|
+
getRowHref: (trace) => href(trace.traceId),
|
|
186
|
+
onRowClick: (trace) => onOpen(trace.traceId),
|
|
187
|
+
emptyMessage: "No traces match. Widen the time range, clear the duration or attribute filters, or show single-span traces."
|
|
188
|
+
})
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
exports.ResultSummary = ResultSummary;
|
|
192
|
+
exports.ResultTable = ResultTable;
|
|
193
|
+
exports.Scatter = Scatter;
|
|
194
|
+
|
|
195
|
+
//# sourceMappingURL=TraceResults.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TraceResults.cjs","names":["_Fragment","niceStep","duration","shortOperation","Badge","ago","DataTable"],"sources":["../../../../src/data/traces/otel/TraceResults.tsx"],"sourcesContent":["import { ago, niceStep } from \"./result-model\";\nimport { Badge } from \"../../Badge\";\nimport { DataTable, type DataTableColumn, type DataTableProps } from \"../../DataTable\";\nimport { duration, type SearchResult, type Summary } from \"./api\";\nimport { shortOperation } from \"./query\";\n\nconst startMs = (trace: Summary) => Date.parse(trace.startedAt);\nconst clock = (ms: number) => new Date(ms).toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\", second: \"2-digit\" });\n\nexport function ResultSummary({ result }: { result: SearchResult }) {\n const shown = result.traces.length;\n return (\n <p className=\"text-sm text-muted-foreground\">\n <span className=\"font-medium text-foreground\">{shown}</span> {shown === 1 ? \"trace\" : \"traces\"}\n {shown < result.total\n ? <> · the {shown} newest of {result.total.toLocaleString()}. Narrow the window or operation to see older ones</>\n : <> · all in the window</>}\n </p>\n );\n}\n\n/** Each trace by when it started and how long it took, dot size by span count. */\nexport function Scatter({ traces, onOpen }: { traces: Summary[]; onOpen: (id: string) => void }) {\n const starts = traces.map(startMs);\n const t0 = Math.min(...starts);\n const span = Math.max(...starts) - t0;\n const slowest = Math.max(...traces.map(trace => trace.durationMs)) || 1;\n const step = niceStep(slowest, 4);\n const top = Math.ceil((slowest * 1.05) / step) * step;\n const yTicks = Array.from({ length: Math.round(top / step) + 1 }, (_, i) => i * step);\n // Traces that all started together sit mid-axis under one tick.\n const xTicks = span === 0 ? [0.5] : [0, 0.25, 0.5, 0.75, 1];\n const x = (ms: number) => (span === 0 ? 0.5 : (ms - t0) / span);\n return (\n <figure className=\"rounded-lg border border-border p-density-2\" aria-label=\"Duration over time\">\n <figcaption className=\"mb-1 flex items-center gap-3 text-xs text-muted-foreground\">\n <span className=\"font-medium text-foreground\">Duration over time</span>\n <span>dot size = span count · click to open</span>\n </figcaption>\n <div className=\"relative ml-[4.5rem] mr-2 mt-3.5 h-[180px]\">\n {yTicks.map(y => (\n <div key={y} className=\"absolute inset-x-0 border-t border-border/60\" style={{ bottom: `${(y / top) * 100}%` }}>\n <span className=\"absolute right-full -translate-y-1/2 whitespace-nowrap pr-1.5 text-xs tabular-nums text-muted-foreground\">{y === 0 ? \"0\" : duration(y)}</span>\n </div>\n ))}\n {traces.map(trace => {\n const size = 6 + Math.log2(trace.spanCount) * 1.6;\n const label = `${shortOperation(trace.operation)}, ${duration(trace.durationMs)}, ${trace.spanCount} spans at ${clock(startMs(trace))}`;\n return (\n <button\n key={trace.traceId}\n type=\"button\"\n aria-label={label}\n title={label}\n onClick={() => onOpen(trace.traceId)}\n className={`absolute -translate-x-1/2 translate-y-1/2 rounded-full opacity-75 hover:ring-2 hover:ring-ring ${trace.errors > 0 ? \"bg-destructive\" : trace.spanCount > 1 ? \"bg-primary\" : \"bg-muted-foreground\"}`}\n style={{ left: `${x(startMs(trace)) * 100}%`, bottom: `${(trace.durationMs / top) * 100}%`, width: size, height: size }}\n />\n );\n })}\n </div>\n <div className=\"relative ml-[4.5rem] mr-2 mt-1 h-4 text-xs tabular-nums text-muted-foreground\">\n {xTicks.map((fraction, i) => (\n <span key={fraction} className={`absolute whitespace-nowrap ${xTicks.length > 1 && i === 0 ? \"\" : xTicks.length > 1 && i === xTicks.length - 1 ? \"-translate-x-full\" : \"-translate-x-1/2\"}`} style={{ left: `${fraction * 100}%` }}>\n {clock(t0 + fraction * span)}\n </span>\n ))}\n </div>\n </figure>\n );\n}\n\n/** The traces, newest first: what ran, when, how long against the slowest, and its span count. */\nexport function ResultTable({ traces, href, onOpen, now, tableProps = {} }: { traces: Summary[]; href: (id: string) => string; onOpen: (id: string) => void; now: number; tableProps?: Pick<DataTableProps<Summary>, \"externalFilters\" | \"externalSearch\" | \"externalTimeRange\" | \"pagination\" | \"infinite\" | \"loading\"> }) {\n const slowest = Math.max(1, ...traces.map(trace => trace.durationMs));\n const columns: DataTableColumn<Summary>[] = [\n {\n key: \"operation\",\n label: \"Trace\",\n grow: true,\n minWidth: 320,\n render: (_, trace) => (\n <span className=\"flex min-w-0 items-center gap-2\" title={trace.operation}>\n <span className=\"shrink-0 font-medium\">{shortOperation(trace.operation) || trace.traceId}</span>\n <code className=\"text-xs text-muted-foreground\">{trace.traceId.slice(0, 8)}</code>\n {trace.services.length > 1 && <span className=\"truncate text-xs text-muted-foreground\">{trace.services.join(\" → \")}</span>}\n {trace.errors > 0 && <Badge size=\"sm\" tone=\"danger\" variant=\"soft\">{trace.errors} {trace.errors === 1 ? \"error\" : \"errors\"}</Badge>}\n </span>\n ),\n },\n {\n key: \"startedAt\",\n label: \"Started\",\n render: (_, trace) => <span className=\"whitespace-nowrap tabular-nums\">{clock(startMs(trace))} <span className=\"text-muted-foreground\">{ago(now - startMs(trace))}</span></span>,\n },\n {\n key: \"durationMs\",\n label: \"Duration\",\n render: (_, trace) => (\n <span className=\"flex items-center gap-2\">\n <span className=\"relative h-1.5 w-24 rounded-full bg-muted\">\n <span className=\"absolute inset-y-0 left-0 rounded-full bg-primary\" style={{ width: `${(trace.durationMs / slowest) * 100}%` }} />\n </span>\n <span className=\"tabular-nums\">{duration(trace.durationMs)}</span>\n </span>\n ),\n },\n { key: \"spanCount\", label: \"Spans\", align: \"right\" },\n ];\n return (\n <div className=\"flex h-[28rem] min-h-0 flex-col\">\n <DataTable\n {...tableProps}\n data={traces}\n columns={columns}\n getRowId={trace => trace.traceId}\n autoFilter={false}\n getRowHref={trace => href(trace.traceId)}\n onRowClick={trace => onOpen(trace.traceId)}\n emptyMessage=\"No traces match. Widen the time range, clear the duration or attribute filters, or show single-span traces.\"\n />\n </div>\n );\n}\n"],"mappings":"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"}
|