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]

Reply via email to