Skip to content

feat(traces): one trace link form, ?traceId=&traceType=<trace source> - #205

Merged
wu-sheng merged 1 commit into
mainfrom
feat/trace-popout-store
Oct 22, 2026
Merged

wu-sheng merged 1 commit into
mainfrom
feat/trace-popout-store

Conversation

@wu-sheng

@wu-sheng wu-sheng commented Oct 22, 2026 •

Copy link
Copy Markdown
Member

Why

A trace could be linked four different ways — ?traceId= with a page-decided popout, &source=native|zipkin from the copy buttons, &traceType=SKYWALKING_NATIVE|OTLP markers (where OTLP meant the Zipkin popout), and ?traceqlId=&ds= for TraceQL — plus ?evaluationTraceId= on the Evaluation records tab. A link without a marker opened in whatever popout the page guessed, so a trace could be read from a store it is not in and shown as empty. This makes one form for every trace link, names the query that reads it, and stops guessing.

What

One link form: ?traceId=<id>&traceType=<source>. The source is one of the names a layer template's traces.sources already uses, and says which OAP query reads the trace: native (native trace query), zipkin (Zipkin query API), traceql-native / traceql-zipkin / traceql-otlp (TraceQL over that datasource). Span keys (traceSegmentId, traceSpanIndex, traceSpanId) and the window keys (traceAt, traceEnd, traceLookback) are unchanged.

Where Before Now
Native trace card ⧉ url (Traces tab, Trace inspect) traceId=X&source=native traceId=X&traceType=native
Zipkin trace card ⧉ url …&source=zipkin&traceAt=T …&traceType=zipkin&traceAt=T
TraceQL card ⧉ url traceqlId=X&ds=D traceId=X&traceType=traceql-D
Evaluation records row trace link SKYWALKING_NATIVE / OTLP (Zipkin) / traceqlId=X&ds=otlp&traceqlSpanId=S native / zipkin / traceId=X&traceType=traceql-otlp&traceSpanId=S
Record list trace icon SKYWALKING_NATIVE / OTLP / traceqlId&ds / no store: bare id the widget's own recordTrace.source / no store: bare id
Span detail cross-trace ref traceId=X traceId=X&traceType=native
Log rows (Logs, Log inspect, AI chat logs) traceId=X&traceAt=T traceId=X&traceType=<the page's source>&traceAt=T
Evaluation records trace condition ?evaluationTraceId=X, written as you type read once from a trace link when the page opens or moves to another group
  • Each popout opens only for its own source. A link with no traceType, or a value outside the five, opens a notice (TraceLinkNotice) that shows the id and the bad value and offers one button per source; the button sets traceType on the same link. Nothing falls back to a page default any more.
  • A dashboard record list with no recordTrace — the bundled General, MySQL, PostgreSQL, Redis, Virtual Database and Virtual Cache lists among them — now opens that notice instead of the layer's popout. Bundled templates are untouched; the 1.1.0 changelog carries a Breaking entry with how to set the store.
  • An id a Zipkin source cannot hold (a SkyWalking id with dashes, say) reads No trace with that id. at once in the TraceQL and Zipkin popouts and Pick span…, instead of The trace source is not answering. or a failed request. The BFF decides it with Zipkin's own id rule (normalizeZipkinTraceId, mirroring OAP's Span.normalizeTraceId) before asking OAP — the Zipkin trace route and the TraceQL zipkin datasource only — and answers notFound + invalidId; a 400 OAP itself returns stays a failure.
  • Fix: a native span's cross-trace ref on a Zipkin page now stays native.
  • Layer dashboard editor fix. Save dropped empty grids of scopes no page renders, even when the template began with them. General Service and Istio Managed SVCs ship such grids, so Reset to bundled → Save wrote OAP's copy back: Check diff & push stayed disabled while the sidebar marked the layer diverged. Save now keeps an empty grid the template began with and drops only one the edit created; a new test holds every bundled layer template to "Reset to bundled, Save, unchanged".
  • Docs: operate/traces.md, operate/genai-evaluation.md, components/dashboard-widgets.md, customization/layer-templates.md; 1.1.0 changelog; new notice strings in all 8 locales.

e2e

  • genai: URL checks use the new values; the trace-condition spec opens the tab from a trace link, closes the popout, and checks the condition was filled.
  • ui/trace-deeplink: names the source, and adds bare id → notice → pick native → waterfall.
  • istio/zipkin-traces: names zipkin. ui/popouts: a log-row link names native.
  • The e2e cases run on ubuntu-24.04. ubuntu-latest is moving to 26.04 (Oct 19 – Nov 19, 2026), where kind cannot load the multi-platform OAP image into its node (ctr images import --all-platforms: content digest not found), so the kind cases (istio, deployment) failed before any test ran; the compose cases pass on either image. 24.04 stays supported while it is one of the two latest images.

Validation

  • pnpm -r run type-check, UI and BFF builds, pnpm lint (repo-wide gate: i18n parity, docs links, source budget, design tokens, security, template + i18n validation), e2e spec type-check, license headers — green. pnpm -r run test:unit: api-client 201, conversation-view 163, BFF 2178, UI 1627.
  • Live, against the public demo OAP (no proxy): the notice for a missing / unknown type; the chooser opening a native trace (61 spans) from a stored Virtual Database record list; No trace with that id. for a SkyWalking id asked of zipkin and traceql-zipkin; copy buttons on Trace inspect writing and reopening the new form; Istio Managed SVCs Reset to bundled → Save enabling Check diff & push (not pushed).
  • Earlier in the work, the genai browser specs passed 9/9 against the local e2e stack. Not re-run on the final commit: the local Docker engine stopped answering, so the e2e cases are left to CI.
  • Reviewed with Codex (gpt-6-astra, max) over several rounds, including whole-change impact evaluations; findings fixed, final review clean.

@wu-sheng wu-sheng added this to the 1.1.0 milestone Oct 22, 2026
@wu-sheng wu-sheng added bug Something isn't working enhancement New feature or request labels Oct 22, 2026
wankai123
wankai123 previously approved these changes Oct 22, 2026
Every trace link is `?traceId=<id>&traceType=<source>`, where the source is
one of the names a layer template's `traces.sources` uses — native, zipkin,
traceql-native, traceql-zipkin, traceql-otlp — and names the OAP query that
reads the trace. Each popout opens only for its own source; a link naming
none, or an unknown one, opens a notice that offers each source to query.
`source=`, `traceqlId`/`ds`/`traceqlSpanId`, `evaluationTraceId` and the old
`traceType=SKYWALKING_NATIVE|OTLP` markers are gone.

- Copy buttons, evaluation records, record lists, span refs and log rows all
  write the new form; log rows name the source of the page's own traces.
- The Evaluation records tab reads its trace condition from a trace link once,
  when the page opens or moves to another group, and no longer writes it.
- An id a Zipkin source cannot hold reads "No trace with that id." at once,
  in both popouts and Pick span…, instead of a failed request or "The trace
  source is not answering."; the BFF checks it by Zipkin's id rule before
  asking OAP, so a real OAP 400 stays a failure.
- Layer dashboard editor: Save keeps an empty grid the template began with,
  so Reset to bundled, then Save, writes the bundled template and Check diff &
  push can publish it; a test holds every bundled layer template to that.

- CI: the e2e cases run on ubuntu-24.04. ubuntu-latest is moving to 26.04,
  where kind cannot load the multi-platform OAP image into its node, so the
  kind cases (istio, deployment) failed before any test ran.
@wu-sheng
wu-sheng force-pushed the feat/trace-popout-store branch from 3bd4892 to 3831847 Compare October 22, 2026 13:49
@wu-sheng
wu-sheng merged commit ed6171d into main Oct 22, 2026
15 checks passed
@wu-sheng
wu-sheng deleted the feat/trace-popout-store branch October 22, 2026 23:18
wu-sheng added a commit that referenced this pull request Oct 23, 2026
…ages per platform

Docker 29 (ubuntu-26.04 runners) uses the containerd image store, where a
pulled multi-platform image holds only the host platform; importing every
platform into kind failed for the OAP image ("content digest ... not
found") and, on the containerd 1.7 kindest/node:v1.28.15 these cases pin,
for the Rover image, whose attestation manifests do not unpack as images
("mismatched image rootfs and manifest layers"). infra-e2e now saves and
imports only the node platform (apache/skywalking-infra-e2e#150, #151), so
the e2e cases follow ubuntu-latest again instead of the ubuntu-24.04 pin
#205 added.
wu-sheng added a commit that referenced this pull request Oct 23, 2026
…ages per platform

Docker 29 (ubuntu-26.04 runners) uses the containerd image store, where a
pulled multi-platform image holds only the host platform; importing every
platform into kind failed for the OAP image ("content digest ... not
found") and, on the containerd 1.7 kindest/node:v1.28.15 these cases pin,
for the Rover image, whose attestation manifests do not unpack as images
("mismatched image rootfs and manifest layers"). infra-e2e now saves only the node platform and leaves attestation
manifests out of the archive (apache/skywalking-infra-e2e#150, #151), so
the e2e cases follow ubuntu-latest again instead of the ubuntu-24.04 pin
#205 added.
wu-sheng added a commit that referenced this pull request Oct 23, 2026
…ages per platform

Docker 29 (ubuntu-26.04 runners) uses the containerd image store, where a
pulled multi-platform image holds only the host platform; importing every
platform into kind failed for the OAP image ("content digest ... not
found"). Saved for one platform, the archive also lists the image's
referrers, such as attestations, at its top level, and the containerd 1.7
kindest/node:v1.28.15 these cases pin imports each one as an image, which
failed for the Rover image ("mismatched image rootfs and manifest layers").
infra-e2e now saves only the node platform and leaves the referrers out of
the archive (apache/skywalking-infra-e2e#150, #151), so the e2e cases follow
ubuntu-latest again instead of the ubuntu-24.04 pin #205 added.
wu-sheng added a commit that referenced this pull request Oct 23, 2026
…ages per platform

Docker 29 (ubuntu-26.04 runners) uses the containerd image store, where a
pulled multi-platform image holds only the host platform; importing every
platform into kind failed for the OAP image ("content digest ... not
found"). Saved for one platform, the archive also lists the image's
referrers, such as attestations, at its top level, and the containerd 1.7
kindest/node:v1.28.15 these cases pin imports each one as an image, which
failed for the Rover image ("mismatched image rootfs and manifest layers").
infra-e2e now saves only the node platform and leaves the referrers out of
the archive (apache/skywalking-infra-e2e#150, #151), so the e2e cases follow
ubuntu-latest again instead of the ubuntu-24.04 pin #205 added.
wu-sheng added a commit that referenced this pull request Oct 23, 2026
…ges per platform

Docker 29 (ubuntu-26.04 runners) uses the containerd image store, where a
pulled multi-platform image holds only the host platform; importing every
platform into kind failed for the OAP image ("content digest ... not
found"). Saved for one platform, the archive also lists the image's
referrers, such as attestations, at its top level, and the containerd 1.7
kindest/node:v1.28.15 these cases pin imports each one as an image, which
failed for the Rover image ("mismatched image rootfs and manifest layers").
infra-e2e now saves only the node platform and leaves the referrers out of
the archive (apache/skywalking-infra-e2e#150, #151), so the e2e cases leave
the ubuntu-24.04 pin #205 added.

The CI and e2e jobs name ubuntu-26.04 rather than ubuntu-latest:
ubuntu-latest jobs sat queued with no runner while jobs naming ubuntu-24.04
or ubuntu-26.04 started within seconds.
wu-sheng added a commit that referenced this pull request Oct 23, 2026
…ges per platform

Docker 29 (ubuntu-26.04 runners) uses the containerd image store, where a
pulled multi-platform image holds only the host platform; importing every
platform into kind failed for the OAP image ("content digest ... not
found"). Saved for one platform, the archive also lists the image's
referrers, such as attestations, at its top level, and the containerd 1.7
kindest/node:v1.28.15 these cases pin imports each one as an image, which
failed for the Rover image ("mismatched image rootfs and manifest layers").
infra-e2e now saves only the node platform and leaves the referrers out of
the archive (apache/skywalking-infra-e2e#150, #151), so the e2e cases leave
the ubuntu-24.04 pin #205 added.

The CI and e2e jobs name ubuntu-26.04 rather than ubuntu-latest:
ubuntu-latest jobs sat queued with no runner while jobs naming ubuntu-24.04
or ubuntu-26.04 started within seconds.

The istio mesh spec accepts `UNKNOWN` as the service the MESH header opens
on. Since the e2e OAP pin moved past apache/skywalking#14135 (#204), OAP
reads the Kubernetes metadata of a new pod address in the background, so
bookinfo's first calls count under `UNKNOWN`; in the first minute of traffic
that burst can rank first by calls per minute, and the header then picks
it. It failed so on main at ed6171d (ubuntu-24.04) as well as here.
wu-sheng added a commit that referenced this pull request Oct 23, 2026
…ges per platform

Docker 29 (ubuntu-26.04 runners) uses the containerd image store, where a
pulled multi-platform image holds only the host platform; importing every
platform into kind failed for the OAP image ("content digest ... not
found"). Saved for one platform, the archive also lists the image's
referrers, such as attestations, at its top level, and the containerd 1.7
kindest/node:v1.28.15 these cases pin imports each one as an image, which
failed for the Rover image ("mismatched image rootfs and manifest layers").
infra-e2e now saves only the node platform and leaves the referrers out of
the archive (apache/skywalking-infra-e2e#150, #151), so the e2e cases leave
the ubuntu-24.04 pin #205 added.

The CI and e2e jobs name ubuntu-26.04 rather than ubuntu-latest:
ubuntu-latest jobs sat queued with no runner while jobs naming ubuntu-24.04
or ubuntu-26.04 started within seconds.

The istio mesh and eBPF profiling specs accept `UNKNOWN` as the service
the MESH header opens on (MESH_HEADER_SERVICES; MESH_SERVICES still lists
only the real workloads). Since the e2e OAP pin moved past
apache/skywalking#14135 (#204), OAP reads the Kubernetes metadata of a new
pod address in the background, so bookinfo's first calls count under
`UNKNOWN`; in the first minute of traffic that burst can rank first by
calls per minute, and the header then picks it. It failed so on main at
ed6171d (ubuntu-24.04) as well as here. A mesh whose calls all count
under `UNKNOWN` still fails: the mesh spec requires every bookinfo peer in
the service picker.
wu-sheng added a commit that referenced this pull request Oct 23, 2026
…ges per platform

Docker 29 (ubuntu-26.04 runners) uses the containerd image store, where a
pulled multi-platform image holds only the host platform; importing every
platform into kind failed for the OAP image ("content digest ... not
found"). Saved for one platform, the archive also lists the image's
referrers, such as attestations, at its top level, and the containerd 1.7
kindest/node:v1.28.15 these cases pin imports each one as an image, which
failed for the Rover image ("mismatched image rootfs and manifest layers").
infra-e2e now saves only the node platform and leaves the referrers out of
the archive (apache/skywalking-infra-e2e#150, #151), so the e2e cases leave
the ubuntu-24.04 pin #205 added.

The CI and e2e jobs name ubuntu-26.04 rather than ubuntu-latest:
ubuntu-latest jobs sat queued with no runner while jobs naming ubuntu-24.04
or ubuntu-26.04 started within seconds.

The istio mesh fixture is fully known, so its specs now require all of it
and accept only `UNKNOWN` beyond it. The mesh spec asserts the service
picker lists exactly the five workloads (bookinfo's four and the ingress
gateway) plus, optionally, `UNKNOWN`; the topology spec requires a node for
each workload by name; and the roster readiness check waits until Horizon
lists all five. MESH_PEERS, which left `ratings` out, is gone.

`UNKNOWN` is accepted as the service the MESH header opens on
(MESH_HEADER_SERVICES, in the mesh and eBPF profiling specs). Since the e2e
OAP pin moved past apache/skywalking#14135 (#204), OAP reads the Kubernetes
metadata of a new pod address in the background, so bookinfo's first calls
count under `UNKNOWN`; in the first minute of traffic that burst can rank
first by calls per minute, and the header then picks it. It failed so on
main at ed6171d (ubuntu-24.04) as well as here.
wu-sheng added a commit that referenced this pull request Oct 23, 2026
…ges per platform

Docker 29 (ubuntu-26.04 runners) uses the containerd image store, where a
pulled multi-platform image holds only the host platform; importing every
platform into kind failed for the OAP image ("content digest ... not
found"). Saved for one platform, the archive also lists the image's
referrers, such as attestations, at its top level, and the containerd 1.7
kindest/node:v1.28.15 these cases pin imports each one as an image, which
failed for the Rover image ("mismatched image rootfs and manifest layers").
infra-e2e now saves only the node platform and leaves the referrers out of
the archive (apache/skywalking-infra-e2e#150, #151), so the e2e cases leave
the ubuntu-24.04 pin #205 added.

The CI and e2e jobs name ubuntu-26.04 rather than ubuntu-latest:
ubuntu-latest jobs sat queued with no runner while jobs naming ubuntu-24.04
or ubuntu-26.04 started within seconds.

The istio mesh fixture is fully known, so its specs now require all of it
and accept only `UNKNOWN` beyond it. The mesh spec asserts the service
picker lists exactly the five workloads (bookinfo's four and the ingress
gateway) plus, optionally, `UNKNOWN`; the topology spec requires a node for
each workload by name; and the roster readiness check waits until Horizon
lists all five. MESH_PEERS, which left `ratings` out, is gone.

`UNKNOWN` is accepted as the service the MESH header opens on
(MESH_HEADER_SERVICES, in the mesh and eBPF profiling specs). Since the e2e
OAP pin moved past apache/skywalking#14135 (#204), OAP reads the Kubernetes
metadata of a new pod address in the background, so bookinfo's first calls
count under `UNKNOWN`; in the first minute of traffic that burst can rank
first by calls per minute, and the header then picks it. It failed so on
main at ed6171d (ubuntu-24.04) as well as here.
wu-sheng added a commit that referenced this pull request Oct 23, 2026
…ges per platform (#206)

Docker 29 (ubuntu-26.04 runners) uses the containerd image store, where a
pulled multi-platform image holds only the host platform; importing every
platform into kind failed for the OAP image ("content digest ... not
found"). Saved for one platform, the archive also lists the image's
referrers, such as attestations, at its top level, and the containerd 1.7
kindest/node:v1.28.15 these cases pin imports each one as an image, which
failed for the Rover image ("mismatched image rootfs and manifest layers").
infra-e2e now saves only the node platform and leaves the referrers out of
the archive (apache/skywalking-infra-e2e#150, #151), so the e2e cases leave
the ubuntu-24.04 pin #205 added.

The CI and e2e jobs name ubuntu-26.04 rather than ubuntu-latest:
ubuntu-latest jobs sat queued with no runner while jobs naming ubuntu-24.04
or ubuntu-26.04 started within seconds.

The istio mesh fixture is fully known, so its specs now require all of it
and accept only `UNKNOWN` beyond it. The mesh spec asserts the service
picker lists exactly the five workloads (bookinfo's four and the ingress
gateway) plus, optionally, `UNKNOWN`; the topology spec requires a node for
each workload by name; and the roster readiness check waits until Horizon
lists all five. MESH_PEERS, which left `ratings` out, is gone.

`UNKNOWN` is accepted as the service the MESH header opens on
(MESH_HEADER_SERVICES, in the mesh and eBPF profiling specs). Since the e2e
OAP pin moved past apache/skywalking#14135 (#204), OAP reads the Kubernetes
metadata of a new pod address in the background, so bookinfo's first calls
count under `UNKNOWN`; in the first minute of traffic that burst can rank
first by calls per minute, and the header then picks it. It failed so on
main at ed6171d (ubuntu-24.04) as well as here.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants