Skip to content

Support cold stage in the Zipkin query API #14045

Description

@wu-sheng

Search before asking

  • I had searched in the issues and found no similar feature requirement.

Description

The Zipkin query API has no way to ask for the cold stage, so Zipkin traces cannot be read once they have aged out of hot+warm — even on a deployment where zipkinTrace has a cold stage configured and the data is demonstrably there.

The native query protocol has carried Duration.coldStage since BanyanDB's lifecycle stages landed, and bydb.yml exposes enableColdStage for the zipkinTrace group alongside trace, recordsLog and the metrics tiers. So the storage side is complete: Zipkin spans migrate into the cold stage exactly like native traces. Only the query surface is missing.

The practical effect is that a deployment ageing Zipkin traces into cold storage can write them and never read them back. For a UI it is worse than a gap, because the two trace sources answer differently under the same switch: a "cold only" selection returns cold native traces beside hot Zipkin traces, with nothing to indicate that one of the two ignored the request.

Use case

An operator investigating an incident older than the hot+warm window switches their UI to cold-stage reads. Native traces answer from cold. Zipkin traces answer from hot — which for that window is empty, or worse, is a different set of traces than the ones being compared against.

Apache SkyWalking Horizon UI (apache/skywalking-horizon-ui) exposes a cold-stage toggle that maps onto Duration.coldStage. Because the Zipkin branch cannot carry the flag, the UI has to either exclude the Zipkin trace source from the toggle — which makes the feature inconsistent between two views of the same concept — or show hot Zipkin results under a cold-only label. Neither is good, and both are worked around rather than solved.

Proposal

Add an optional coldStage query parameter to the Zipkin query endpoints, defaulting to false.

GET /api/v2/traces?...&coldStage=true
GET /api/v2/trace/{traceId}?coldStage=true
GET /api/v2/traceMany?traceIds=...&coldStage=true
GET /api/v2/autocompleteKeys?coldStage=true
GET /api/v2/autocompleteValues?key=...&coldStage=true

Why this shape:

  • Same name as the native protocol. The query-protocol field is Duration.coldStage; keeping the name identical means one term for one concept across both query surfaces, which matters for documentation, for translations, and for anyone grepping.

  • Compatible with Zipkin clients by construction. The parameter is not part of the Zipkin OpenAPI spec, so no existing client sends it, and the default preserves today's behaviour exactly. A server that ignores an unknown parameter and a server that defaults it to false are indistinguishable to those clients.

  • It reaches the existing plumbing. ZipkinQueryHandler already builds a Duration for every one of these endpoints before delegating to ZipkinQueryService — for example in getTraces:

    Duration duration = new Duration();
    duration.setStep(Step.SECOND);
    duration.setStart(startTime.toString("yyyy-MM-dd HHmmss"));
    duration.setEnd(endTime.toString("yyyy-MM-dd HHmmss"));
    List<List<Span>> traces = zipkinQueryService.getTraces(queryRequest, duration);

    so the change is to accept the parameter and call duration.setColdStage(...) on the object that already exists. No new plumbing, and non-BanyanDB storage keeps ignoring the resulting flag as it does today.

Two points worth settling in review:

  1. Which endpoints take it. The trace reads clearly should. The two autocomplete endpoints also build a Duration, so they can — though tag keys and values may be considered stage-independent, in which case leaving them hot is a defensible answer as long as it is deliberate rather than accidental.
  2. Behaviour when the group has no cold stage. The native protocol returns empty, which is consistent and honest; the Zipkin endpoints should do the same rather than silently falling back to hot, since a silent fallback is precisely what makes the current situation hard to diagnose.

Related code

  • oap-server/server-query-plugin/zipkin-query-plugin/src/main/java/org/apache/skywalking/oap/query/zipkin/handler/ZipkinQueryHandler.java
  • oap-server/server-starter/src/main/resources/bydb.yml — the zipkinTrace group and its enableColdStage

Are you willing to submit a pull request to implement this on your own?

  • Yes I am willing to submit a pull request on my own!

Metadata

Metadata

Assignees

Labels

backendOAP backend related.featureNew featuretracingDistributed tracing

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions