update
Build and Publish / Metadata (push) Successful in 2s
Build and Publish / BuildAndDeployAmd64 (push) Successful in 58s

This commit is contained in:
mats committed 2026-09-19 14:25:23 +02:00
1 parent 7436966689
commit 412e430cac
2 files changed
+268 -162

No files matched your search

+66
View File
@@ -0,0 +1,66 @@
import { linkRumRequest, parseRequestCrumb, type BackendRequest, type RumBackendLink } from "./http-endpoint"
import type { RumSession, RumTimelineEntry } from "./rum-utils"
/** One browser request from a session, with the backend span that served it (if any). */
export interface LinkedRequest {
/** Index into session.timeline. */
index: number
entry: RumTimelineEntry
method: string
url: string
link: RumBackendLink | null
}
export interface ServiceUsage {
service: string
requests: LinkedRequest[]
/** Requests linked only by method+path+time, not by trace id. */
inferred: number
failed: number
}
export interface SessionServices {
requests: LinkedRequest[]
services: ServiceUsage[]
/** Browser requests that never matched a backend span (uninstrumented hop, sampled out, not loaded). */
unlinked: LinkedRequest[]
}
/** Matches every fetch/xhr in the session timeline to a backend span, then groups by serving service. */
export function sessionServices(session: RumSession, backend: BackendRequest[]): SessionServices {
const requests: LinkedRequest[] = []
session.timeline.forEach((entry, index) => {
if (entry.category !== "fetch" && entry.category !== "xhr") return
const req = parseRequestCrumb(entry.message)
if (!req) return
const link = linkRumRequest(
{
// Breadcrumbs are stamped on completion; the request started duration earlier.
timestamp: entry.timestamp - (entry.durationMs ?? 0),
durationMs: entry.durationMs,
traceId: entry.traceId,
method: req.method,
url: req.url,
},
backend,
)
requests.push({ index, entry, method: req.method, url: req.url, link })
})
const byService = new Map<string, ServiceUsage>()
const unlinked: LinkedRequest[] = []
for (const r of requests) {
if (!r.link) {
unlinked.push(r)
continue
}
const name = r.link.backend.service || "unknown"
const usage = byService.get(name) ?? { service: name, requests: [], inferred: 0, failed: 0 }
usage.requests.push(r)
if (r.link.confidence === "path+time") usage.inferred += 1
if (r.entry.severe) usage.failed += 1
byService.set(name, usage)
}
const services = [...byService.values()].sort((a, b) => b.requests.length - a.requests.length)
return { requests, services, unlinked }
}