fix(otel): show workbench api spans in trace summary (#795)
Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
@@ -823,15 +823,17 @@ function renderTraceTable(input: {
|
||||
? [...asArray(input.result.errorSpans), ...asArray(input.result.spans)]
|
||||
: asArray(input.result.spans);
|
||||
const spanRows = uniqueSpanRecords(spanSource)
|
||||
.sort((left, right) => traceSpanImportanceScore(right) - traceSpanImportanceScore(left))
|
||||
.slice(0, 10)
|
||||
.map((span) => {
|
||||
const attrs = asPlainRecord(span.attributes);
|
||||
const durationMs = traceSpanDurationMs(span, attrs);
|
||||
return [
|
||||
shortenEnd(textValue(span.name), 40),
|
||||
shortenEnd(textValue(span.service), 22),
|
||||
shortenEnd(spanColumnAttr(attrs, ["http.route", "workbench.ui.route"]), 34),
|
||||
spanColumnAttr(attrs, ["http.response.status_code", "http.status_code", "http.response.status_class"]),
|
||||
spanColumnAttr(attrs, ["workbench.ui.value_ms"]),
|
||||
numberValue(durationMs),
|
||||
spanColumnAttr(attrs, ["workbench.ui.resource_duration_ms"]),
|
||||
spanColumnAttr(attrs, ["workbench.ui.resource_fetch_to_request_ms"]),
|
||||
spanColumnAttr(attrs, ["workbench.ui.resource_request_wait_ms"]),
|
||||
@@ -865,7 +867,7 @@ function renderTraceTable(input: {
|
||||
formatTable(["FIELD", "VALUE"], identityRows.length > 0 ? identityRows : [["-", "-"]]),
|
||||
"",
|
||||
"Key spans:",
|
||||
formatTable(["NAME", "SERVICE", "ROUTE", "STATUS", "VALUE_MS", "RES_MS", "FETCH_REQ", "REQ_WAIT", "RESP_XFER", "PROTO", "DETAIL"], spanRows.length > 0 ? spanRows : [["-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-"]]),
|
||||
formatTable(["NAME", "SERVICE", "ROUTE", "STATUS", "DUR_MS", "RES_MS", "FETCH_REQ", "REQ_WAIT", "RESP_XFER", "PROTO", "DETAIL"], spanRows.length > 0 ? spanRows : [["-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-"]]),
|
||||
"",
|
||||
"Span name counts:",
|
||||
formatTable(["NAME", "COUNT"], countRows.length > 0 ? countRows : [["-", "-"]]),
|
||||
@@ -1023,6 +1025,29 @@ function renderDiagnoseCodeAgentTable(input: {
|
||||
};
|
||||
}
|
||||
|
||||
function traceSpanDurationMs(span: Record<string, unknown>, attrs: Record<string, unknown> | null): number {
|
||||
const topLevel = numberFromUnknown(span.durationMs);
|
||||
if (Number.isFinite(topLevel)) return topLevel;
|
||||
if (attrs === null) return Number.NaN;
|
||||
for (const key of ["workbench.ui.value_ms", "workbench.ui.resource_duration_ms", "durationMs"]) {
|
||||
const value = numberFromUnknown(attrs[key]);
|
||||
if (Number.isFinite(value)) return value;
|
||||
}
|
||||
return Number.NaN;
|
||||
}
|
||||
|
||||
function traceSpanImportanceScore(span: Record<string, unknown>): number {
|
||||
const attrs = asPlainRecord(span.attributes);
|
||||
const statusCode = textValue(span.statusCode);
|
||||
const name = textValue(span.name).toLowerCase();
|
||||
const hasFailure = spanColumnAttr(attrs, ["failureKind", "errorSummary", "error.message", "exception.message"]) !== "-";
|
||||
const terminalStatus = spanColumnAttr(attrs, ["terminalStatus"]);
|
||||
const problemScore = statusCode === "STATUS_CODE_ERROR" || statusCode === "2" || name.includes("error") || hasFailure || terminalStatus === "failed" || terminalStatus === "blocked" ? 1_000_000_000 : 0;
|
||||
const durationMs = traceSpanDurationMs(span, attrs);
|
||||
const durationScore = Number.isFinite(durationMs) ? durationMs : 0;
|
||||
return problemScore + durationScore;
|
||||
}
|
||||
|
||||
function searchTraceStatus(trace: Record<string, unknown>): string {
|
||||
if (trace.queryOk === false) return "query-bad";
|
||||
if (trace.parseOk === false) return "parse-bad";
|
||||
@@ -2297,7 +2322,7 @@ for batch in batches_from_body(parsed):
|
||||
error_spans.append(item)
|
||||
if matched:
|
||||
matched_spans.append(item)
|
||||
if error or name in IMPORTANT_NAMES or name.startswith("runner_error.") or name.startswith("runner_terminal."):
|
||||
if error or name in IMPORTANT_NAMES or name.startswith("runner_error.") or name.startswith("runner_terminal.") or name.startswith("workbench.api_request."):
|
||||
signature = key_signature(item)
|
||||
if signature not in seen_key_spans:
|
||||
seen_key_spans.add(signature)
|
||||
|
||||
Reference in New Issue
Block a user