// Traffic — request log + drawer const { Drawer, Seg, RegionPill, StatusCode, RequestDetailContent, fmtBytes, fmtAgo, BarChart, Sparkline } = window.UI; function PageTraffic({ state, dispatch, busy }) { const { traffic } = state; const [filter, setFilter] = React.useState("all"); const [search, setSearch] = React.useState(""); const [open, setOpen] = React.useState(null); const rows = traffic.requests.filter(r => { if (filter === "errors") { if (!(r.status === 0 || r.status >= 400)) return false; } if (filter === "tunnel" && r.type !== "tunnel") return false; if (filter === "template" && !r.template) return false; if (search) { const q = search.toLowerCase(); if (!r.url.toLowerCase().includes(q) && !r.pool.toLowerCase().includes(q) && !r.region.toLowerCase().includes(q)) return false; } return true; }); const total = traffic.requests.length; const canLoadMore = total > 0 && total < 1000 && total % 200 === 0; const errs = traffic.requests.filter(r => r.status === 0 || r.status >= 400).length; const tunnels = traffic.requests.filter(r => r.type === "tunnel").length; const exportCSV = () => { const header = ["time","type","method","url","region","pool","node","status","duration_ms","bytes","error"]; const lines = rows.map(r => [ new Date(r.ts).toISOString(), r.type, r.method, r.url, r.group, r.pool, r.node, r.status, r.duration_ms, r.bytes, r.error || "", ].map(v => `"${String(v).replaceAll('"', '""')}"`).join(",")); const blob = new Blob([[header.join(","), ...lines].join("\n")], { type: "text/csv" }); const url = URL.createObjectURL(blob); const a = document.createElement("a"); a.href = url; a.download = "chijie-traffic.csv"; a.click(); URL.revokeObjectURL(url); }; return (

Traffic

Per-request log of HTTP and tunnel egress. Click any row to inspect routing, TLS profile and replay payload.

Requests
{total}
Errors
{errs}{total ? ` · ${(errs/total*100).toFixed(1)}%` : ""}
{errs > 0 ? "investigating" : "clean window"}
Active tunnels
{tunnels}
s.success)} width={240} height={36}/>
Avg ms
{Math.round(traffic.requests.reduce((a,b)=>a+b.duration_ms,0)/total)||0}
last {total} requests

Request log

{rows.length} of {total}
setSearch(e.target.value)} style={{paddingLeft:30, width:220}}/>
{rows.map(r => ( setOpen(r)} style={{cursor:"pointer"}}> ))}
TimeTypeMethodURL RegionPoolTLS Statusmsbytes
{fmtAgo(r.ts)} {r.type === "tunnel" ? "WS" : "HTTP"} {r.method} {r.url}
{r.pool}{r.template && tpl}
{r.node}
{r.tls || "—"} {r.duration_ms} {fmtBytes(r.bytes)}
memory window max 1000
setOpen(null)} title="Request detail">
); } window.PageTraffic = PageTraffic;