wu-sheng opened a new pull request, #48:
URL: https://github.com/apache/skywalking-horizon-ui/pull/48

   ## What
   
   Adds a **Browser Logs** tab to the BROWSER layer and **source-map 
de-obfuscation** for
   the JS errors the browser agent reports — the long-standing ask in
   [apache/skywalking#6784](https://github.com/apache/skywalking/issues/6784).
   
   The tab lists `queryBrowserErrorLogs` rows (message, category, page, app 
version, time,
   minified `line:col`), filterable by category, app version, page path, and 
time window.
   Expanding a row shows the **raw stack** next to a **de-obfuscated** view: 
pick a loaded
   `.map` and the BFF resolves each frame back to the original file / line / 
column / symbol
   name plus a source snippet.
   
   ## Why it's UI-only (no SWIP)
   
   Per the discussion on #6784, this is implemented entirely in Horizon UI — 
**no OAP, agent,
   or query-protocol change**. It reads the existing `queryBrowserErrorLogs` 
GraphQL query and
   hosts source maps in the **BFF process memory** as a deliberate, 
no-backend-change pilot:
   
   - **Uploaded `.map` files are temporary** — held in BFF memory only, evicted
     least-recently-used past a configurable budget, and lost on restart. The 
UI surfaces this
     explicitly (a "temporary" badge, a usage bar, and a warning).
   - **Durable provisioning is a static mount** — drop `.map` files into the 
server's
     source-map directory (`HORIZON_SOURCEMAPS_DIR`, `/app/sourcemaps` in the 
image); those
     reload automatically and can't be deleted from the UI.
   
   Resolution runs server-side in Node (`@jridgewell/trace-mapping`, 
pure-JS/sync) so maps —
   and their `sourcesContent` — never ship to the browser.
   
   ## Config
   
   New `sourceMaps` block in `horizon.yaml` (all hot-reloadable except the boot 
mount and
   *raising* the per-file upload cap):
   
   ```yaml
   sourceMaps:
     enabled: true
     maxFileBytes: 67108864      # 64 MiB — reject a single .map larger than 
this
     maxTotalBytes: 536870912    # 512 MiB — resident in-memory upload budget 
(LRU past it)
     maxFileCount: 128           # per-set cap (uploaded set / mounted set each)
     bootMountDir: /app/sourcemaps
   ```
   
   RBAC: uploading/deleting maps needs the new **`source-map:write`** verb; 
listing errors,
   listing maps, and resolving ride on **`browser-errors:read`**. Both are 
granted to the
   default roles in the example/demo configs.
   
   ## Scope of the change
   
   - **BFF** — `POST /api/layer/:key/browser-errors` (mirrors the logs route; 
SECOND step,
     OAP-server-local time, per-page time range, DESC re-sort for BanyanDB 
segment order);
     source-map admin routes (multipart upload / list / delete / resolve); a 
process-global
     `SourceMapStore` (budget accounting, LRU eviction, lazy mount reads, 
bounded parsed cache).
   - **UI** — `layer/browser-errors/` (view + composable + embedded source-map 
manager),
     api façade, tab wiring across sidebar / router / caps / topbar opt-out. 
The view matches
     the general Logs tab vocabulary (histogram, category legend, dense 
stream); the tab owns
     its own time range and pauses auto-refresh.
   - **i18n** — all operator strings wrapped in `t()`; 40 new keys added to 
English and
     translated into the 7 other catalogs (de/es/fr/ja/ko/pt/zh-CN), 
placeholders + technical
     tokens preserved.
   - **Docs** — operator page `docs/operate/browser-source-maps.md` (+ menu 
entry), plus
     `horizon.yaml`, container-image, and RBAC doc updates.
   - **Bundled BROWSER layer template** — gains the `browserErrors` widget; the 
generic `logs`
     tab is disabled for BROWSER (browser errors replace it there).
   
   ## Validation
   
   - **Live OAP** (local OAP + version-locked BanyanDB, real browser-error 
data): tab appears,
     `queryBrowserErrorLogs` returns rows; verified the SECOND-precision 
rolling **and** custom
     epoch-ms time ranges agree, results are strictly newest-first, a 
statically-mounted `.map`
     loads and is non-deletable, and an uploaded `.map` resolves a real 
minified stack to the
     correct original positions + snippet.
   - **Unit tests** — 194 pass (109 BFF + 85 UI), including the source-map 
pipeline
     (esbuild-generated real `.map` → original positions), 
budget/eviction/hot-reload invariants,
     and the multipart HTTP surface (200 / 413 / 403).
   - `type-check`, `lint`, and `license-eye` header check all clean.
   
   ## Out of scope
   
   OAP/agent-side changes (Debug-ID matching, ingest-time resolution, OAP-side 
map storage) —
   the proper long-term home, deferred. The general service **Logs** tab is 
untouched.
   


-- 
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