wu-sheng opened a new pull request, #101:
URL: https://github.com/apache/skywalking-horizon-ui/pull/101
## Why
The AI assistant's ask → approval profiling workflow is ours; the profiling
**rules** are OAP's, and they differ across OAP versions, agents and storage
backends. We had mirrored several of those rules on our side and turned them
into hard refusals — so operators were blocked from tasks their backend would
have accepted, with a message that blamed the deployment for what was really
Horizon configuration.
Separately, Horizon could already display the results of *auto-triggered*
profiling tasks but had no way to see or change the policies behind them, even
though OAP has exposed that API all along.
## What
**1 — Horizon-invented refusals became caveats.** Checked against OAP's
create paths, none of these is something OAP validates: no profiling create
takes a layer argument, none consults the instance's runtime language, and
`createEBPFProfilingFixedTimeTask` never runs the `couldProfiling` query we
gated on. The layer-template gate, the eBPF readiness gate, the JVM/Go language
gate and the 30-minute network process probe now ride back as caveats the
assistant must relay before approval. The card is shown; OAP gets to be the one
that refuses, and its rejection ("The instance doesn't have processes.") is
both accurate and actionable where ours was a guess.
**2 — Rules we had outright wrong.** pprof duration is **minutes capped at
15**, not the 600 "seconds" we bounded it by (40× too loose, failing after
approval). eBPF has a 60s minimum we never enforced. Network tasks are fixed at
10 minutes and take no duration, so any proposed window was fiction. async has
no server-side cap, so its 10-minute clamp is gone. Over-cap instance lists now
fail with a reason instead of silently profiling 32 of 40 while the card
advertised the fleet.
**3 — Reading results the way OAP reports them.** Analyzing a task right
after approving it — the obvious thing to do — used to answer *"ran but
produced no analyzable stacks, do not retry"*, because any progress log counted
as finished; `NOTIFIED` only means *issued to the agent*. Still-collecting,
finished-empty and agent-failed are now three different answers. Also: OFF_CPU
was aggregated by `COUNT` (scheduler switch count) where `DURATION` is time
blocked — inverting the answer for the one target you pick to find blocking;
ALLOC profiles read only the in-TLAB half; multi-event tasks rendered only the
first event; the network graph read at HOUR/DAY step against minute-only
metrics; trace analysis issued one query per *span* where OAP marks `profiled`
per *segment*; and task `startTime` was the browser wall clock, which OAP only
dispatches within ±5 min of its own.
**4 — New: Operate → Continuous profiling.** Arm a policy once and OAP
starts the profiling task itself when a process crosses a threshold. Pick a
layer + service, edit targets (`ON_CPU` / `OFF_CPU` / `NETWORK`) with
conditions of monitor type / threshold / period / count, plus a URI list or
regex for the HTTP monitors. A **Monitored instances** panel shows what OAP is
actually evaluating — a stored policy matching nothing otherwise looks
identical to a working one. Saving replaces the service's whole policy, because
that is how OAP stores it, so the button says "Replace policy". Reads need
`profile:read`, saving needs `profile:enable`.
## Validation
Against a **local SkyWalking e2e OAP** (`profiling/trace/banyandb` + Java
agent), not mocks:
- trace propose → approve → analyze end-to-end; the approved task's id is
what the analysis reads, proven by a negative control (a second, empty task
analyzed by id returns its own facts, not the populated task's flame).
- The three paths that previously refused (pprof on a Java service, eBPF
with no Rover, network on a layer omitting it) now emit a card with the caveat
relayed; approving the network card surfaces OAP's own rejection.
- A trace create with no `startTime` is accepted and OAP stamps the task
with its own clock.
- A mid-flight task reports "still collecting" (logs: `NOTIFIED`) where it
previously said it found nothing.
- Continuous profiling: policy write returns `status:true` and reads back
byte-identical including the `uriRegex`. This caught a real wire bug — OAP's
schema names the field `targetType` on the mutation input but `type` on the
query output, so posting a read policy straight back fails; the BFF renames on
the way out.
- The public demo has **no** continuous-profiling policy on any of its 59
services, so it exercises the empty state only.
Green: `type-check`, `build-ui`, `build-bff`, `lint`, `license:check`,
`i18n:validate`, 229 BFF + 143 UI unit tests. New UI strings are translated in
all 8 locales.
## Notes for review
Three audit findings were deliberately **not** acted on, as they need an
upstream decision rather than a UI change: OAP's `ProfileStack` equality is
`sequence`-only with no segmentId (cross-segment stacks can still collapse);
network task ordering on JDBC backends; and BanyanDB's ~10-minute
segment-retrieval limit versus the 15-minute trace window OAP itself allows —
capping our window to 10 would hardcode one backend's limit into the UI, which
is the mistake this PR is undoing.
Continuous-profiling *tasks* remain out of the assistant's analyze path on
purpose: they are auto-triggered by policy, so folding them into "analyze the
task you approved" would conflate two different things.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]