Skip to content

Commit

Permalink
Merge #97807
Browse files Browse the repository at this point in the history
97807: ui/tracez: display aggregated data on children spans r=benbardin a=benbardin

Return and display spans' children metadata on /debug/tracez page.

Release note: None
Informs: None

New children metadata table rendered:
<img width="1272" alt="Screenshot 2023-03-06 at 4 40 20 PM" src="https://user-images.githubusercontent.com/261508/223239091-75d904a6-d5b5-4df6-b503-97a9c3916ec9.png">
<img width="1273" alt="Screenshot 2023-03-06 at 4 40 14 PM" src="https://user-images.githubusercontent.com/261508/223239102-b77d1a77-0a0c-49d6-bd8d-f665633e633c.png">


No children metadata on this span, new section correctly omitted:
<img width="1112" alt="Screenshot 2023-02-28 at 2 34 50 PM" src="https://user-images.githubusercontent.com/261508/221961147-0698d478-f218-447c-805f-6312051dbed3.png">


Co-authored-by: Ben Bardin <[email protected]>
  • Loading branch information
craig[bot] and benbardin committed Mar 14, 2023
2 parents 0595b4a + fced789 commit 10c1e3e
Show file tree
Hide file tree
Showing 9 changed files with 257 additions and 72 deletions.
15 changes: 15 additions & 0 deletions docs/generated/http/full.md
Original file line number Diff line number Diff line change
Expand Up @@ -7258,6 +7258,7 @@ the tracing UI.
| processed_tags | [SpanTag](#cockroach.server.serverpb.GetTracingSnapshotResponse-cockroach.server.serverpb.SpanTag) | repeated | | [reserved](#support-status) |
| current | [bool](#cockroach.server.serverpb.GetTracingSnapshotResponse-bool) | | current is set if the span is still alive (i.e. still present in the active spans registry). | [reserved](#support-status) |
| current_recording_mode | [cockroach.util.tracing.tracingpb.RecordingMode](#cockroach.server.serverpb.GetTracingSnapshotResponse-cockroach.util.tracing.tracingpb.RecordingMode) | | current_recording_mode represents the span's current recording mode. This is not set if current == false. | [reserved](#support-status) |
| children_metadata | [NamedOperationMetadata](#cockroach.server.serverpb.GetTracingSnapshotResponse-cockroach.server.serverpb.NamedOperationMetadata) | repeated | | [reserved](#support-status) |



Expand Down Expand Up @@ -7301,6 +7302,20 @@ of the tracing UI.



<a name="cockroach.server.serverpb.GetTracingSnapshotResponse-cockroach.server.serverpb.NamedOperationMetadata"></a>
#### NamedOperationMetadata



| Field | Type | Label | Description | Support status |
| ----- | ---- | ----- | ----------- | -------------- |
| name | [string](#cockroach.server.serverpb.GetTracingSnapshotResponse-string) | | | [reserved](#support-status) |
| metadata | [cockroach.util.tracing.tracingpb.OperationMetadata](#cockroach.server.serverpb.GetTracingSnapshotResponse-cockroach.util.tracing.tracingpb.OperationMetadata) | | | [reserved](#support-status) |





<a name="cockroach.server.serverpb.GetTracingSnapshotResponse-cockroach.server.serverpb.TracingSnapshot.StacksEntry"></a>
#### TracingSnapshot.StacksEntry

Expand Down
15 changes: 13 additions & 2 deletions pkg/server/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -4197,8 +4197,18 @@ func (s *adminServer) GetTracingSnapshot(

for i, s := range spansList.Spans {
tags := make([]*serverpb.SpanTag, len(s.Tags))
for j, t := range s.Tags {
tags[j] = getSpanTag(t)
for j, tag := range s.Tags {
tags[j] = getSpanTag(tag)
}
childrenMetadata := make([]*serverpb.NamedOperationMetadata, len(s.ChildrenMetadata))

j := 0
for name, cm := range s.ChildrenMetadata {
childrenMetadata[j] = &serverpb.NamedOperationMetadata{
Name: name,
Metadata: cm,
}
j++
}

spans[i] = &serverpb.TracingSpan{
Expand All @@ -4211,6 +4221,7 @@ func (s *adminServer) GetTracingSnapshot(
ProcessedTags: tags,
Current: s.Current,
CurrentRecordingMode: s.CurrentRecordingMode.ToProto(),
ChildrenMetadata: childrenMetadata,
}
}

Expand Down
7 changes: 7 additions & 0 deletions pkg/server/serverpb/admin.proto
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import "roachpb/metadata.proto";
import "roachpb/data.proto";
import "ts/catalog/chart_catalog.proto";
import "util/metric/metric.proto";
import "util/tracing/tracingpb/recorded_span.proto";
import "gogoproto/gogo.proto";
import "google/api/annotations.proto";
import "google/protobuf/timestamp.proto";
Expand Down Expand Up @@ -1402,6 +1403,11 @@ message TracingSnapshot {
map<string, string> stacks = 4;
}

message NamedOperationMetadata {
string name = 1;
util.tracing.tracingpb.OperationMetadata metadata = 2 [(gogoproto.nullable) = false];
}

// TracingSpan represents a span, in a form slightly processed for the use of
// the tracing UI.
message TracingSpan {
Expand All @@ -1418,6 +1424,7 @@ message TracingSpan {
// current_recording_mode represents the span's current recording mode. This is
// not set if current == false.
util.tracing.tracingpb.RecordingMode current_recording_mode = 9;
repeated NamedOperationMetadata children_metadata = 10;
}

// SpanTag represents a tag on a tracing span, in a form processed for the use
Expand Down
2 changes: 2 additions & 0 deletions pkg/ui/workspaces/cluster-ui/src/api/tracezApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export type GetTracingSnapshotRequest =
export type GetTracingSnapshotResponse =
cockroach.server.serverpb.GetTracingSnapshotResponse;

export type NamedOperationMetadata =
cockroach.server.serverpb.INamedOperationMetadata;
export type Span = cockroach.server.serverpb.ITracingSpan;
export type Snapshot = cockroach.server.serverpb.ITracingSnapshot;

Expand Down
21 changes: 21 additions & 0 deletions pkg/ui/workspaces/cluster-ui/src/tracez/snapshot.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@
justify-content: right;
}

.metadata-icon-cell {
padding: 8px 4px 4px 0px;
margin: 0px;
display: flex;
justify-content: right;
}

.metadata-name-cell {
padding: 4px 0px 4px 0px; // For vertical, override default of 16px.
}

.table-cell-time {
padding: 4px 16px; // For vertical, override default of 16px.
display: flex;
Expand Down Expand Up @@ -106,6 +117,16 @@
padding-top: 1px;
}

.icon-hollow-green {
fill: none;
height: 10px;
width: 10px;
padding-top: 2px;
stroke: green;
stroke-width: 4px;
clip-path: circle(4px at 5px 6px);
}

.icon-gray {
fill: lightgray;
height: 10px;
Expand Down
161 changes: 98 additions & 63 deletions pkg/ui/workspaces/cluster-ui/src/tracez/snapshot/spanComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import "antd/lib/switch/style";
import Long from "long";
import { Button } from "src/button";
import { useHistory } from "react-router-dom";
import { SpanMetadataTable } from "./spanMetadataTable";

const cx = classNames.bind(styles);

Expand Down Expand Up @@ -60,6 +61,10 @@ const SpanStatus: React.FC<{
.finally(() => {
setRecordingInFlight(false);
});
// Objects in hook dependencies use referential equality, not value
// equality. To force a hook refresh on span, explicitly mark spanID. But,
// having done that, there's no need to include the span, as it's purely a
// function of that input.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [
nodeID,
Expand Down Expand Up @@ -108,8 +113,6 @@ const SpanStatus: React.FC<{

export const SpanComponent: React.FC<{
snapshot: GetTracingSnapshotResponse;
sort: SortSetting;
changeSortSetting: (_: SortSetting) => void;
spanDetailsURL: (_: Long) => string;
span: Span;

Expand All @@ -126,8 +129,6 @@ export const SpanComponent: React.FC<{
}> = props => {
const {
snapshot,
sort,
changeSortSetting,
span,
spanDetailsURL,
snapshotError,
Expand All @@ -139,11 +140,16 @@ export const SpanComponent: React.FC<{
const snapshotID = snapshot?.snapshot.snapshot_id;
const spans = snapshot?.snapshot.spans;
const spanID = span?.span_id;

const childFilteredSnapshot = useMemo(() => {
return {
...snapshot?.snapshot,
spans: spans?.filter(s => s.parent_span_id.equals(spanID)),
};
// Objects in hook dependencies use referential equality, not value
// equality. To force a hook refresh, explicitly mark nodeID, snapshotID,
// and spanID. But, having done that, there's no need to include the
// snapshot and spans, as they're purely a function of those inputs.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [nodeID, snapshotID, spanID]);

Expand All @@ -152,21 +158,37 @@ export const SpanComponent: React.FC<{
...snapshot?.snapshot,
spans: spans?.filter(s => s.span_id.equals(span.parent_span_id)),
};
// Objects in hook dependencies use referential equality, not value
// equality. To force a hook refresh, explicitly mark nodeID, snapshotID,
// and spanID. But, having done that, there's no need to include the
// snapshot and spans, as they're purely a function of those inputs.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [nodeID, snapshotID, spanID]);

const snapshotTime = useMemo(() => {
return TimestampToMoment(snapshot?.snapshot.captured_at);
// Objects in hook dependencies use referential equality, not value
// equality. To force a hook refresh, explicitly mark nodeID and
// snapshotID. But, having done that, there's no need to include the
// snapshot, as it's purely a function of those inputs.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [nodeID, snapshotID]);

const startTime = useMemo(
() => {
return TimestampToMoment(span?.start);
},
// Objects in hook dependencies use referential equality, not value
// equality. To force a hook refresh, explicitly mark nodeID, snapshotID
// and spanID. But, having done that, there's no need to include the
// span, as it's purely a function of those inputs.
// eslint-disable-next-line react-hooks/exhaustive-deps
[nodeID, snapshotID, spanID],
);
const [childSpanSortSetting, setChildSpanSortSetting] =
useState<SortSetting>();

const childrenMetadata = span?.children_metadata;

const history = useHistory();
return (
Expand All @@ -187,67 +209,80 @@ export const SpanComponent: React.FC<{
View Raw Trace
</Button>
</div>
<section className={cx("span-section", "span-snapshot-columns")}>
<div className={cx("span-snapshot-column")}>
<div className={cx("span-snapshot-key-value")}>
<div className={cx("span-snapshot-key")}>Snapshot Time (UTC)</div>
{snapshotTime.format("YYYY-MM-DD HH:mm:ss.SSS")}
</div>
<div className={cx("span-snapshot-key-value")}>
<div className={cx("span-snapshot-key")}>Start Time (UTC)</div>
{startTime.format("YYYY-MM-DD HH:mm:ss.SSS")}
</div>
<div className={cx("span-snapshot-key-value")}>
<div className={cx("span-snapshot-key")}>Duration</div>
{formatDurationHours(moment.duration(snapshotTime.diff(startTime)))}
</div>
<SpanStatus
span={span}
setTraceRecordingType={setTraceRecordingType}
nodeID={nodeID}
/>
</div>
<div>
<div className={cx("span-snapshot-key", "span-snapshot-key-value")}>
Tags
</div>
{span && <TagCell span={span} defaultExpanded={true} />}
</div>
</section>
{parentFilteredSnapshot.spans?.length > 0 && (
<section className={cx("span-section")}>
<h3 className={commonStyles("base-heading")}>Parent Span</h3>
<Loading
loading={snapshotLoading}
page={"snapshots"}
error={snapshotError}
render={() => (
<SpanTable
snapshot={parentFilteredSnapshot}
spanDetailsURL={spanDetailsURL}
/>

<Loading
loading={snapshotLoading}
page={"snapshots"}
error={snapshotError}
render={() => (
<div>
<section className={cx("span-section", "span-snapshot-columns")}>
<div className={cx("span-snapshot-column")}>
<div className={cx("span-snapshot-key-value")}>
<div className={cx("span-snapshot-key")}>
Snapshot Time (UTC)
</div>
{snapshotTime.format("YYYY-MM-DD HH:mm:ss.SSS")}
</div>
<div className={cx("span-snapshot-key-value")}>
<div className={cx("span-snapshot-key")}>
Start Time (UTC)
</div>
{startTime.format("YYYY-MM-DD HH:mm:ss.SSS")}
</div>
<div className={cx("span-snapshot-key-value")}>
<div className={cx("span-snapshot-key")}>Duration</div>
{formatDurationHours(
moment.duration(snapshotTime.diff(startTime)),
)}
</div>
<SpanStatus
span={span}
setTraceRecordingType={setTraceRecordingType}
nodeID={nodeID}
/>
</div>
<div>
<div
className={cx("span-snapshot-key", "span-snapshot-key-value")}
>
Tags
</div>
{span && <TagCell span={span} defaultExpanded={true} />}
</div>
</section>
{parentFilteredSnapshot.spans?.length > 0 && (
<section className={cx("span-section")}>
<h3 className={commonStyles("base-heading")}>Parent Span</h3>
<SpanTable
snapshot={parentFilteredSnapshot}
spanDetailsURL={spanDetailsURL}
/>
</section>
)}
/>
</section>
)}
{childFilteredSnapshot.spans?.length > 0 && (
<section className={cx("span-section")}>
<h3 className={commonStyles("base-heading")}>Child Spans</h3>
<Loading
loading={snapshotLoading}
page={"snapshots"}
error={snapshotError}
render={() => (
<SpanTable
snapshot={childFilteredSnapshot}
setSort={changeSortSetting}
sort={sort}
spanDetailsURL={spanDetailsURL}
/>
{childrenMetadata?.length > 0 && (
<section className={cx("span-section")}>
<h3 className={commonStyles("base-heading")}>
Aggregated Child Span Metadata
</h3>

<SpanMetadataTable childrenMetadata={childrenMetadata} />
</section>
)}
/>
</section>
)}
{childFilteredSnapshot.spans?.length > 0 && (
<section className={cx("span-section")}>
<h3 className={commonStyles("base-heading")}>Child Spans</h3>
<SpanTable
snapshot={childFilteredSnapshot}
setSort={setChildSpanSortSetting}
sort={childSpanSortSetting}
spanDetailsURL={spanDetailsURL}
/>
</section>
)}
</div>
)}
/>
<div className={cx("bottom-padding")} />
</div>
);
Expand Down
Loading

0 comments on commit 10c1e3e

Please sign in to comment.