This is an automated email from the ASF dual-hosted git repository.
wu-sheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-website.git
The following commit(s) were added to refs/heads/master by this push:
new 8badf78edc6 Blog: Meet Horizon UI 9/17 — Five Profilers, One Flame
Graph (#873)
8badf78edc6 is described below
commit 8badf78edc68e04b0798d90a0a7d007965575b51
Author: 吴晟 Wu Sheng <[email protected]>
AuthorDate: Mon Jun 29 11:42:56 2026 +0800
Blog: Meet Horizon UI 9/17 — Five Profilers, One Flame Graph (#873)
Part 9 of the Meet Horizon UI series on profiling: trace, async (JVM),
eBPF, Go pprof, and network. Four pour into one shared flame-graph /
stack-tree engine; network renders a process honeycomb instead. Covers
the per-profiler task models, the create-vs-read permission split
(profile:enable / profile:read), and per-layer availability.
4 figures (WebP): flame + tree (same result, two views), the pprof tab's
one-event-per-task model, and the network honeycomb.
---
.../blog/2026-06-26-horizon-ui-profiling/index.md | 62 +++++++++++++++++++++
.../horizon-0.7.0/p09-profiling-01-flame.webp | Bin 0 -> 158410 bytes
.../horizon-0.7.0/p09-profiling-01-tree.webp | Bin 0 -> 151964 bytes
.../p09-profiling-02-pprof-tasks.webp | Bin 0 -> 147486 bytes
.../p09-profiling-03-network-honeycomb.webp | Bin 0 -> 94968 bytes
5 files changed, 62 insertions(+)
diff --git a/content/blog/2026-06-26-horizon-ui-profiling/index.md
b/content/blog/2026-06-26-horizon-ui-profiling/index.md
new file mode 100644
index 00000000000..6c2ea29cd57
--- /dev/null
+++ b/content/blog/2026-06-26-horizon-ui-profiling/index.md
@@ -0,0 +1,62 @@
+---
+title: "Meet Horizon UI · 9/17: Five Profilers, One Flame Graph"
+date: 2026-06-26
+author: Sheng Wu
+description: "Part 9 of the Meet Horizon UI series: SkyWalking's five
profilers — trace, async (JVM), eBPF, Go pprof, and network — four of them
pouring into one shared flame-graph and stack-tree engine, and the fifth
rendering a process honeycomb instead."
+tags:
+ - Profiling
+ - Engineering
+---
+
+This is the ninth post in the [Meet Horizon
UI](/blog/2026-06-21-skywalking-horizon-ui-introduction/) series. Metrics tell
you *what* slowed down; [traces](/blog/2026-06-22-horizon-ui-trace-explorer/)
tell you *which hop*. Profiling goes one level deeper — into the call stacks,
kernel events, and process-to-process conversations of a running service — to
tell you *where in the code*. SkyWalking has five different profilers for that,
and Horizon surfaces all of them. The headline of this [...]
+
+## One renderer, four profilers
+
+Trace, async, eBPF, and pprof profiling all produce the same fundamental thing
— a tree of stack frames with sample counts — so Horizon normalizes them into
one shape and renders them through **one flame-graph component** (a wrapper
over `d3-flame-graph`). The payoff is that you learn the view once and it works
the same everywhere:
+
+- each frame's width is its share of the samples, and the hover card reads out
the code signature, the dump count, the time spent (including and *excluding*
children), and the frame's **% of root**;
+- clicking a frame zooms into it and pins a highlight on it — and that
selected-frame highlight is consistent across all four profilers;
+- a dim, per-frame color keyed off the method name keeps a thousand-frame
graph legible on the dark canvas.
+
+
+Figure 1: One flame graph for four profilers — frames by sample share, the
selected frame pinned, the hover card with % of root.</br>
+
+On the **Trace** and **eBPF** tabs you can flip the same data to a **Tree**
view instead — an indented stack table with each method's total vs **self**
duration and its dump count, expandable frame by frame. (Async and pprof are
flame-graph-only; the toggle shows up where both views apply.)
+
+
+Figure 2: The same result, one toggle away — the Tree view swaps the flame for
an indented stack table carrying total vs self duration and dump count.</br>
+
+## What each of the four catches
+
+The four stack profilers share the renderer but answer different questions,
and each has its own New Task form:
+
+- **Trace Profiling** samples the call stacks of *slow trace segments*. Scope
a task to a service (and optionally one endpoint), set a slowness **threshold**
and a **dump period**, and the agent snapshots thread stacks from segments that
cross the threshold. Then you pick a sampled trace, drill to a profiled span,
and **Analyze** — with a *data mode* that includes or excludes child-span time.
+- **Async Profiling** runs the JVM **async-profiler** against a live Java
service with no restart. A task can target several instances and several events
at once — `CPU`, `ALLOC`, `LOCK`, `WALL`, and the timer events — and an
event-type selector re-draws the flame for whichever one you want to read.
+- **eBPF Profiling** captures *kernel-level* stacks with no in-process agent,
driven by [SkyWalking Rover](https://github.com/apache/skywalking-rover):
**ON_CPU** (where the process burns CPU) or **OFF_CPU** (where it's blocked —
on locks, I/O, scheduling). A process picker lets you expand a process's
attributes and pin the ones to profile, and an aggregate toggle counts samples
or sums blocked time (the latter only makes sense off-CPU).
+- **pprof** profiles a live **Go** service through the standard runtime
profiler — exactly *one* event per task, chosen from `CPU`, `HEAP`, `BLOCK`,
`MUTEX`, `GOROUTINE`, `ALLOCS`, and `THREADCREATE`. The dialog adapts to the
choice: a duration for the timed captures, a sampling rate for `BLOCK`/`MUTEX`,
and a one-shot snapshot for the rest.
+
+
+Figure 3: pprof takes exactly one Go event per task — GOROUTINE, MUTEX, and
CPU are separate tasks, each with its own duration and sampling rate; select
one and Analyze pours it into the same flame graph.</br>
+
+## Network Profiling: the deliberate exception
+
+The fifth profiler answers a different kind of question — not "where is one
process spending time" but "which processes are talking to which, and over
what" — so it renders differently on purpose. **Network Profiling** captures
the network conversations between the processes of a service instance and draws
them as a **honeycomb topology**: each process is a hexagon, the instance's own
processes pack into the centre under a dashed pod boundary, and external peers
ring the edge. The links [...]
+
+It also runs differently: instead of a fixed duration, a network task carries
**sampling rules** — match by URI pattern, by 4xx/5xx responses, or by a
minimum duration, and choose how much of each request/response body to keep —
and keeps running until you stop it. Click an edge and a **Client side | Server
side** panel opens with that conversation's call rate, latency, and bytes
charted over the window. It's drawn from the same process-relation data that
powers the [3D Infrastructure Ma [...]
+
+
+Figure 4: The odd one out — process conversations as a honeycomb. In-pod
processes pack inside the dashed pod boundary, external peers ring it, and
every edge is colored by protocol; clicking one opens its client-vs-server
metrics.</br>
+
+## One task model, two permissions
+
+For all the differences in what they capture, every profiling tab is the same
workflow: a **task list** on the left, a **New Task** control, and a **result
panel** on the right. Create a task and the list polls for a few rounds until
OAP has dispatched it and the instances report back; select a task to analyze
it.
+
+That create-versus-read split is also a permission boundary. Starting a task
needs **`profile:enable`** (an operator-and-above default) — because an
unbounded profile could peg a production instance's CPU, so the task forms are
duration- and size-capped on the server. *Reading* a result needs only
**`profile:read`** (part of the read-only data catalog). So a viewer can sit
with a flame graph all day and never be able to launch a profile.
+
+Which tabs you even see depends on the service: a tab appears only when OAP
reports that the service supports that kind of profiling. In practice the
General agent layer carries the four stack engines (trace, eBPF, async, pprof),
eBPF rides wherever Rover is deployed, and network profiling lights up on the
service mesh.
+
+## Where to go next
+
+For the field reference — every task field, the eBPF aggregate modes, the
network sampling rules — see the [Profiling
docs](https://skywalking.apache.org/docs/skywalking-horizon-ui/next/operate/profiling/).
+
+Next up: **Alarms & Incident Triage** — the incident-centric alarm surface,
and replaying the MQE snapshot that fired a rule.
diff --git a/static/screenshots/horizon-0.7.0/p09-profiling-01-flame.webp
b/static/screenshots/horizon-0.7.0/p09-profiling-01-flame.webp
new file mode 100644
index 00000000000..5bb6633a834
Binary files /dev/null and
b/static/screenshots/horizon-0.7.0/p09-profiling-01-flame.webp differ
diff --git a/static/screenshots/horizon-0.7.0/p09-profiling-01-tree.webp
b/static/screenshots/horizon-0.7.0/p09-profiling-01-tree.webp
new file mode 100644
index 00000000000..532f884f95f
Binary files /dev/null and
b/static/screenshots/horizon-0.7.0/p09-profiling-01-tree.webp differ
diff --git a/static/screenshots/horizon-0.7.0/p09-profiling-02-pprof-tasks.webp
b/static/screenshots/horizon-0.7.0/p09-profiling-02-pprof-tasks.webp
new file mode 100644
index 00000000000..ff4f87aab09
Binary files /dev/null and
b/static/screenshots/horizon-0.7.0/p09-profiling-02-pprof-tasks.webp differ
diff --git
a/static/screenshots/horizon-0.7.0/p09-profiling-03-network-honeycomb.webp
b/static/screenshots/horizon-0.7.0/p09-profiling-03-network-honeycomb.webp
new file mode 100644
index 00000000000..48f5cd2f196
Binary files /dev/null and
b/static/screenshots/horizon-0.7.0/p09-profiling-03-network-honeycomb.webp
differ