[{"data":1,"prerenderedAt":4258},["ShallowReactive",2],{"navigation_docs":3,"-build-on-top-consumer-recipes":427,"-build-on-top-consumer-recipes-surround":4253},[4,35,159,201,289,324,411],{"title":5,"path":6,"stem":7,"children":8,"page":34},"Getting Started","\u002Fgetting-started","1.getting-started",[9,14,19,24,29],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-info",{"title":15,"path":16,"stem":17,"icon":18},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":20,"path":21,"stem":22,"icon":23},"Quick Start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-zap",{"title":25,"path":26,"stem":27,"icon":28},"Agent Skills","\u002Fgetting-started\u002Fagent-skills","1.getting-started\u002F4.agent-skills","i-lucide-sparkles",{"title":30,"path":31,"stem":32,"icon":33},"vs Other Loggers","\u002Fgetting-started\u002Fvs-other-loggers","1.getting-started\u002F5.vs-other-loggers","i-lucide-scale",false,{"title":36,"path":37,"stem":38,"children":39,"page":34},"Logging","\u002Flogging","2.logging",[40,45,50,55,60,65,70,99,127],{"title":41,"path":42,"stem":43,"icon":44},"Overview","\u002Flogging\u002Foverview","2.logging\u002F0.overview","i-lucide-list",{"title":46,"path":47,"stem":48,"icon":49},"Simple Logging","\u002Flogging\u002Fsimple-logging","2.logging\u002F1.simple-logging","i-lucide-terminal",{"title":51,"path":52,"stem":53,"icon":54},"Wide Events","\u002Flogging\u002Fwide-events","2.logging\u002F2.wide-events","i-lucide-layers",{"title":56,"path":57,"stem":58,"icon":59},"Structured Errors","\u002Flogging\u002Fstructured-errors","2.logging\u002F3.structured-errors","i-lucide-shield-alert",{"title":61,"path":62,"stem":63,"icon":64},"Catalogs","\u002Flogging\u002Fcatalogs","2.logging\u002F4.catalogs","i-lucide-book-open",{"title":66,"path":67,"stem":68,"icon":69},"Client Logging","\u002Flogging\u002Fclient-logging","2.logging\u002F5.client-logging","i-lucide-monitor",{"title":71,"icon":72,"path":73,"stem":74,"children":75,"page":34},"AI SDK","i-simple-icons-vercel","\u002Flogging\u002Fai-sdk","2.logging\u002F6.ai-sdk",[76,79,84,89,94],{"title":41,"path":77,"stem":78,"icon":44},"\u002Flogging\u002Fai-sdk\u002Foverview","2.logging\u002F6.ai-sdk\u002F01.overview",{"title":80,"path":81,"stem":82,"icon":83},"Usage","\u002Flogging\u002Fai-sdk\u002Fusage","2.logging\u002F6.ai-sdk\u002F02.usage","i-lucide-code",{"title":85,"path":86,"stem":87,"icon":88},"Options","\u002Flogging\u002Fai-sdk\u002Foptions","2.logging\u002F6.ai-sdk\u002F03.options","i-lucide-sliders",{"title":90,"path":91,"stem":92,"icon":93},"Metadata","\u002Flogging\u002Fai-sdk\u002Fmetadata","2.logging\u002F6.ai-sdk\u002F04.metadata","i-lucide-database",{"title":95,"path":96,"stem":97,"icon":98},"Telemetry","\u002Flogging\u002Fai-sdk\u002Ftelemetry","2.logging\u002F6.ai-sdk\u002F05.telemetry","i-lucide-activity",{"title":100,"icon":101,"path":102,"stem":103,"children":104,"page":34},"Better Auth","i-simple-icons-betterauth","\u002Flogging\u002Fbetter-auth","2.logging\u002F7.better-auth",[105,108,113,118,122],{"title":41,"path":106,"stem":107,"icon":44},"\u002Flogging\u002Fbetter-auth\u002Foverview","2.logging\u002F7.better-auth\u002F01.overview",{"title":109,"path":110,"stem":111,"icon":112},"Identify User","\u002Flogging\u002Fbetter-auth\u002Fidentify-user","2.logging\u002F7.better-auth\u002F02.identify-user","i-lucide-user-check",{"title":114,"path":115,"stem":116,"icon":117},"Middleware","\u002Flogging\u002Fbetter-auth\u002Fmiddleware","2.logging\u002F7.better-auth\u002F03.middleware","i-lucide-shield",{"title":119,"path":120,"stem":121,"icon":69},"Client Sync","\u002Flogging\u002Fbetter-auth\u002Fclient-sync","2.logging\u002F7.better-auth\u002F04.client-sync",{"title":123,"path":124,"stem":125,"icon":126},"Performance","\u002Flogging\u002Fbetter-auth\u002Fperformance","2.logging\u002F7.better-auth\u002F05.performance","i-lucide-gauge",{"title":128,"icon":129,"path":130,"stem":131,"children":132,"page":34},"Audit Logs","i-lucide-shield-check","\u002Flogging\u002Faudit","2.logging\u002F8.audit",[133,136,141,146,151,155],{"title":41,"path":134,"stem":135,"icon":44},"\u002Flogging\u002Faudit\u002Foverview","2.logging\u002F8.audit\u002F01.overview",{"title":137,"path":138,"stem":139,"icon":140},"Schema","\u002Flogging\u002Faudit\u002Fschema","2.logging\u002F8.audit\u002F02.schema","i-lucide-file-text",{"title":142,"path":143,"stem":144,"icon":145},"Recording","\u002Flogging\u002Faudit\u002Frecording","2.logging\u002F8.audit\u002F03.recording","i-lucide-pen-line",{"title":147,"path":148,"stem":149,"icon":150},"Drains","\u002Flogging\u002Faudit\u002Fpipeline","2.logging\u002F8.audit\u002F04.pipeline","i-lucide-link",{"title":152,"path":153,"stem":154,"icon":129},"Compliance","\u002Flogging\u002Faudit\u002Fcompliance","2.logging\u002F8.audit\u002F05.compliance",{"title":156,"path":157,"stem":158,"icon":64},"Recipes","\u002Flogging\u002Faudit\u002Frecipes","2.logging\u002F8.audit\u002F06.recipes",{"title":160,"path":161,"stem":162,"children":163,"page":34},"Core Concepts","\u002Fcore-concepts","3.core-concepts",[164,169,174,179,184,188,191,196],{"title":165,"path":166,"stem":167,"icon":168},"Lifecycle","\u002Fcore-concepts\u002Flifecycle","3.core-concepts\u002F0.lifecycle","i-lucide-arrow-right-left",{"title":170,"path":171,"stem":172,"icon":173},"Configuration","\u002Fcore-concepts\u002Fconfiguration","3.core-concepts\u002F1.configuration","i-lucide-settings",{"title":175,"path":176,"stem":177,"icon":178},"Sampling","\u002Fcore-concepts\u002Fsampling","3.core-concepts\u002F2.sampling","i-lucide-filter",{"title":180,"path":181,"stem":182,"icon":183},"Typed Fields","\u002Fcore-concepts\u002Ftyped-fields","3.core-concepts\u002F3.typed-fields","i-simple-icons-typescript",{"title":185,"path":186,"stem":187,"icon":129},"Best Practices","\u002Fcore-concepts\u002Fbest-practices","3.core-concepts\u002F4.best-practices",{"title":123,"path":189,"stem":190,"icon":126},"\u002Fcore-concepts\u002Fperformance","3.core-concepts\u002F5.performance",{"title":192,"path":193,"stem":194,"icon":195},"Vite Plugin","\u002Fcore-concepts\u002Fvite-plugin","3.core-concepts\u002F6.vite-plugin","i-custom-vite",{"title":197,"path":198,"stem":199,"icon":200},"Auto-Redaction","\u002Fcore-concepts\u002Fredaction","3.core-concepts\u002F7.redaction","i-lucide-eye-off",{"title":202,"path":203,"stem":204,"children":205,"page":34},"Frameworks","\u002Fframeworks","4.frameworks",[206,210,215,220,225,230,235,240,245,250,255,260,265,270,274,279,284],{"title":41,"path":207,"stem":208,"icon":209},"\u002Fframeworks\u002Foverview","4.frameworks\u002F00.overview","i-lucide-layout-grid",{"title":211,"path":212,"stem":213,"icon":214},"Nuxt","\u002Fframeworks\u002Fnuxt","4.frameworks\u002F01.nuxt","i-simple-icons-nuxtdotjs",{"title":216,"path":217,"stem":218,"icon":219},"Next.js","\u002Fframeworks\u002Fnextjs","4.frameworks\u002F02.nextjs","i-simple-icons-nextdotjs",{"title":221,"path":222,"stem":223,"icon":224},"SvelteKit","\u002Fframeworks\u002Fsveltekit","4.frameworks\u002F03.sveltekit","i-simple-icons-svelte",{"title":226,"path":227,"stem":228,"icon":229},"Nitro","\u002Fframeworks\u002Fnitro","4.frameworks\u002F04.nitro","i-custom-nitro",{"title":231,"path":232,"stem":233,"icon":234},"TanStack Start","\u002Fframeworks\u002Ftanstack-start","4.frameworks\u002F05.tanstack-start","i-custom-tanstack",{"title":236,"path":237,"stem":238,"icon":239},"NestJS","\u002Fframeworks\u002Fnestjs","4.frameworks\u002F06.nestjs","i-simple-icons-nestjs",{"title":241,"path":242,"stem":243,"icon":244},"Express","\u002Fframeworks\u002Fexpress","4.frameworks\u002F07.express","i-simple-icons-express",{"title":246,"path":247,"stem":248,"icon":249},"Hono","\u002Fframeworks\u002Fhono","4.frameworks\u002F08.hono","i-simple-icons-hono",{"title":251,"path":252,"stem":253,"icon":254},"Fastify","\u002Fframeworks\u002Ffastify","4.frameworks\u002F09.fastify","i-simple-icons-fastify",{"title":256,"path":257,"stem":258,"icon":259},"Elysia","\u002Fframeworks\u002Felysia","4.frameworks\u002F10.elysia","i-custom-elysia",{"title":261,"path":262,"stem":263,"icon":264},"React Router","\u002Fframeworks\u002Freact-router","4.frameworks\u002F11.react-router","i-custom-reactrouter",{"title":266,"path":267,"stem":268,"icon":269},"Cloudflare Workers","\u002Fframeworks\u002Fcloudflare-workers","4.frameworks\u002F12.cloudflare-workers","i-simple-icons-cloudflare",{"title":271,"path":272,"stem":273,"icon":183},"Standalone","\u002Fframeworks\u002Fstandalone","4.frameworks\u002F13.standalone",{"title":275,"path":276,"stem":277,"icon":278},"Astro","\u002Fframeworks\u002Fastro","4.frameworks\u002F14.astro","i-simple-icons-astro",{"title":280,"path":281,"stem":282,"icon":283},"AWS Lambda","\u002Fframeworks\u002Faws-lambda","4.frameworks\u002F16.aws-lambda","i-custom-lambda",{"title":285,"path":286,"stem":287,"icon":288},"Custom Integration","\u002Fframeworks\u002Fcustom-integration","4.frameworks\u002F17.custom-integration","i-lucide-puzzle",{"title":290,"path":291,"stem":292,"children":293,"page":34},"Build on top","\u002Fbuild-on-top","5.build-on-top",[294,297,302,307,311,315,320],{"title":41,"path":295,"stem":296,"icon":54},"\u002Fbuild-on-top\u002Foverview","5.build-on-top\u002F0.overview",{"title":298,"path":299,"stem":300,"icon":301},"Stream","\u002Fbuild-on-top\u002Fstream","5.build-on-top\u002F1.stream","i-lucide-radio-tower",{"title":303,"path":304,"stem":305,"icon":306},"FS reader","\u002Fbuild-on-top\u002Ffs-reader","5.build-on-top\u002F2.fs-reader","i-lucide-folder-search",{"title":156,"path":308,"stem":309,"icon":310},"\u002Fbuild-on-top\u002Fconsumer-recipes","5.build-on-top\u002F3.consumer-recipes","i-lucide-chef-hat",{"title":312,"path":313,"stem":314,"icon":288},"Pipeline extension","\u002Fbuild-on-top\u002Fpipeline-extension","5.build-on-top\u002F4.pipeline-extension",{"title":316,"path":317,"stem":318,"icon":319},"Sinks","\u002Fbuild-on-top\u002Fsinks","5.build-on-top\u002F5.sinks","i-lucide-share-2",{"title":321,"path":322,"stem":323,"icon":288},"Framework integration","\u002Fbuild-on-top\u002Fframework-integration","5.build-on-top\u002F6.framework-integration",{"title":325,"path":326,"stem":327,"children":328,"page":34},"Adapters","\u002Fadapters","6.adapters",[329,332,372,387],{"title":41,"path":330,"stem":331,"icon":44},"\u002Fadapters\u002Foverview","6.adapters\u002F01.overview",{"title":333,"path":334,"stem":335,"children":336,"page":34},"Cloud destinations","\u002Fadapters\u002Fcloud","6.adapters\u002F02.cloud",[337,342,347,352,357,362,367],{"title":338,"path":339,"stem":340,"icon":341},"Axiom","\u002Fadapters\u002Fcloud\u002Faxiom","6.adapters\u002F02.cloud\u002F01.axiom","i-custom-axiom",{"title":343,"path":344,"stem":345,"icon":346},"OTLP","\u002Fadapters\u002Fcloud\u002Fotlp","6.adapters\u002F02.cloud\u002F02.otlp","i-simple-icons-opentelemetry",{"title":348,"path":349,"stem":350,"icon":351},"PostHog","\u002Fadapters\u002Fcloud\u002Fposthog","6.adapters\u002F02.cloud\u002F03.posthog","i-simple-icons-posthog",{"title":353,"path":354,"stem":355,"icon":356},"Sentry","\u002Fadapters\u002Fcloud\u002Fsentry","6.adapters\u002F02.cloud\u002F04.sentry","i-simple-icons-sentry",{"title":358,"path":359,"stem":360,"icon":361},"Better Stack","\u002Fadapters\u002Fcloud\u002Fbetter-stack","6.adapters\u002F02.cloud\u002F05.better-stack","i-simple-icons-betterstack",{"title":363,"path":364,"stem":365,"icon":366},"Datadog","\u002Fadapters\u002Fcloud\u002Fdatadog","6.adapters\u002F02.cloud\u002F06.datadog","i-simple-icons-datadog",{"title":368,"path":369,"stem":370,"icon":371},"HyperDX","\u002Fadapters\u002Fcloud\u002Fhyperdx","6.adapters\u002F02.cloud\u002F07.hyperdx","i-custom-hyperdx",{"title":373,"path":374,"stem":375,"children":376,"page":34},"Self-hosted","\u002Fadapters\u002Fself-hosted","6.adapters\u002F03.self-hosted",[377,382],{"title":378,"path":379,"stem":380,"icon":381},"File System","\u002Fadapters\u002Fself-hosted\u002Ffs","6.adapters\u002F03.self-hosted\u002F01.fs","i-lucide-hard-drive",{"title":383,"path":384,"stem":385,"icon":386},"NuxtHub","\u002Fadapters\u002Fself-hosted\u002Fnuxthub","6.adapters\u002F03.self-hosted\u002F02.nuxthub","i-simple-icons-nuxt",{"title":388,"path":389,"stem":390,"children":391,"page":34},"Building blocks","\u002Fadapters\u002Fbuilding-blocks","6.adapters\u002F04.building-blocks",[392,397,402,406],{"title":393,"path":394,"stem":395,"icon":396},"Pipeline","\u002Fadapters\u002Fbuilding-blocks\u002Fpipeline","6.adapters\u002F04.building-blocks\u002F01.pipeline","i-lucide-workflow",{"title":398,"path":399,"stem":400,"icon":401},"HTTP","\u002Fadapters\u002Fbuilding-blocks\u002Fhttp","6.adapters\u002F04.building-blocks\u002F02.http","i-lucide-globe",{"title":403,"path":404,"stem":405,"icon":83},"Custom Adapters","\u002Fadapters\u002Fbuilding-blocks\u002Fcustom","6.adapters\u002F04.building-blocks\u002F03.custom",{"title":407,"path":408,"stem":409,"icon":410},"Toolkit","\u002Fadapters\u002Fbuilding-blocks\u002Ftoolkit","6.adapters\u002F04.building-blocks\u002F04.toolkit","i-lucide-blocks",{"title":412,"path":413,"stem":414,"children":415,"page":34},"Enrichers","\u002Fenrichers","7.enrichers",[416,419,423],{"title":41,"path":417,"stem":418,"icon":28},"\u002Fenrichers\u002Foverview","7.enrichers\u002F1.overview",{"title":420,"path":421,"stem":422,"icon":288},"Built-in","\u002Fenrichers\u002Fbuilt-in","7.enrichers\u002F2.built-in",{"title":424,"path":425,"stem":426,"icon":83},"Custom","\u002Fenrichers\u002Fcustom","7.enrichers\u002F3.custom",{"id":428,"title":156,"body":429,"description":4246,"extension":4247,"links":4248,"meta":4249,"navigation":4250,"path":308,"seo":4251,"stem":309,"__hash__":4252},"docs\u002F5.build-on-top\u002F3.consumer-recipes.md",{"type":430,"value":431,"toc":4233},"minimark",[432,445,520,525,546,551,1550,1557,1561,2169,2173,2539,2547,2551,2556,2610,2613,2717,2730,2734,2737,3157,3166,3170,3176,3674,3678,3681,4037,4041,4044,4203,4206,4210,4230],[433,434,435,436,440,441,444],"p",{},"Real-world patterns that combine the ",[437,438,439],"a",{"href":299},"in-process bus and stream server"," with the ",[437,442,443],{"href":304},"filesystem reader",".",[446,447,450,453,512],"prompt",{":actions":448,"description":449,"icon":310},"[\"copy\",\"cursor\",\"windsurf\"]","Build a custom evlog devtool \u002F dashboard",[433,451,452],{},"Bootstrap a local devtool or dashboard that consumes evlog wide events.",[454,455,456,469,480,499,506,509],"ul",{},[457,458,459,460,464,465,468],"li",{},"Pick the source: live (stream server over SSE) or history (",[461,462,463],"code",{},"readFsLogs"," from ",[461,466,467],{},".evlog\u002Flogs",") or both (replay then live tail)",[457,470,471,472,475,476,479],{},"For SSE: discover the URL via ",[461,473,474],{},".evlog\u002Fstream.url"," or ",[461,477,478],{},"GET \u002Fapi\u002F_evlog\u002Fstream-info",", never hard-code the port",[457,481,482,483,486,487,490,491,494,495,498],{},"Open an ",[461,484,485],{},"EventSource"," and decode messages as ",[461,488,489],{},"{ evlog: '1', type, data }"," envelopes (",[461,492,493],{},"type"," is ",[461,496,497],{},"hello | event | replay | ping",")",[457,500,501,502,505],{},"For browser tabs running on a different origin from the dev server, configure CORS via the stream server ",[461,503,504],{},"cors"," option and forward credentials carefully",[457,507,508],{},"Aggregate on the consumer side (counts, latency histograms, error groups) — keep the server simple",[457,510,511],{},"Skip on serverless platforms — the stream is in-process",[433,513,514,515],{},"Docs: ",[437,516,517],{"href":517,"rel":518},"https:\u002F\u002Fwww.evlog.dev\u002Fbuild-on-top\u002Fconsumer-recipes",[519],"nofollow",[521,522,524],"h2",{"id":523},"_1-build-a-minimal-devtool","1. Build a minimal devtool",[433,526,527,528,530,531,533,534,537,538,540,541,545],{},"A live event panel is essentially ",[461,529,485],{}," + a list. The full wire format and discovery rules — ",[461,532,474],{},", ",[461,535,536],{},"\u002Fapi\u002F_evlog\u002Fstream-info",", the ",[461,539,489],{}," envelope, and auth — are documented on the ",[437,542,544],{"href":543},"\u002Fbuild-on-top\u002Fstream#wire-format","stream page",". Each recipe below assumes you've grabbed the URL via either of those mechanisms.",[547,548,550],"h3",{"id":549},"vanilla-html-js-drop-into-any-page","Vanilla HTML + JS (drop into any page)",[552,553,558],"pre",{"className":554,"code":555,"language":556,"meta":557,"style":557},"language-html shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003C!doctype html>\n\u003Chtml>\n\u003Chead>\n  \u003Cmeta charset=\"utf-8\">\n  \u003Ctitle>evlog mini devtool\u003C\u002Ftitle>\n  \u003Cstyle>\n    body { font: 13px ui-sans-serif, system-ui; margin: 0; padding: 0; }\n    table { width: 100%; border-collapse: collapse; }\n    td, th { padding: 6px 10px; border-bottom: 1px solid #eee; text-align: left; }\n    .lvl-error { color: #ef4444 }\n    .lvl-warn  { color: #f59e0b }\n    .lvl-info  { color: #3b82f6 }\n  \u003C\u002Fstyle>\n\u003C\u002Fhead>\n\u003Cbody>\n  \u003Ctable id=\"t\">\n    \u003Cthead>\u003Ctr>\u003Cth>time\u003C\u002Fth>\u003Cth>level\u003C\u002Fth>\u003Cth>service\u003C\u002Fth>\u003Cth>action\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\n    \u003Ctbody>\u003C\u002Ftbody>\n  \u003C\u002Ftable>\n\n  \u003Cscript>\n    \u002F\u002F Replace with the URL printed at startup, or fetch it from \u002Fapi\u002F_evlog\u002Fstream-info\n    const STREAM_URL = 'http:\u002F\u002F127.0.0.1:51203'\n    const tbody = document.querySelector('#t tbody')\n    const es = new EventSource(STREAM_URL)\n\n    es.onmessage = (e) => {\n      const env = JSON.parse(e.data)\n      if (env.evlog !== '1') return\n      if (env.type !== 'event' && env.type !== 'replay') return\n\n      const w = env.data\n      const tr = document.createElement('tr')\n      tr.innerHTML = `\n        \u003Ctd>${new Date(w.timestamp).toLocaleTimeString()}\u003C\u002Ftd>\n        \u003Ctd class=\"lvl-${w.level}\">${w.level}\u003C\u002Ftd>\n        \u003Ctd>${w.service ?? ''}\u003C\u002Ftd>\n        \u003Ctd>${w.action ?? w.message ?? w.path ?? ''}\u003C\u002Ftd>\n      `\n      tbody.prepend(tr)\n      while (tbody.children.length > 200) tbody.lastElementChild.remove()\n    }\n  \u003C\u002Fscript>\n\u003C\u002Fbody>\n\u003C\u002Fhtml>\n","html","",[461,559,560,580,590,600,626,648,658,713,743,799,824,846,867,877,886,896,918,997,1011,1020,1027,1037,1044,1064,1097,1116,1121,1150,1180,1213,1257,1262,1279,1306,1322,1359,1391,1413,1451,1457,1474,1517,1523,1532,1541],{"__ignoreMap":557},[561,562,565,569,573,577],"span",{"class":563,"line":564},"line",1,[561,566,568],{"class":567},"sMK4o","\u003C!",[561,570,572],{"class":571},"swJcz","doctype",[561,574,576],{"class":575},"spNyl"," html",[561,578,579],{"class":567},">\n",[561,581,583,586,588],{"class":563,"line":582},2,[561,584,585],{"class":567},"\u003C",[561,587,556],{"class":571},[561,589,579],{"class":567},[561,591,593,595,598],{"class":563,"line":592},3,[561,594,585],{"class":567},[561,596,597],{"class":571},"head",[561,599,579],{"class":567},[561,601,603,606,609,612,615,618,622,624],{"class":563,"line":602},4,[561,604,605],{"class":567},"  \u003C",[561,607,608],{"class":571},"meta",[561,610,611],{"class":575}," charset",[561,613,614],{"class":567},"=",[561,616,617],{"class":567},"\"",[561,619,621],{"class":620},"sfazB","utf-8",[561,623,617],{"class":567},[561,625,579],{"class":567},[561,627,629,631,634,637,641,644,646],{"class":563,"line":628},5,[561,630,605],{"class":567},[561,632,633],{"class":571},"title",[561,635,636],{"class":567},">",[561,638,640],{"class":639},"sTEyZ","evlog mini devtool",[561,642,643],{"class":567},"\u003C\u002F",[561,645,633],{"class":571},[561,647,579],{"class":567},[561,649,651,653,656],{"class":563,"line":650},6,[561,652,605],{"class":567},[561,654,655],{"class":571},"style",[561,657,579],{"class":567},[561,659,661,665,668,672,675,679,682,685,688,691,694,696,699,701,704,706,708,710],{"class":563,"line":660},7,[561,662,664],{"class":663},"sBMFI","    body",[561,666,667],{"class":567}," {",[561,669,671],{"class":670},"sqsOY"," font",[561,673,674],{"class":567},":",[561,676,678],{"class":677},"sbssI"," 13px",[561,680,681],{"class":639}," ui-sans-serif",[561,683,684],{"class":567},",",[561,686,687],{"class":639}," system-ui",[561,689,690],{"class":567},";",[561,692,693],{"class":670}," margin",[561,695,674],{"class":567},[561,697,698],{"class":677}," 0",[561,700,690],{"class":567},[561,702,703],{"class":670}," padding",[561,705,674],{"class":567},[561,707,698],{"class":677},[561,709,690],{"class":567},[561,711,712],{"class":567}," }\n",[561,714,716,719,721,724,726,729,731,734,736,739,741],{"class":563,"line":715},8,[561,717,718],{"class":663},"    table",[561,720,667],{"class":567},[561,722,723],{"class":670}," width",[561,725,674],{"class":567},[561,727,728],{"class":677}," 100%",[561,730,690],{"class":567},[561,732,733],{"class":670}," border-collapse",[561,735,674],{"class":567},[561,737,738],{"class":639}," collapse",[561,740,690],{"class":567},[561,742,712],{"class":567},[561,744,746,749,751,754,756,758,760,763,766,768,771,773,776,779,782,785,787,790,792,795,797],{"class":563,"line":745},9,[561,747,748],{"class":663},"    td",[561,750,684],{"class":567},[561,752,753],{"class":663}," th",[561,755,667],{"class":567},[561,757,703],{"class":670},[561,759,674],{"class":567},[561,761,762],{"class":677}," 6px",[561,764,765],{"class":677}," 10px",[561,767,690],{"class":567},[561,769,770],{"class":670}," border-bottom",[561,772,674],{"class":567},[561,774,775],{"class":677}," 1px",[561,777,778],{"class":639}," solid ",[561,780,781],{"class":567},"#",[561,783,784],{"class":639},"eee",[561,786,690],{"class":567},[561,788,789],{"class":670}," text-align",[561,791,674],{"class":567},[561,793,794],{"class":639}," left",[561,796,690],{"class":567},[561,798,712],{"class":567},[561,800,802,805,808,810,813,815,818,821],{"class":563,"line":801},10,[561,803,804],{"class":567},"    .",[561,806,807],{"class":663},"lvl-error",[561,809,667],{"class":567},[561,811,812],{"class":670}," color",[561,814,674],{"class":567},[561,816,817],{"class":567}," #",[561,819,820],{"class":639},"ef4444 ",[561,822,823],{"class":567},"}\n",[561,825,827,829,832,835,837,839,841,844],{"class":563,"line":826},11,[561,828,804],{"class":567},[561,830,831],{"class":663},"lvl-warn",[561,833,834],{"class":567},"  {",[561,836,812],{"class":670},[561,838,674],{"class":567},[561,840,817],{"class":567},[561,842,843],{"class":639},"f59e0b ",[561,845,823],{"class":567},[561,847,849,851,854,856,858,860,862,865],{"class":563,"line":848},12,[561,850,804],{"class":567},[561,852,853],{"class":663},"lvl-info",[561,855,834],{"class":567},[561,857,812],{"class":670},[561,859,674],{"class":567},[561,861,817],{"class":567},[561,863,864],{"class":639},"3b82f6 ",[561,866,823],{"class":567},[561,868,870,873,875],{"class":563,"line":869},13,[561,871,872],{"class":567},"  \u003C\u002F",[561,874,655],{"class":571},[561,876,579],{"class":567},[561,878,880,882,884],{"class":563,"line":879},14,[561,881,643],{"class":567},[561,883,597],{"class":571},[561,885,579],{"class":567},[561,887,889,891,894],{"class":563,"line":888},15,[561,890,585],{"class":567},[561,892,893],{"class":571},"body",[561,895,579],{"class":567},[561,897,899,901,904,907,909,911,914,916],{"class":563,"line":898},16,[561,900,605],{"class":567},[561,902,903],{"class":571},"table",[561,905,906],{"class":575}," id",[561,908,614],{"class":567},[561,910,617],{"class":567},[561,912,913],{"class":620},"t",[561,915,617],{"class":567},[561,917,579],{"class":567},[561,919,921,924,927,930,933,935,938,940,943,945,947,949,951,953,956,958,960,962,964,966,969,971,973,975,977,979,982,984,986,989,991,993,995],{"class":563,"line":920},17,[561,922,923],{"class":567},"    \u003C",[561,925,926],{"class":571},"thead",[561,928,929],{"class":567},">\u003C",[561,931,932],{"class":571},"tr",[561,934,929],{"class":567},[561,936,937],{"class":571},"th",[561,939,636],{"class":567},[561,941,942],{"class":639},"time",[561,944,643],{"class":567},[561,946,937],{"class":571},[561,948,929],{"class":567},[561,950,937],{"class":571},[561,952,636],{"class":567},[561,954,955],{"class":639},"level",[561,957,643],{"class":567},[561,959,937],{"class":571},[561,961,929],{"class":567},[561,963,937],{"class":571},[561,965,636],{"class":567},[561,967,968],{"class":639},"service",[561,970,643],{"class":567},[561,972,937],{"class":571},[561,974,929],{"class":567},[561,976,937],{"class":571},[561,978,636],{"class":567},[561,980,981],{"class":639},"action",[561,983,643],{"class":567},[561,985,937],{"class":571},[561,987,988],{"class":567},">\u003C\u002F",[561,990,932],{"class":571},[561,992,988],{"class":567},[561,994,926],{"class":571},[561,996,579],{"class":567},[561,998,1000,1002,1005,1007,1009],{"class":563,"line":999},18,[561,1001,923],{"class":567},[561,1003,1004],{"class":571},"tbody",[561,1006,988],{"class":567},[561,1008,1004],{"class":571},[561,1010,579],{"class":567},[561,1012,1014,1016,1018],{"class":563,"line":1013},19,[561,1015,872],{"class":567},[561,1017,903],{"class":571},[561,1019,579],{"class":567},[561,1021,1023],{"class":563,"line":1022},20,[561,1024,1026],{"emptyLinePlaceholder":1025},true,"\n",[561,1028,1030,1032,1035],{"class":563,"line":1029},21,[561,1031,605],{"class":567},[561,1033,1034],{"class":571},"script",[561,1036,579],{"class":567},[561,1038,1040],{"class":563,"line":1039},22,[561,1041,1043],{"class":1042},"sHwdD","    \u002F\u002F Replace with the URL printed at startup, or fetch it from \u002Fapi\u002F_evlog\u002Fstream-info\n",[561,1045,1047,1050,1053,1055,1058,1061],{"class":563,"line":1046},23,[561,1048,1049],{"class":575},"    const",[561,1051,1052],{"class":639}," STREAM_URL ",[561,1054,614],{"class":567},[561,1056,1057],{"class":567}," '",[561,1059,1060],{"class":620},"http:\u002F\u002F127.0.0.1:51203",[561,1062,1063],{"class":567},"'\n",[561,1065,1067,1069,1072,1074,1077,1079,1083,1086,1089,1092,1094],{"class":563,"line":1066},24,[561,1068,1049],{"class":575},[561,1070,1071],{"class":639}," tbody ",[561,1073,614],{"class":567},[561,1075,1076],{"class":639}," document",[561,1078,444],{"class":567},[561,1080,1082],{"class":1081},"s2Zo4","querySelector",[561,1084,1085],{"class":639},"(",[561,1087,1088],{"class":567},"'",[561,1090,1091],{"class":620},"#t tbody",[561,1093,1088],{"class":567},[561,1095,1096],{"class":639},")\n",[561,1098,1100,1102,1105,1107,1110,1113],{"class":563,"line":1099},25,[561,1101,1049],{"class":575},[561,1103,1104],{"class":639}," es ",[561,1106,614],{"class":567},[561,1108,1109],{"class":567}," new",[561,1111,1112],{"class":1081}," EventSource",[561,1114,1115],{"class":639},"(STREAM_URL)\n",[561,1117,1119],{"class":563,"line":1118},26,[561,1120,1026],{"emptyLinePlaceholder":1025},[561,1122,1124,1127,1129,1132,1135,1138,1142,1144,1147],{"class":563,"line":1123},27,[561,1125,1126],{"class":639},"    es",[561,1128,444],{"class":567},[561,1130,1131],{"class":1081},"onmessage",[561,1133,1134],{"class":567}," =",[561,1136,1137],{"class":567}," (",[561,1139,1141],{"class":1140},"sHdIc","e",[561,1143,498],{"class":567},[561,1145,1146],{"class":575}," =>",[561,1148,1149],{"class":567}," {\n",[561,1151,1153,1156,1159,1161,1164,1166,1169,1171,1173,1175,1178],{"class":563,"line":1152},28,[561,1154,1155],{"class":575},"      const",[561,1157,1158],{"class":639}," env",[561,1160,1134],{"class":567},[561,1162,1163],{"class":639}," JSON",[561,1165,444],{"class":567},[561,1167,1168],{"class":1081},"parse",[561,1170,1085],{"class":571},[561,1172,1141],{"class":639},[561,1174,444],{"class":567},[561,1176,1177],{"class":639},"data",[561,1179,1096],{"class":571},[561,1181,1183,1187,1189,1192,1194,1197,1200,1202,1205,1207,1210],{"class":563,"line":1182},29,[561,1184,1186],{"class":1185},"s7zQu","      if",[561,1188,1137],{"class":571},[561,1190,1191],{"class":639},"env",[561,1193,444],{"class":567},[561,1195,1196],{"class":639},"evlog",[561,1198,1199],{"class":567}," !==",[561,1201,1057],{"class":567},[561,1203,1204],{"class":620},"1",[561,1206,1088],{"class":567},[561,1208,1209],{"class":571},") ",[561,1211,1212],{"class":1185},"return\n",[561,1214,1216,1218,1220,1222,1224,1226,1228,1230,1233,1235,1238,1240,1242,1244,1246,1248,1251,1253,1255],{"class":563,"line":1215},30,[561,1217,1186],{"class":1185},[561,1219,1137],{"class":571},[561,1221,1191],{"class":639},[561,1223,444],{"class":567},[561,1225,493],{"class":639},[561,1227,1199],{"class":567},[561,1229,1057],{"class":567},[561,1231,1232],{"class":620},"event",[561,1234,1088],{"class":567},[561,1236,1237],{"class":567}," &&",[561,1239,1158],{"class":639},[561,1241,444],{"class":567},[561,1243,493],{"class":639},[561,1245,1199],{"class":567},[561,1247,1057],{"class":567},[561,1249,1250],{"class":620},"replay",[561,1252,1088],{"class":567},[561,1254,1209],{"class":571},[561,1256,1212],{"class":1185},[561,1258,1260],{"class":563,"line":1259},31,[561,1261,1026],{"emptyLinePlaceholder":1025},[561,1263,1265,1267,1270,1272,1274,1276],{"class":563,"line":1264},32,[561,1266,1155],{"class":575},[561,1268,1269],{"class":639}," w",[561,1271,1134],{"class":567},[561,1273,1158],{"class":639},[561,1275,444],{"class":567},[561,1277,1278],{"class":639},"data\n",[561,1280,1282,1284,1287,1289,1291,1293,1296,1298,1300,1302,1304],{"class":563,"line":1281},33,[561,1283,1155],{"class":575},[561,1285,1286],{"class":639}," tr",[561,1288,1134],{"class":567},[561,1290,1076],{"class":639},[561,1292,444],{"class":567},[561,1294,1295],{"class":1081},"createElement",[561,1297,1085],{"class":571},[561,1299,1088],{"class":567},[561,1301,932],{"class":620},[561,1303,1088],{"class":567},[561,1305,1096],{"class":571},[561,1307,1309,1312,1314,1317,1319],{"class":563,"line":1308},34,[561,1310,1311],{"class":639},"      tr",[561,1313,444],{"class":567},[561,1315,1316],{"class":639},"innerHTML",[561,1318,1134],{"class":567},[561,1320,1321],{"class":567}," `\n",[561,1323,1325,1328,1331,1334,1337,1340,1342,1345,1347,1350,1353,1356],{"class":563,"line":1324},35,[561,1326,1327],{"class":620},"        \u003Ctd>",[561,1329,1330],{"class":567},"${",[561,1332,1333],{"class":567},"new",[561,1335,1336],{"class":1081}," Date",[561,1338,1339],{"class":639},"(w",[561,1341,444],{"class":567},[561,1343,1344],{"class":639},"timestamp)",[561,1346,444],{"class":567},[561,1348,1349],{"class":1081},"toLocaleTimeString",[561,1351,1352],{"class":639},"()",[561,1354,1355],{"class":567},"}",[561,1357,1358],{"class":620},"\u003C\u002Ftd>\n",[561,1360,1362,1365,1367,1370,1372,1374,1376,1379,1381,1383,1385,1387,1389],{"class":563,"line":1361},36,[561,1363,1364],{"class":620},"        \u003Ctd class=\"lvl-",[561,1366,1330],{"class":567},[561,1368,1369],{"class":639},"w",[561,1371,444],{"class":567},[561,1373,955],{"class":639},[561,1375,1355],{"class":567},[561,1377,1378],{"class":620},"\">",[561,1380,1330],{"class":567},[561,1382,1369],{"class":639},[561,1384,444],{"class":567},[561,1386,955],{"class":639},[561,1388,1355],{"class":567},[561,1390,1358],{"class":620},[561,1392,1394,1396,1398,1400,1402,1405,1408,1411],{"class":563,"line":1393},37,[561,1395,1327],{"class":620},[561,1397,1330],{"class":567},[561,1399,1369],{"class":639},[561,1401,444],{"class":567},[561,1403,1404],{"class":639},"service ",[561,1406,1407],{"class":567},"??",[561,1409,1410],{"class":567}," ''}",[561,1412,1358],{"class":620},[561,1414,1416,1418,1420,1422,1424,1427,1429,1431,1433,1436,1438,1440,1442,1445,1447,1449],{"class":563,"line":1415},38,[561,1417,1327],{"class":620},[561,1419,1330],{"class":567},[561,1421,1369],{"class":639},[561,1423,444],{"class":567},[561,1425,1426],{"class":639},"action ",[561,1428,1407],{"class":567},[561,1430,1269],{"class":639},[561,1432,444],{"class":567},[561,1434,1435],{"class":639},"message ",[561,1437,1407],{"class":567},[561,1439,1269],{"class":639},[561,1441,444],{"class":567},[561,1443,1444],{"class":639},"path ",[561,1446,1407],{"class":567},[561,1448,1410],{"class":567},[561,1450,1358],{"class":620},[561,1452,1454],{"class":563,"line":1453},39,[561,1455,1456],{"class":567},"      `\n",[561,1458,1460,1463,1465,1468,1470,1472],{"class":563,"line":1459},40,[561,1461,1462],{"class":639},"      tbody",[561,1464,444],{"class":567},[561,1466,1467],{"class":1081},"prepend",[561,1469,1085],{"class":571},[561,1471,932],{"class":639},[561,1473,1096],{"class":571},[561,1475,1477,1480,1482,1484,1486,1489,1491,1494,1497,1500,1502,1504,1506,1509,1511,1514],{"class":563,"line":1476},41,[561,1478,1479],{"class":1185},"      while",[561,1481,1137],{"class":571},[561,1483,1004],{"class":639},[561,1485,444],{"class":567},[561,1487,1488],{"class":639},"children",[561,1490,444],{"class":567},[561,1492,1493],{"class":639},"length",[561,1495,1496],{"class":567}," >",[561,1498,1499],{"class":677}," 200",[561,1501,1209],{"class":571},[561,1503,1004],{"class":639},[561,1505,444],{"class":567},[561,1507,1508],{"class":639},"lastElementChild",[561,1510,444],{"class":567},[561,1512,1513],{"class":1081},"remove",[561,1515,1516],{"class":571},"()\n",[561,1518,1520],{"class":563,"line":1519},42,[561,1521,1522],{"class":567},"    }\n",[561,1524,1526,1528,1530],{"class":563,"line":1525},43,[561,1527,872],{"class":567},[561,1529,1034],{"class":571},[561,1531,579],{"class":567},[561,1533,1535,1537,1539],{"class":563,"line":1534},44,[561,1536,643],{"class":567},[561,1538,893],{"class":571},[561,1540,579],{"class":567},[561,1542,1544,1546,1548],{"class":563,"line":1543},45,[561,1545,643],{"class":567},[561,1547,556],{"class":571},[561,1549,579],{"class":567},[433,1551,1552,1553,1556],{},"Save as ",[461,1554,1555],{},"devtool.html",", open in any browser tab while your evlog-instrumented dev server is running. That's the whole MVP.",[547,1558,1560],{"id":1559},"vue-3-component","Vue 3 component",[552,1562,1566],{"className":1563,"code":1564,"language":1565,"meta":557,"style":557},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003Cscript setup lang=\"ts\">\nimport { onBeforeUnmount, onMounted, ref } from 'vue'\nimport type { WideEvent } from 'evlog'\n\nconst events = ref\u003CWideEvent[]>([])\nlet es: EventSource | null = null\n\nonMounted(async () => {\n  \u002F\u002F Discover URL via the same-origin info endpoint (Nuxt)\n  const { url } = await $fetch\u003C{ url: string | null }>('\u002Fapi\u002F_evlog\u002Fstream-info')\n  if (!url) return\n\n  es = new EventSource(url)\n  es.onmessage = (e) => {\n    const env = JSON.parse(e.data)\n    if (env.evlog !== '1') return\n    if (env.type === 'event' || env.type === 'replay') {\n      events.value.unshift(env.data as WideEvent)\n      if (events.value.length > 500) events.value.length = 500\n    }\n  }\n})\n\nonBeforeUnmount(() => es?.close())\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cul>\n    \u003Cli v-for=\"(e, i) in events\" :key=\"`${e.timestamp}-${i}`\">\n      \u003Ccode>{{ e.level }}\u003C\u002Fcode>\n      \u003Cstrong>{{ e.service }}\u003C\u002Fstrong>\n      \u003Cspan>{{ e.action ?? e.message ?? e.path }}\u003C\u002Fspan>\n    \u003C\u002Fli>\n  \u003C\u002Ful>\n\u003C\u002Ftemplate>\n","vue",[461,1567,1568,1591,1623,1645,1649,1674,1697,1701,1718,1723,1770,1787,1791,1808,1828,1852,1877,1920,1950,1989,1993,1998,2004,2008,2030,2038,2042,2051,2059,2091,2109,2127,2144,2153,2161],{"__ignoreMap":557},[561,1569,1570,1572,1574,1577,1580,1582,1584,1587,1589],{"class":563,"line":564},[561,1571,585],{"class":567},[561,1573,1034],{"class":571},[561,1575,1576],{"class":575}," setup",[561,1578,1579],{"class":575}," lang",[561,1581,614],{"class":567},[561,1583,617],{"class":567},[561,1585,1586],{"class":620},"ts",[561,1588,617],{"class":567},[561,1590,579],{"class":567},[561,1592,1593,1596,1598,1601,1603,1606,1608,1611,1614,1617,1619,1621],{"class":563,"line":582},[561,1594,1595],{"class":1185},"import",[561,1597,667],{"class":567},[561,1599,1600],{"class":639}," onBeforeUnmount",[561,1602,684],{"class":567},[561,1604,1605],{"class":639}," onMounted",[561,1607,684],{"class":567},[561,1609,1610],{"class":639}," ref",[561,1612,1613],{"class":567}," }",[561,1615,1616],{"class":1185}," from",[561,1618,1057],{"class":567},[561,1620,1565],{"class":620},[561,1622,1063],{"class":567},[561,1624,1625,1627,1630,1632,1635,1637,1639,1641,1643],{"class":563,"line":592},[561,1626,1595],{"class":1185},[561,1628,1629],{"class":1185}," type",[561,1631,667],{"class":567},[561,1633,1634],{"class":639}," WideEvent",[561,1636,1613],{"class":567},[561,1638,1616],{"class":1185},[561,1640,1057],{"class":567},[561,1642,1196],{"class":620},[561,1644,1063],{"class":567},[561,1646,1647],{"class":563,"line":602},[561,1648,1026],{"emptyLinePlaceholder":1025},[561,1650,1651,1654,1657,1659,1661,1663,1666,1669,1671],{"class":563,"line":628},[561,1652,1653],{"class":575},"const",[561,1655,1656],{"class":639}," events ",[561,1658,614],{"class":567},[561,1660,1610],{"class":1081},[561,1662,585],{"class":567},[561,1664,1665],{"class":663},"WideEvent",[561,1667,1668],{"class":639},"[]",[561,1670,636],{"class":567},[561,1672,1673],{"class":639},"([])\n",[561,1675,1676,1679,1682,1684,1686,1689,1692,1694],{"class":563,"line":650},[561,1677,1678],{"class":575},"let",[561,1680,1681],{"class":639}," es",[561,1683,674],{"class":567},[561,1685,1112],{"class":663},[561,1687,1688],{"class":567}," |",[561,1690,1691],{"class":663}," null",[561,1693,1134],{"class":567},[561,1695,1696],{"class":567}," null\n",[561,1698,1699],{"class":563,"line":660},[561,1700,1026],{"emptyLinePlaceholder":1025},[561,1702,1703,1706,1708,1711,1714,1716],{"class":563,"line":715},[561,1704,1705],{"class":1081},"onMounted",[561,1707,1085],{"class":639},[561,1709,1710],{"class":575},"async",[561,1712,1713],{"class":567}," ()",[561,1715,1146],{"class":575},[561,1717,1149],{"class":567},[561,1719,1720],{"class":563,"line":745},[561,1721,1722],{"class":1042},"  \u002F\u002F Discover URL via the same-origin info endpoint (Nuxt)\n",[561,1724,1725,1728,1730,1733,1735,1737,1740,1743,1746,1748,1750,1753,1755,1757,1760,1762,1764,1766,1768],{"class":563,"line":801},[561,1726,1727],{"class":575},"  const",[561,1729,667],{"class":567},[561,1731,1732],{"class":639}," url",[561,1734,1613],{"class":567},[561,1736,1134],{"class":567},[561,1738,1739],{"class":1185}," await",[561,1741,1742],{"class":1081}," $fetch",[561,1744,1745],{"class":567},"\u003C{",[561,1747,1732],{"class":571},[561,1749,674],{"class":567},[561,1751,1752],{"class":663}," string",[561,1754,1688],{"class":567},[561,1756,1691],{"class":663},[561,1758,1759],{"class":567}," }>",[561,1761,1085],{"class":571},[561,1763,1088],{"class":567},[561,1765,536],{"class":620},[561,1767,1088],{"class":567},[561,1769,1096],{"class":571},[561,1771,1772,1775,1777,1780,1783,1785],{"class":563,"line":826},[561,1773,1774],{"class":1185},"  if",[561,1776,1137],{"class":571},[561,1778,1779],{"class":567},"!",[561,1781,1782],{"class":639},"url",[561,1784,1209],{"class":571},[561,1786,1212],{"class":1185},[561,1788,1789],{"class":563,"line":848},[561,1790,1026],{"emptyLinePlaceholder":1025},[561,1792,1793,1796,1798,1800,1802,1804,1806],{"class":563,"line":869},[561,1794,1795],{"class":639},"  es",[561,1797,1134],{"class":567},[561,1799,1109],{"class":567},[561,1801,1112],{"class":1081},[561,1803,1085],{"class":571},[561,1805,1782],{"class":639},[561,1807,1096],{"class":571},[561,1809,1810,1812,1814,1816,1818,1820,1822,1824,1826],{"class":563,"line":879},[561,1811,1795],{"class":639},[561,1813,444],{"class":567},[561,1815,1131],{"class":1081},[561,1817,1134],{"class":567},[561,1819,1137],{"class":567},[561,1821,1141],{"class":1140},[561,1823,498],{"class":567},[561,1825,1146],{"class":575},[561,1827,1149],{"class":567},[561,1829,1830,1832,1834,1836,1838,1840,1842,1844,1846,1848,1850],{"class":563,"line":888},[561,1831,1049],{"class":575},[561,1833,1158],{"class":639},[561,1835,1134],{"class":567},[561,1837,1163],{"class":639},[561,1839,444],{"class":567},[561,1841,1168],{"class":1081},[561,1843,1085],{"class":571},[561,1845,1141],{"class":639},[561,1847,444],{"class":567},[561,1849,1177],{"class":639},[561,1851,1096],{"class":571},[561,1853,1854,1857,1859,1861,1863,1865,1867,1869,1871,1873,1875],{"class":563,"line":898},[561,1855,1856],{"class":1185},"    if",[561,1858,1137],{"class":571},[561,1860,1191],{"class":639},[561,1862,444],{"class":567},[561,1864,1196],{"class":639},[561,1866,1199],{"class":567},[561,1868,1057],{"class":567},[561,1870,1204],{"class":620},[561,1872,1088],{"class":567},[561,1874,1209],{"class":571},[561,1876,1212],{"class":1185},[561,1878,1879,1881,1883,1885,1887,1889,1892,1894,1896,1898,1901,1903,1905,1907,1909,1911,1913,1915,1917],{"class":563,"line":920},[561,1880,1856],{"class":1185},[561,1882,1137],{"class":571},[561,1884,1191],{"class":639},[561,1886,444],{"class":567},[561,1888,493],{"class":639},[561,1890,1891],{"class":567}," ===",[561,1893,1057],{"class":567},[561,1895,1232],{"class":620},[561,1897,1088],{"class":567},[561,1899,1900],{"class":567}," ||",[561,1902,1158],{"class":639},[561,1904,444],{"class":567},[561,1906,493],{"class":639},[561,1908,1891],{"class":567},[561,1910,1057],{"class":567},[561,1912,1250],{"class":620},[561,1914,1088],{"class":567},[561,1916,1209],{"class":571},[561,1918,1919],{"class":567},"{\n",[561,1921,1922,1925,1927,1930,1932,1935,1937,1939,1941,1943,1946,1948],{"class":563,"line":999},[561,1923,1924],{"class":639},"      events",[561,1926,444],{"class":567},[561,1928,1929],{"class":639},"value",[561,1931,444],{"class":567},[561,1933,1934],{"class":1081},"unshift",[561,1936,1085],{"class":571},[561,1938,1191],{"class":639},[561,1940,444],{"class":567},[561,1942,1177],{"class":639},[561,1944,1945],{"class":1185}," as",[561,1947,1634],{"class":663},[561,1949,1096],{"class":571},[561,1951,1952,1954,1956,1959,1961,1963,1965,1967,1969,1972,1974,1976,1978,1980,1982,1984,1986],{"class":563,"line":1013},[561,1953,1186],{"class":1185},[561,1955,1137],{"class":571},[561,1957,1958],{"class":639},"events",[561,1960,444],{"class":567},[561,1962,1929],{"class":639},[561,1964,444],{"class":567},[561,1966,1493],{"class":639},[561,1968,1496],{"class":567},[561,1970,1971],{"class":677}," 500",[561,1973,1209],{"class":571},[561,1975,1958],{"class":639},[561,1977,444],{"class":567},[561,1979,1929],{"class":639},[561,1981,444],{"class":567},[561,1983,1493],{"class":639},[561,1985,1134],{"class":567},[561,1987,1988],{"class":677}," 500\n",[561,1990,1991],{"class":563,"line":1022},[561,1992,1522],{"class":567},[561,1994,1995],{"class":563,"line":1029},[561,1996,1997],{"class":567},"  }\n",[561,1999,2000,2002],{"class":563,"line":1039},[561,2001,1355],{"class":567},[561,2003,1096],{"class":639},[561,2005,2006],{"class":563,"line":1046},[561,2007,1026],{"emptyLinePlaceholder":1025},[561,2009,2010,2013,2015,2017,2019,2021,2024,2027],{"class":563,"line":1066},[561,2011,2012],{"class":1081},"onBeforeUnmount",[561,2014,1085],{"class":639},[561,2016,1352],{"class":567},[561,2018,1146],{"class":575},[561,2020,1681],{"class":639},[561,2022,2023],{"class":567},"?.",[561,2025,2026],{"class":1081},"close",[561,2028,2029],{"class":639},"())\n",[561,2031,2032,2034,2036],{"class":563,"line":1099},[561,2033,643],{"class":567},[561,2035,1034],{"class":571},[561,2037,579],{"class":567},[561,2039,2040],{"class":563,"line":1118},[561,2041,1026],{"emptyLinePlaceholder":1025},[561,2043,2044,2046,2049],{"class":563,"line":1123},[561,2045,585],{"class":567},[561,2047,2048],{"class":571},"template",[561,2050,579],{"class":567},[561,2052,2053,2055,2057],{"class":563,"line":1152},[561,2054,605],{"class":567},[561,2056,454],{"class":571},[561,2058,579],{"class":567},[561,2060,2061,2063,2065,2068,2070,2072,2075,2077,2080,2082,2084,2087,2089],{"class":563,"line":1182},[561,2062,923],{"class":567},[561,2064,457],{"class":571},[561,2066,2067],{"class":575}," v-for",[561,2069,614],{"class":567},[561,2071,617],{"class":567},[561,2073,2074],{"class":620},"(e, i) in events",[561,2076,617],{"class":567},[561,2078,2079],{"class":575}," :key",[561,2081,614],{"class":567},[561,2083,617],{"class":567},[561,2085,2086],{"class":620},"`${e.timestamp}-${i}`",[561,2088,617],{"class":567},[561,2090,579],{"class":567},[561,2092,2093,2096,2098,2100,2103,2105,2107],{"class":563,"line":1215},[561,2094,2095],{"class":567},"      \u003C",[561,2097,461],{"class":571},[561,2099,636],{"class":567},[561,2101,2102],{"class":639},"{{ e.level }}",[561,2104,643],{"class":567},[561,2106,461],{"class":571},[561,2108,579],{"class":567},[561,2110,2111,2113,2116,2118,2121,2123,2125],{"class":563,"line":1259},[561,2112,2095],{"class":567},[561,2114,2115],{"class":571},"strong",[561,2117,636],{"class":567},[561,2119,2120],{"class":639},"{{ e.service }}",[561,2122,643],{"class":567},[561,2124,2115],{"class":571},[561,2126,579],{"class":567},[561,2128,2129,2131,2133,2135,2138,2140,2142],{"class":563,"line":1264},[561,2130,2095],{"class":567},[561,2132,561],{"class":571},[561,2134,636],{"class":567},[561,2136,2137],{"class":639},"{{ e.action ?? e.message ?? e.path }}",[561,2139,643],{"class":567},[561,2141,561],{"class":571},[561,2143,579],{"class":567},[561,2145,2146,2149,2151],{"class":563,"line":1281},[561,2147,2148],{"class":567},"    \u003C\u002F",[561,2150,457],{"class":571},[561,2152,579],{"class":567},[561,2154,2155,2157,2159],{"class":563,"line":1308},[561,2156,872],{"class":567},[561,2158,454],{"class":571},[561,2160,579],{"class":567},[561,2162,2163,2165,2167],{"class":563,"line":1324},[561,2164,643],{"class":567},[561,2166,2048],{"class":571},[561,2168,579],{"class":567},[547,2170,2172],{"id":2171},"react-hook","React hook",[552,2174,2177],{"className":2175,"code":2176,"language":1586,"meta":557,"style":557},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { useEffect, useState } from 'react'\nimport type { WideEvent } from 'evlog'\n\nexport function useEvlogStream(url: string) {\n  const [events, setEvents] = useState\u003CWideEvent[]>([])\n\n  useEffect(() => {\n    if (!url) return\n    const es = new EventSource(url)\n    es.onmessage = (e) => {\n      const env = JSON.parse(e.data)\n      if (env.evlog !== '1') return\n      if (env.type === 'event' || env.type === 'replay') {\n        setEvents(prev => [env.data, ...prev].slice(0, 500))\n      }\n    }\n    return () => es.close()\n  }, [url])\n\n  return events\n}\n",[461,2178,2179,2204,2224,2228,2251,2282,2286,2299,2313,2331,2351,2375,2399,2439,2485,2490,2494,2511,2523,2527,2535],{"__ignoreMap":557},[561,2180,2181,2183,2185,2188,2190,2193,2195,2197,2199,2202],{"class":563,"line":564},[561,2182,1595],{"class":1185},[561,2184,667],{"class":567},[561,2186,2187],{"class":639}," useEffect",[561,2189,684],{"class":567},[561,2191,2192],{"class":639}," useState",[561,2194,1613],{"class":567},[561,2196,1616],{"class":1185},[561,2198,1057],{"class":567},[561,2200,2201],{"class":620},"react",[561,2203,1063],{"class":567},[561,2205,2206,2208,2210,2212,2214,2216,2218,2220,2222],{"class":563,"line":582},[561,2207,1595],{"class":1185},[561,2209,1629],{"class":1185},[561,2211,667],{"class":567},[561,2213,1634],{"class":639},[561,2215,1613],{"class":567},[561,2217,1616],{"class":1185},[561,2219,1057],{"class":567},[561,2221,1196],{"class":620},[561,2223,1063],{"class":567},[561,2225,2226],{"class":563,"line":592},[561,2227,1026],{"emptyLinePlaceholder":1025},[561,2229,2230,2233,2236,2239,2241,2243,2245,2247,2249],{"class":563,"line":602},[561,2231,2232],{"class":1185},"export",[561,2234,2235],{"class":575}," function",[561,2237,2238],{"class":1081}," useEvlogStream",[561,2240,1085],{"class":567},[561,2242,1782],{"class":1140},[561,2244,674],{"class":567},[561,2246,1752],{"class":663},[561,2248,498],{"class":567},[561,2250,1149],{"class":567},[561,2252,2253,2255,2258,2260,2262,2265,2268,2270,2272,2274,2276,2278,2280],{"class":563,"line":628},[561,2254,1727],{"class":575},[561,2256,2257],{"class":567}," [",[561,2259,1958],{"class":639},[561,2261,684],{"class":567},[561,2263,2264],{"class":639}," setEvents",[561,2266,2267],{"class":567},"]",[561,2269,1134],{"class":567},[561,2271,2192],{"class":1081},[561,2273,585],{"class":567},[561,2275,1665],{"class":663},[561,2277,1668],{"class":571},[561,2279,636],{"class":567},[561,2281,1673],{"class":571},[561,2283,2284],{"class":563,"line":650},[561,2285,1026],{"emptyLinePlaceholder":1025},[561,2287,2288,2291,2293,2295,2297],{"class":563,"line":660},[561,2289,2290],{"class":1081},"  useEffect",[561,2292,1085],{"class":571},[561,2294,1352],{"class":567},[561,2296,1146],{"class":575},[561,2298,1149],{"class":567},[561,2300,2301,2303,2305,2307,2309,2311],{"class":563,"line":715},[561,2302,1856],{"class":1185},[561,2304,1137],{"class":571},[561,2306,1779],{"class":567},[561,2308,1782],{"class":639},[561,2310,1209],{"class":571},[561,2312,1212],{"class":1185},[561,2314,2315,2317,2319,2321,2323,2325,2327,2329],{"class":563,"line":745},[561,2316,1049],{"class":575},[561,2318,1681],{"class":639},[561,2320,1134],{"class":567},[561,2322,1109],{"class":567},[561,2324,1112],{"class":1081},[561,2326,1085],{"class":571},[561,2328,1782],{"class":639},[561,2330,1096],{"class":571},[561,2332,2333,2335,2337,2339,2341,2343,2345,2347,2349],{"class":563,"line":801},[561,2334,1126],{"class":639},[561,2336,444],{"class":567},[561,2338,1131],{"class":1081},[561,2340,1134],{"class":567},[561,2342,1137],{"class":567},[561,2344,1141],{"class":1140},[561,2346,498],{"class":567},[561,2348,1146],{"class":575},[561,2350,1149],{"class":567},[561,2352,2353,2355,2357,2359,2361,2363,2365,2367,2369,2371,2373],{"class":563,"line":826},[561,2354,1155],{"class":575},[561,2356,1158],{"class":639},[561,2358,1134],{"class":567},[561,2360,1163],{"class":639},[561,2362,444],{"class":567},[561,2364,1168],{"class":1081},[561,2366,1085],{"class":571},[561,2368,1141],{"class":639},[561,2370,444],{"class":567},[561,2372,1177],{"class":639},[561,2374,1096],{"class":571},[561,2376,2377,2379,2381,2383,2385,2387,2389,2391,2393,2395,2397],{"class":563,"line":848},[561,2378,1186],{"class":1185},[561,2380,1137],{"class":571},[561,2382,1191],{"class":639},[561,2384,444],{"class":567},[561,2386,1196],{"class":639},[561,2388,1199],{"class":567},[561,2390,1057],{"class":567},[561,2392,1204],{"class":620},[561,2394,1088],{"class":567},[561,2396,1209],{"class":571},[561,2398,1212],{"class":1185},[561,2400,2401,2403,2405,2407,2409,2411,2413,2415,2417,2419,2421,2423,2425,2427,2429,2431,2433,2435,2437],{"class":563,"line":869},[561,2402,1186],{"class":1185},[561,2404,1137],{"class":571},[561,2406,1191],{"class":639},[561,2408,444],{"class":567},[561,2410,493],{"class":639},[561,2412,1891],{"class":567},[561,2414,1057],{"class":567},[561,2416,1232],{"class":620},[561,2418,1088],{"class":567},[561,2420,1900],{"class":567},[561,2422,1158],{"class":639},[561,2424,444],{"class":567},[561,2426,493],{"class":639},[561,2428,1891],{"class":567},[561,2430,1057],{"class":567},[561,2432,1250],{"class":620},[561,2434,1088],{"class":567},[561,2436,1209],{"class":571},[561,2438,1919],{"class":567},[561,2440,2441,2444,2446,2449,2451,2453,2455,2457,2459,2461,2464,2466,2468,2470,2473,2475,2478,2480,2482],{"class":563,"line":879},[561,2442,2443],{"class":1081},"        setEvents",[561,2445,1085],{"class":571},[561,2447,2448],{"class":1140},"prev",[561,2450,1146],{"class":575},[561,2452,2257],{"class":571},[561,2454,1191],{"class":639},[561,2456,444],{"class":567},[561,2458,1177],{"class":639},[561,2460,684],{"class":567},[561,2462,2463],{"class":567}," ...",[561,2465,2448],{"class":639},[561,2467,2267],{"class":571},[561,2469,444],{"class":567},[561,2471,2472],{"class":1081},"slice",[561,2474,1085],{"class":571},[561,2476,2477],{"class":677},"0",[561,2479,684],{"class":567},[561,2481,1971],{"class":677},[561,2483,2484],{"class":571},"))\n",[561,2486,2487],{"class":563,"line":888},[561,2488,2489],{"class":567},"      }\n",[561,2491,2492],{"class":563,"line":898},[561,2493,1522],{"class":567},[561,2495,2496,2499,2501,2503,2505,2507,2509],{"class":563,"line":920},[561,2497,2498],{"class":1185},"    return",[561,2500,1713],{"class":567},[561,2502,1146],{"class":575},[561,2504,1681],{"class":639},[561,2506,444],{"class":567},[561,2508,2026],{"class":1081},[561,2510,1516],{"class":571},[561,2512,2513,2516,2518,2520],{"class":563,"line":999},[561,2514,2515],{"class":567},"  },",[561,2517,2257],{"class":571},[561,2519,1782],{"class":639},[561,2521,2522],{"class":571},"])\n",[561,2524,2525],{"class":563,"line":1013},[561,2526,1026],{"emptyLinePlaceholder":1025},[561,2528,2529,2532],{"class":563,"line":1022},[561,2530,2531],{"class":1185},"  return",[561,2533,2534],{"class":639}," events\n",[561,2536,2537],{"class":563,"line":1029},[561,2538,823],{"class":567},[433,2540,2541,2542,2544,2545,444],{},"That's the entire integration surface. No SDK, no special types beyond ",[461,2543,1665],{}," exported from ",[461,2546,1196],{},[521,2548,2550],{"id":2549},"_2-quick-cli-inspection-with-curl-jq","2. Quick CLI inspection with curl + jq",[433,2552,2553,2554,674],{},"The URL is in ",[461,2555,474],{},[552,2557,2561],{"className":2558,"code":2559,"language":2560,"meta":557,"style":557},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","URL=$(cat .evlog\u002Fstream.url)\ncurl -N \"$URL\" | jq -c 'select(.type == \"event\") | .data'\n","bash",[461,2562,2563,2579],{"__ignoreMap":557},[561,2564,2565,2568,2571,2574,2577],{"class":563,"line":564},[561,2566,2567],{"class":639},"URL",[561,2569,2570],{"class":567},"=$(",[561,2572,2573],{"class":663},"cat",[561,2575,2576],{"class":620}," .evlog\u002Fstream.url",[561,2578,1096],{"class":567},[561,2580,2581,2584,2587,2590,2593,2595,2597,2600,2603,2605,2608],{"class":563,"line":582},[561,2582,2583],{"class":663},"curl",[561,2585,2586],{"class":620}," -N",[561,2588,2589],{"class":567}," \"",[561,2591,2592],{"class":639},"$URL",[561,2594,617],{"class":567},[561,2596,1688],{"class":567},[561,2598,2599],{"class":663}," jq",[561,2601,2602],{"class":620}," -c",[561,2604,1057],{"class":567},[561,2606,2607],{"class":620},"select(.type == \"event\") | .data",[561,2609,1063],{"class":567},[433,2611,2612],{},"Filter on the client side as needed:",[552,2614,2616],{"className":2558,"code":2615,"language":2560,"meta":557,"style":557},"# Only errors\ncurl -sN \"$URL\" | jq -c 'select(.type == \"event\" and .data.level == \"error\") | .data'\n\n# Only one service\ncurl -sN \"$URL\" | jq -c 'select(.type == \"event\" and .data.service == \"checkout\") | .data'\n\n# Slow requests\ncurl -sN \"$URL\" | jq -c 'select(.type == \"event\" and .data.duration > 500) | .data'\n",[461,2617,2618,2623,2649,2653,2658,2683,2687,2692],{"__ignoreMap":557},[561,2619,2620],{"class":563,"line":564},[561,2621,2622],{"class":1042},"# Only errors\n",[561,2624,2625,2627,2630,2632,2634,2636,2638,2640,2642,2644,2647],{"class":563,"line":582},[561,2626,2583],{"class":663},[561,2628,2629],{"class":620}," -sN",[561,2631,2589],{"class":567},[561,2633,2592],{"class":639},[561,2635,617],{"class":567},[561,2637,1688],{"class":567},[561,2639,2599],{"class":663},[561,2641,2602],{"class":620},[561,2643,1057],{"class":567},[561,2645,2646],{"class":620},"select(.type == \"event\" and .data.level == \"error\") | .data",[561,2648,1063],{"class":567},[561,2650,2651],{"class":563,"line":592},[561,2652,1026],{"emptyLinePlaceholder":1025},[561,2654,2655],{"class":563,"line":602},[561,2656,2657],{"class":1042},"# Only one service\n",[561,2659,2660,2662,2664,2666,2668,2670,2672,2674,2676,2678,2681],{"class":563,"line":628},[561,2661,2583],{"class":663},[561,2663,2629],{"class":620},[561,2665,2589],{"class":567},[561,2667,2592],{"class":639},[561,2669,617],{"class":567},[561,2671,1688],{"class":567},[561,2673,2599],{"class":663},[561,2675,2602],{"class":620},[561,2677,1057],{"class":567},[561,2679,2680],{"class":620},"select(.type == \"event\" and .data.service == \"checkout\") | .data",[561,2682,1063],{"class":567},[561,2684,2685],{"class":563,"line":650},[561,2686,1026],{"emptyLinePlaceholder":1025},[561,2688,2689],{"class":563,"line":660},[561,2690,2691],{"class":1042},"# Slow requests\n",[561,2693,2694,2696,2698,2700,2702,2704,2706,2708,2710,2712,2715],{"class":563,"line":715},[561,2695,2583],{"class":663},[561,2697,2629],{"class":620},[561,2699,2589],{"class":567},[561,2701,2592],{"class":639},[561,2703,617],{"class":567},[561,2705,1688],{"class":567},[561,2707,2599],{"class":663},[561,2709,2602],{"class":620},[561,2711,1057],{"class":567},[561,2713,2714],{"class":620},"select(.type == \"event\" and .data.duration > 500) | .data",[561,2716,1063],{"class":567},[433,2718,2719,2722,2723,2725,2726,2729],{},[461,2720,2721],{},"-N"," keeps ",[461,2724,2583],{}," in streaming mode (no buffering). ",[461,2727,2728],{},"-s"," is silent.",[521,2731,2733],{"id":2732},"_3-replay-history-then-go-live","3. Replay history then go live",[433,2735,2736],{},"History on disk (filesystem drain) + live updates from the stream server = a full picture from any point in time.",[552,2738,2740],{"className":2175,"code":2739,"language":1586,"meta":557,"style":557},"import { readFsLogs } from 'evlog\u002Ffs'\nimport { readFile } from 'node:fs\u002Fpromises'\nimport type { WideEvent } from 'evlog'\n\nasync function bootstrap(handle: (e: WideEvent) => void) {\n  \u002F\u002F 1. Replay the last hour from `.evlog\u002Flogs\u002F`\n  const since = new Date(Date.now() - 60 * 60 * 1000)\n  for await (const event of readFsLogs({ since })) {\n    handle(event)\n  }\n\n  \u002F\u002F 2. Switch to the live SSE stream\n  const url = (await readFile('.evlog\u002Fstream.url', 'utf-8')).trim()\n  const es = new EventSource(url)\n  es.onmessage = (e) => {\n    const env = JSON.parse(e.data)\n    if (env.evlog !== '1') return\n    if (env.type === 'event' || env.type === 'replay') {\n      handle(env.data)\n    }\n  }\n  return () => es.close()\n}\n",[461,2741,2742,2762,2782,2802,2806,2841,2846,2890,2923,2934,2938,2942,2947,2988,3006,3026,3050,3074,3114,3129,3133,3137,3153],{"__ignoreMap":557},[561,2743,2744,2746,2748,2751,2753,2755,2757,2760],{"class":563,"line":564},[561,2745,1595],{"class":1185},[561,2747,667],{"class":567},[561,2749,2750],{"class":639}," readFsLogs",[561,2752,1613],{"class":567},[561,2754,1616],{"class":1185},[561,2756,1057],{"class":567},[561,2758,2759],{"class":620},"evlog\u002Ffs",[561,2761,1063],{"class":567},[561,2763,2764,2766,2768,2771,2773,2775,2777,2780],{"class":563,"line":582},[561,2765,1595],{"class":1185},[561,2767,667],{"class":567},[561,2769,2770],{"class":639}," readFile",[561,2772,1613],{"class":567},[561,2774,1616],{"class":1185},[561,2776,1057],{"class":567},[561,2778,2779],{"class":620},"node:fs\u002Fpromises",[561,2781,1063],{"class":567},[561,2783,2784,2786,2788,2790,2792,2794,2796,2798,2800],{"class":563,"line":592},[561,2785,1595],{"class":1185},[561,2787,1629],{"class":1185},[561,2789,667],{"class":567},[561,2791,1634],{"class":639},[561,2793,1613],{"class":567},[561,2795,1616],{"class":1185},[561,2797,1057],{"class":567},[561,2799,1196],{"class":620},[561,2801,1063],{"class":567},[561,2803,2804],{"class":563,"line":602},[561,2805,1026],{"emptyLinePlaceholder":1025},[561,2807,2808,2810,2812,2815,2817,2820,2822,2824,2826,2828,2830,2832,2834,2837,2839],{"class":563,"line":628},[561,2809,1710],{"class":575},[561,2811,2235],{"class":575},[561,2813,2814],{"class":1081}," bootstrap",[561,2816,1085],{"class":567},[561,2818,2819],{"class":1081},"handle",[561,2821,674],{"class":567},[561,2823,1137],{"class":567},[561,2825,1141],{"class":1140},[561,2827,674],{"class":567},[561,2829,1634],{"class":663},[561,2831,498],{"class":567},[561,2833,1146],{"class":575},[561,2835,2836],{"class":663}," void",[561,2838,498],{"class":567},[561,2840,1149],{"class":567},[561,2842,2843],{"class":563,"line":650},[561,2844,2845],{"class":1042},"  \u002F\u002F 1. Replay the last hour from `.evlog\u002Flogs\u002F`\n",[561,2847,2848,2850,2853,2855,2857,2859,2861,2864,2866,2869,2872,2875,2878,2881,2883,2885,2888],{"class":563,"line":660},[561,2849,1727],{"class":575},[561,2851,2852],{"class":639}," since",[561,2854,1134],{"class":567},[561,2856,1109],{"class":567},[561,2858,1336],{"class":1081},[561,2860,1085],{"class":571},[561,2862,2863],{"class":639},"Date",[561,2865,444],{"class":567},[561,2867,2868],{"class":1081},"now",[561,2870,2871],{"class":571},"() ",[561,2873,2874],{"class":567},"-",[561,2876,2877],{"class":677}," 60",[561,2879,2880],{"class":567}," *",[561,2882,2877],{"class":677},[561,2884,2880],{"class":567},[561,2886,2887],{"class":677}," 1000",[561,2889,1096],{"class":571},[561,2891,2892,2895,2897,2899,2901,2904,2907,2909,2911,2914,2916,2918,2921],{"class":563,"line":715},[561,2893,2894],{"class":1185},"  for",[561,2896,1739],{"class":1185},[561,2898,1137],{"class":571},[561,2900,1653],{"class":575},[561,2902,2903],{"class":639}," event",[561,2905,2906],{"class":567}," of",[561,2908,2750],{"class":1081},[561,2910,1085],{"class":571},[561,2912,2913],{"class":567},"{",[561,2915,2852],{"class":639},[561,2917,1613],{"class":567},[561,2919,2920],{"class":571},")) ",[561,2922,1919],{"class":567},[561,2924,2925,2928,2930,2932],{"class":563,"line":745},[561,2926,2927],{"class":1081},"    handle",[561,2929,1085],{"class":571},[561,2931,1232],{"class":639},[561,2933,1096],{"class":571},[561,2935,2936],{"class":563,"line":801},[561,2937,1997],{"class":567},[561,2939,2940],{"class":563,"line":826},[561,2941,1026],{"emptyLinePlaceholder":1025},[561,2943,2944],{"class":563,"line":848},[561,2945,2946],{"class":1042},"  \u002F\u002F 2. Switch to the live SSE stream\n",[561,2948,2949,2951,2953,2955,2957,2960,2962,2964,2966,2968,2970,2972,2974,2976,2978,2981,2983,2986],{"class":563,"line":869},[561,2950,1727],{"class":575},[561,2952,1732],{"class":639},[561,2954,1134],{"class":567},[561,2956,1137],{"class":571},[561,2958,2959],{"class":1185},"await",[561,2961,2770],{"class":1081},[561,2963,1085],{"class":571},[561,2965,1088],{"class":567},[561,2967,474],{"class":620},[561,2969,1088],{"class":567},[561,2971,684],{"class":567},[561,2973,1057],{"class":567},[561,2975,621],{"class":620},[561,2977,1088],{"class":567},[561,2979,2980],{"class":571},"))",[561,2982,444],{"class":567},[561,2984,2985],{"class":1081},"trim",[561,2987,1516],{"class":571},[561,2989,2990,2992,2994,2996,2998,3000,3002,3004],{"class":563,"line":879},[561,2991,1727],{"class":575},[561,2993,1681],{"class":639},[561,2995,1134],{"class":567},[561,2997,1109],{"class":567},[561,2999,1112],{"class":1081},[561,3001,1085],{"class":571},[561,3003,1782],{"class":639},[561,3005,1096],{"class":571},[561,3007,3008,3010,3012,3014,3016,3018,3020,3022,3024],{"class":563,"line":888},[561,3009,1795],{"class":639},[561,3011,444],{"class":567},[561,3013,1131],{"class":1081},[561,3015,1134],{"class":567},[561,3017,1137],{"class":567},[561,3019,1141],{"class":1140},[561,3021,498],{"class":567},[561,3023,1146],{"class":575},[561,3025,1149],{"class":567},[561,3027,3028,3030,3032,3034,3036,3038,3040,3042,3044,3046,3048],{"class":563,"line":898},[561,3029,1049],{"class":575},[561,3031,1158],{"class":639},[561,3033,1134],{"class":567},[561,3035,1163],{"class":639},[561,3037,444],{"class":567},[561,3039,1168],{"class":1081},[561,3041,1085],{"class":571},[561,3043,1141],{"class":639},[561,3045,444],{"class":567},[561,3047,1177],{"class":639},[561,3049,1096],{"class":571},[561,3051,3052,3054,3056,3058,3060,3062,3064,3066,3068,3070,3072],{"class":563,"line":920},[561,3053,1856],{"class":1185},[561,3055,1137],{"class":571},[561,3057,1191],{"class":639},[561,3059,444],{"class":567},[561,3061,1196],{"class":639},[561,3063,1199],{"class":567},[561,3065,1057],{"class":567},[561,3067,1204],{"class":620},[561,3069,1088],{"class":567},[561,3071,1209],{"class":571},[561,3073,1212],{"class":1185},[561,3075,3076,3078,3080,3082,3084,3086,3088,3090,3092,3094,3096,3098,3100,3102,3104,3106,3108,3110,3112],{"class":563,"line":999},[561,3077,1856],{"class":1185},[561,3079,1137],{"class":571},[561,3081,1191],{"class":639},[561,3083,444],{"class":567},[561,3085,493],{"class":639},[561,3087,1891],{"class":567},[561,3089,1057],{"class":567},[561,3091,1232],{"class":620},[561,3093,1088],{"class":567},[561,3095,1900],{"class":567},[561,3097,1158],{"class":639},[561,3099,444],{"class":567},[561,3101,493],{"class":639},[561,3103,1891],{"class":567},[561,3105,1057],{"class":567},[561,3107,1250],{"class":620},[561,3109,1088],{"class":567},[561,3111,1209],{"class":571},[561,3113,1919],{"class":567},[561,3115,3116,3119,3121,3123,3125,3127],{"class":563,"line":1013},[561,3117,3118],{"class":1081},"      handle",[561,3120,1085],{"class":571},[561,3122,1191],{"class":639},[561,3124,444],{"class":567},[561,3126,1177],{"class":639},[561,3128,1096],{"class":571},[561,3130,3131],{"class":563,"line":1022},[561,3132,1522],{"class":567},[561,3134,3135],{"class":563,"line":1029},[561,3136,1997],{"class":567},[561,3138,3139,3141,3143,3145,3147,3149,3151],{"class":563,"line":1039},[561,3140,2531],{"class":1185},[561,3142,1713],{"class":567},[561,3144,1146],{"class":575},[561,3146,1681],{"class":639},[561,3148,444],{"class":567},[561,3150,2026],{"class":1081},[561,3152,1516],{"class":571},[561,3154,3155],{"class":563,"line":1046},[561,3156,823],{"class":567},[433,3158,3159,3161,3162,3165],{},[461,3160,463],{}," skips files outside the date range, so the replay step is fast even if you keep weeks of history. For a tail-only mode without on-disk replay, hit the stream server with ",[461,3163,3164],{},"?since=\u003Ciso>"," to reuse the in-process ring buffer instead.",[521,3167,3169],{"id":3168},"_4-node-bun-client-fetch-readablestream","4. Node \u002F Bun client (fetch + ReadableStream)",[433,3171,3172,3173,3175],{},"Same protocol, no ",[461,3174,485],{}," polyfill needed:",[552,3177,3179],{"className":2175,"code":3178,"language":1586,"meta":557,"style":557},"import { readFile } from 'node:fs\u002Fpromises'\n\nconst url = (await readFile('.evlog\u002Fstream.url', 'utf-8')).trim()\nconst res = await fetch(url)\nconst reader = res.body!.getReader()\nconst decoder = new TextDecoder()\nlet buffer = ''\n\nwhile (true) {\n  const { value, done } = await reader.read()\n  if (done) break\n  buffer += decoder.decode(value, { stream: true })\n\n  let idx\n  while ((idx = buffer.indexOf('\\n\\n')) !== -1) {\n    const frame = buffer.slice(0, idx)\n    buffer = buffer.slice(idx + 2)\n    const dataLine = frame.split('\\n').find(l => l.startsWith('data:'))\n    if (!dataLine) continue\n    const env = JSON.parse(dataLine.slice(5).trim())\n    if (env.type === 'event') console.log(env.data)\n  }\n}\n",[461,3180,3181,3199,3203,3242,3259,3283,3299,3311,3315,3330,3360,3374,3410,3414,3422,3466,3492,3517,3575,3591,3626,3666,3670],{"__ignoreMap":557},[561,3182,3183,3185,3187,3189,3191,3193,3195,3197],{"class":563,"line":564},[561,3184,1595],{"class":1185},[561,3186,667],{"class":567},[561,3188,2770],{"class":639},[561,3190,1613],{"class":567},[561,3192,1616],{"class":1185},[561,3194,1057],{"class":567},[561,3196,2779],{"class":620},[561,3198,1063],{"class":567},[561,3200,3201],{"class":563,"line":582},[561,3202,1026],{"emptyLinePlaceholder":1025},[561,3204,3205,3207,3210,3212,3214,3216,3218,3220,3222,3224,3226,3228,3230,3232,3234,3236,3238,3240],{"class":563,"line":592},[561,3206,1653],{"class":575},[561,3208,3209],{"class":639}," url ",[561,3211,614],{"class":567},[561,3213,1137],{"class":639},[561,3215,2959],{"class":1185},[561,3217,2770],{"class":1081},[561,3219,1085],{"class":639},[561,3221,1088],{"class":567},[561,3223,474],{"class":620},[561,3225,1088],{"class":567},[561,3227,684],{"class":567},[561,3229,1057],{"class":567},[561,3231,621],{"class":620},[561,3233,1088],{"class":567},[561,3235,2980],{"class":639},[561,3237,444],{"class":567},[561,3239,2985],{"class":1081},[561,3241,1516],{"class":639},[561,3243,3244,3246,3249,3251,3253,3256],{"class":563,"line":602},[561,3245,1653],{"class":575},[561,3247,3248],{"class":639}," res ",[561,3250,614],{"class":567},[561,3252,1739],{"class":1185},[561,3254,3255],{"class":1081}," fetch",[561,3257,3258],{"class":639},"(url)\n",[561,3260,3261,3263,3266,3268,3271,3273,3275,3278,3281],{"class":563,"line":628},[561,3262,1653],{"class":575},[561,3264,3265],{"class":639}," reader ",[561,3267,614],{"class":567},[561,3269,3270],{"class":639}," res",[561,3272,444],{"class":567},[561,3274,893],{"class":639},[561,3276,3277],{"class":567},"!.",[561,3279,3280],{"class":1081},"getReader",[561,3282,1516],{"class":639},[561,3284,3285,3287,3290,3292,3294,3297],{"class":563,"line":650},[561,3286,1653],{"class":575},[561,3288,3289],{"class":639}," decoder ",[561,3291,614],{"class":567},[561,3293,1109],{"class":567},[561,3295,3296],{"class":1081}," TextDecoder",[561,3298,1516],{"class":639},[561,3300,3301,3303,3306,3308],{"class":563,"line":660},[561,3302,1678],{"class":575},[561,3304,3305],{"class":639}," buffer ",[561,3307,614],{"class":567},[561,3309,3310],{"class":567}," ''\n",[561,3312,3313],{"class":563,"line":715},[561,3314,1026],{"emptyLinePlaceholder":1025},[561,3316,3317,3320,3322,3326,3328],{"class":563,"line":745},[561,3318,3319],{"class":1185},"while",[561,3321,1137],{"class":639},[561,3323,3325],{"class":3324},"sfNiH","true",[561,3327,1209],{"class":639},[561,3329,1919],{"class":567},[561,3331,3332,3334,3336,3339,3341,3344,3346,3348,3350,3353,3355,3358],{"class":563,"line":801},[561,3333,1727],{"class":575},[561,3335,667],{"class":567},[561,3337,3338],{"class":639}," value",[561,3340,684],{"class":567},[561,3342,3343],{"class":639}," done",[561,3345,1613],{"class":567},[561,3347,1134],{"class":567},[561,3349,1739],{"class":1185},[561,3351,3352],{"class":639}," reader",[561,3354,444],{"class":567},[561,3356,3357],{"class":1081},"read",[561,3359,1516],{"class":571},[561,3361,3362,3364,3366,3369,3371],{"class":563,"line":826},[561,3363,1774],{"class":1185},[561,3365,1137],{"class":571},[561,3367,3368],{"class":639},"done",[561,3370,1209],{"class":571},[561,3372,3373],{"class":1185},"break\n",[561,3375,3376,3379,3382,3385,3387,3390,3392,3394,3396,3398,3401,3403,3406,3408],{"class":563,"line":848},[561,3377,3378],{"class":639},"  buffer",[561,3380,3381],{"class":567}," +=",[561,3383,3384],{"class":639}," decoder",[561,3386,444],{"class":567},[561,3388,3389],{"class":1081},"decode",[561,3391,1085],{"class":571},[561,3393,1929],{"class":639},[561,3395,684],{"class":567},[561,3397,667],{"class":567},[561,3399,3400],{"class":571}," stream",[561,3402,674],{"class":567},[561,3404,3405],{"class":3324}," true",[561,3407,1613],{"class":567},[561,3409,1096],{"class":571},[561,3411,3412],{"class":563,"line":869},[561,3413,1026],{"emptyLinePlaceholder":1025},[561,3415,3416,3419],{"class":563,"line":879},[561,3417,3418],{"class":575},"  let",[561,3420,3421],{"class":639}," idx\n",[561,3423,3424,3427,3430,3433,3435,3438,3440,3443,3445,3447,3450,3452,3454,3457,3460,3462,3464],{"class":563,"line":888},[561,3425,3426],{"class":1185},"  while",[561,3428,3429],{"class":571}," ((",[561,3431,3432],{"class":639},"idx",[561,3434,1134],{"class":567},[561,3436,3437],{"class":639}," buffer",[561,3439,444],{"class":567},[561,3441,3442],{"class":1081},"indexOf",[561,3444,1085],{"class":571},[561,3446,1088],{"class":567},[561,3448,3449],{"class":639},"\\n\\n",[561,3451,1088],{"class":567},[561,3453,2920],{"class":571},[561,3455,3456],{"class":567},"!==",[561,3458,3459],{"class":567}," -",[561,3461,1204],{"class":677},[561,3463,1209],{"class":571},[561,3465,1919],{"class":567},[561,3467,3468,3470,3473,3475,3477,3479,3481,3483,3485,3487,3490],{"class":563,"line":898},[561,3469,1049],{"class":575},[561,3471,3472],{"class":639}," frame",[561,3474,1134],{"class":567},[561,3476,3437],{"class":639},[561,3478,444],{"class":567},[561,3480,2472],{"class":1081},[561,3482,1085],{"class":571},[561,3484,2477],{"class":677},[561,3486,684],{"class":567},[561,3488,3489],{"class":639}," idx",[561,3491,1096],{"class":571},[561,3493,3494,3497,3499,3501,3503,3505,3507,3509,3512,3515],{"class":563,"line":920},[561,3495,3496],{"class":639},"    buffer",[561,3498,1134],{"class":567},[561,3500,3437],{"class":639},[561,3502,444],{"class":567},[561,3504,2472],{"class":1081},[561,3506,1085],{"class":571},[561,3508,3432],{"class":639},[561,3510,3511],{"class":567}," +",[561,3513,3514],{"class":677}," 2",[561,3516,1096],{"class":571},[561,3518,3519,3521,3524,3526,3528,3530,3533,3535,3537,3540,3542,3544,3546,3549,3551,3554,3556,3559,3561,3564,3566,3568,3571,3573],{"class":563,"line":999},[561,3520,1049],{"class":575},[561,3522,3523],{"class":639}," dataLine",[561,3525,1134],{"class":567},[561,3527,3472],{"class":639},[561,3529,444],{"class":567},[561,3531,3532],{"class":1081},"split",[561,3534,1085],{"class":571},[561,3536,1088],{"class":567},[561,3538,3539],{"class":639},"\\n",[561,3541,1088],{"class":567},[561,3543,498],{"class":571},[561,3545,444],{"class":567},[561,3547,3548],{"class":1081},"find",[561,3550,1085],{"class":571},[561,3552,3553],{"class":1140},"l",[561,3555,1146],{"class":575},[561,3557,3558],{"class":639}," l",[561,3560,444],{"class":567},[561,3562,3563],{"class":1081},"startsWith",[561,3565,1085],{"class":571},[561,3567,1088],{"class":567},[561,3569,3570],{"class":620},"data:",[561,3572,1088],{"class":567},[561,3574,2484],{"class":571},[561,3576,3577,3579,3581,3583,3586,3588],{"class":563,"line":1013},[561,3578,1856],{"class":1185},[561,3580,1137],{"class":571},[561,3582,1779],{"class":567},[561,3584,3585],{"class":639},"dataLine",[561,3587,1209],{"class":571},[561,3589,3590],{"class":1185},"continue\n",[561,3592,3593,3595,3597,3599,3601,3603,3605,3607,3609,3611,3613,3615,3618,3620,3622,3624],{"class":563,"line":1022},[561,3594,1049],{"class":575},[561,3596,1158],{"class":639},[561,3598,1134],{"class":567},[561,3600,1163],{"class":639},[561,3602,444],{"class":567},[561,3604,1168],{"class":1081},[561,3606,1085],{"class":571},[561,3608,3585],{"class":639},[561,3610,444],{"class":567},[561,3612,2472],{"class":1081},[561,3614,1085],{"class":571},[561,3616,3617],{"class":677},"5",[561,3619,498],{"class":571},[561,3621,444],{"class":567},[561,3623,2985],{"class":1081},[561,3625,2029],{"class":571},[561,3627,3628,3630,3632,3634,3636,3638,3640,3642,3644,3646,3648,3651,3653,3656,3658,3660,3662,3664],{"class":563,"line":1029},[561,3629,1856],{"class":1185},[561,3631,1137],{"class":571},[561,3633,1191],{"class":639},[561,3635,444],{"class":567},[561,3637,493],{"class":639},[561,3639,1891],{"class":567},[561,3641,1057],{"class":567},[561,3643,1232],{"class":620},[561,3645,1088],{"class":567},[561,3647,1209],{"class":571},[561,3649,3650],{"class":639},"console",[561,3652,444],{"class":567},[561,3654,3655],{"class":1081},"log",[561,3657,1085],{"class":571},[561,3659,1191],{"class":639},[561,3661,444],{"class":567},[561,3663,1177],{"class":639},[561,3665,1096],{"class":571},[561,3667,3668],{"class":563,"line":1039},[561,3669,1997],{"class":567},[561,3671,3672],{"class":563,"line":1046},[561,3673,823],{"class":567},[521,3675,3677],{"id":3676},"_5-filter-transform-aggregate-on-the-consumer","5. Filter, transform, aggregate on the consumer",[433,3679,3680],{},"Keep the server dumb — every consumer picks what it cares about:",[552,3682,3684],{"className":2175,"code":3683,"language":1586,"meta":557,"style":557},"\u002F\u002F Just errors\nconst errors = events.filter(e => e.level === 'error')\n\n\u002F\u002F Slow requests\nconst slowReqs = events.filter(e => typeof e.duration === 'number' && e.duration > 500)\n\n\u002F\u002F Group by service\nconst byService = Object.groupBy(events, e => e.service)\n\n\u002F\u002F Rolling error rate (last 100 events)\nconst last100 = events.slice(0, 100)\nconst errorRate = last100.filter(e => e.level === 'error').length \u002F last100.length\n\n\u002F\u002F Ad-hoc cost analytics — works because evlog\u002Fai writes ai.* fields on every AI call\nconst totalCost = events\n  .filter(e => typeof e.ai?.estimatedCost === 'number')\n  .reduce((sum, e) => sum + (e.ai?.estimatedCost as number), 0)\n",[461,3685,3686,3691,3734,3738,3743,3797,3801,3806,3839,3843,3848,3874,3927,3931,3936,3947,3984],{"__ignoreMap":557},[561,3687,3688],{"class":563,"line":564},[561,3689,3690],{"class":1042},"\u002F\u002F Just errors\n",[561,3692,3693,3695,3698,3700,3703,3705,3708,3710,3712,3714,3717,3719,3722,3725,3727,3730,3732],{"class":563,"line":582},[561,3694,1653],{"class":575},[561,3696,3697],{"class":639}," errors ",[561,3699,614],{"class":567},[561,3701,3702],{"class":639}," events",[561,3704,444],{"class":567},[561,3706,3707],{"class":1081},"filter",[561,3709,1085],{"class":639},[561,3711,1141],{"class":1140},[561,3713,1146],{"class":575},[561,3715,3716],{"class":639}," e",[561,3718,444],{"class":567},[561,3720,3721],{"class":639},"level ",[561,3723,3724],{"class":567},"===",[561,3726,1057],{"class":567},[561,3728,3729],{"class":620},"error",[561,3731,1088],{"class":567},[561,3733,1096],{"class":639},[561,3735,3736],{"class":563,"line":592},[561,3737,1026],{"emptyLinePlaceholder":1025},[561,3739,3740],{"class":563,"line":602},[561,3741,3742],{"class":1042},"\u002F\u002F Slow requests\n",[561,3744,3745,3747,3750,3752,3754,3756,3758,3760,3762,3764,3767,3769,3771,3774,3776,3778,3781,3783,3785,3787,3789,3791,3793,3795],{"class":563,"line":628},[561,3746,1653],{"class":575},[561,3748,3749],{"class":639}," slowReqs ",[561,3751,614],{"class":567},[561,3753,3702],{"class":639},[561,3755,444],{"class":567},[561,3757,3707],{"class":1081},[561,3759,1085],{"class":639},[561,3761,1141],{"class":1140},[561,3763,1146],{"class":575},[561,3765,3766],{"class":567}," typeof",[561,3768,3716],{"class":639},[561,3770,444],{"class":567},[561,3772,3773],{"class":639},"duration ",[561,3775,3724],{"class":567},[561,3777,1057],{"class":567},[561,3779,3780],{"class":620},"number",[561,3782,1088],{"class":567},[561,3784,1237],{"class":567},[561,3786,3716],{"class":639},[561,3788,444],{"class":567},[561,3790,3773],{"class":639},[561,3792,636],{"class":567},[561,3794,1971],{"class":677},[561,3796,1096],{"class":639},[561,3798,3799],{"class":563,"line":650},[561,3800,1026],{"emptyLinePlaceholder":1025},[561,3802,3803],{"class":563,"line":660},[561,3804,3805],{"class":1042},"\u002F\u002F Group by service\n",[561,3807,3808,3810,3813,3815,3818,3820,3823,3826,3828,3830,3832,3834,3836],{"class":563,"line":715},[561,3809,1653],{"class":575},[561,3811,3812],{"class":639}," byService ",[561,3814,614],{"class":567},[561,3816,3817],{"class":639}," Object",[561,3819,444],{"class":567},[561,3821,3822],{"class":1081},"groupBy",[561,3824,3825],{"class":639},"(events",[561,3827,684],{"class":567},[561,3829,3716],{"class":1140},[561,3831,1146],{"class":575},[561,3833,3716],{"class":639},[561,3835,444],{"class":567},[561,3837,3838],{"class":639},"service)\n",[561,3840,3841],{"class":563,"line":745},[561,3842,1026],{"emptyLinePlaceholder":1025},[561,3844,3845],{"class":563,"line":801},[561,3846,3847],{"class":1042},"\u002F\u002F Rolling error rate (last 100 events)\n",[561,3849,3850,3852,3855,3857,3859,3861,3863,3865,3867,3869,3872],{"class":563,"line":826},[561,3851,1653],{"class":575},[561,3853,3854],{"class":639}," last100 ",[561,3856,614],{"class":567},[561,3858,3702],{"class":639},[561,3860,444],{"class":567},[561,3862,2472],{"class":1081},[561,3864,1085],{"class":639},[561,3866,2477],{"class":677},[561,3868,684],{"class":567},[561,3870,3871],{"class":677}," 100",[561,3873,1096],{"class":639},[561,3875,3876,3878,3881,3883,3886,3888,3890,3892,3894,3896,3898,3900,3902,3904,3906,3908,3910,3912,3914,3917,3920,3922,3924],{"class":563,"line":848},[561,3877,1653],{"class":575},[561,3879,3880],{"class":639}," errorRate ",[561,3882,614],{"class":567},[561,3884,3885],{"class":639}," last100",[561,3887,444],{"class":567},[561,3889,3707],{"class":1081},[561,3891,1085],{"class":639},[561,3893,1141],{"class":1140},[561,3895,1146],{"class":575},[561,3897,3716],{"class":639},[561,3899,444],{"class":567},[561,3901,3721],{"class":639},[561,3903,3724],{"class":567},[561,3905,1057],{"class":567},[561,3907,3729],{"class":620},[561,3909,1088],{"class":567},[561,3911,498],{"class":639},[561,3913,444],{"class":567},[561,3915,3916],{"class":639},"length ",[561,3918,3919],{"class":567},"\u002F",[561,3921,3885],{"class":639},[561,3923,444],{"class":567},[561,3925,3926],{"class":639},"length\n",[561,3928,3929],{"class":563,"line":869},[561,3930,1026],{"emptyLinePlaceholder":1025},[561,3932,3933],{"class":563,"line":879},[561,3934,3935],{"class":1042},"\u002F\u002F Ad-hoc cost analytics — works because evlog\u002Fai writes ai.* fields on every AI call\n",[561,3937,3938,3940,3943,3945],{"class":563,"line":888},[561,3939,1653],{"class":575},[561,3941,3942],{"class":639}," totalCost ",[561,3944,614],{"class":567},[561,3946,2534],{"class":639},[561,3948,3949,3952,3954,3956,3958,3960,3962,3964,3966,3969,3971,3974,3976,3978,3980,3982],{"class":563,"line":898},[561,3950,3951],{"class":567},"  .",[561,3953,3707],{"class":1081},[561,3955,1085],{"class":639},[561,3957,1141],{"class":1140},[561,3959,1146],{"class":575},[561,3961,3766],{"class":567},[561,3963,3716],{"class":639},[561,3965,444],{"class":567},[561,3967,3968],{"class":639},"ai",[561,3970,2023],{"class":567},[561,3972,3973],{"class":639},"estimatedCost ",[561,3975,3724],{"class":567},[561,3977,1057],{"class":567},[561,3979,3780],{"class":620},[561,3981,1088],{"class":567},[561,3983,1096],{"class":639},[561,3985,3986,3988,3991,3993,3995,3998,4000,4002,4004,4006,4009,4012,4015,4017,4019,4021,4023,4026,4029,4031,4033,4035],{"class":563,"line":920},[561,3987,3951],{"class":567},[561,3989,3990],{"class":1081},"reduce",[561,3992,1085],{"class":639},[561,3994,1085],{"class":567},[561,3996,3997],{"class":1140},"sum",[561,3999,684],{"class":567},[561,4001,3716],{"class":1140},[561,4003,498],{"class":567},[561,4005,1146],{"class":575},[561,4007,4008],{"class":639}," sum ",[561,4010,4011],{"class":567},"+",[561,4013,4014],{"class":639}," (e",[561,4016,444],{"class":567},[561,4018,3968],{"class":639},[561,4020,2023],{"class":567},[561,4022,3973],{"class":639},[561,4024,4025],{"class":1185},"as",[561,4027,4028],{"class":663}," number",[561,4030,498],{"class":639},[561,4032,684],{"class":567},[561,4034,698],{"class":677},[561,4036,1096],{"class":639},[521,4038,4040],{"id":4039},"_6-self-hosted-tail-f-replacement","6. Self-hosted \"tail -f\" replacement",[433,4042,4043],{},"Skip the network entirely if the consumer runs on the same machine:",[552,4045,4047],{"className":2175,"code":4046,"language":1586,"meta":557,"style":557},"import { tailFsLogs } from 'evlog\u002Ffs'\n\nconst ac = new AbortController()\nprocess.on('SIGINT', () => ac.abort())\n\nfor await (const event of tailFsLogs({ signal: ac.signal })) {\n  if (event.level === 'error') notifyOps(event)\n}\n",[461,4048,4049,4068,4072,4088,4123,4127,4168,4199],{"__ignoreMap":557},[561,4050,4051,4053,4055,4058,4060,4062,4064,4066],{"class":563,"line":564},[561,4052,1595],{"class":1185},[561,4054,667],{"class":567},[561,4056,4057],{"class":639}," tailFsLogs",[561,4059,1613],{"class":567},[561,4061,1616],{"class":1185},[561,4063,1057],{"class":567},[561,4065,2759],{"class":620},[561,4067,1063],{"class":567},[561,4069,4070],{"class":563,"line":582},[561,4071,1026],{"emptyLinePlaceholder":1025},[561,4073,4074,4076,4079,4081,4083,4086],{"class":563,"line":592},[561,4075,1653],{"class":575},[561,4077,4078],{"class":639}," ac ",[561,4080,614],{"class":567},[561,4082,1109],{"class":567},[561,4084,4085],{"class":1081}," AbortController",[561,4087,1516],{"class":639},[561,4089,4090,4093,4095,4098,4100,4102,4105,4107,4109,4111,4113,4116,4118,4121],{"class":563,"line":602},[561,4091,4092],{"class":639},"process",[561,4094,444],{"class":567},[561,4096,4097],{"class":1081},"on",[561,4099,1085],{"class":639},[561,4101,1088],{"class":567},[561,4103,4104],{"class":620},"SIGINT",[561,4106,1088],{"class":567},[561,4108,684],{"class":567},[561,4110,1713],{"class":567},[561,4112,1146],{"class":575},[561,4114,4115],{"class":639}," ac",[561,4117,444],{"class":567},[561,4119,4120],{"class":1081},"abort",[561,4122,2029],{"class":639},[561,4124,4125],{"class":563,"line":628},[561,4126,1026],{"emptyLinePlaceholder":1025},[561,4128,4129,4132,4134,4136,4138,4141,4144,4146,4148,4150,4153,4155,4157,4159,4162,4164,4166],{"class":563,"line":650},[561,4130,4131],{"class":1185},"for",[561,4133,1739],{"class":1185},[561,4135,1137],{"class":639},[561,4137,1653],{"class":575},[561,4139,4140],{"class":639}," event ",[561,4142,4143],{"class":567},"of",[561,4145,4057],{"class":1081},[561,4147,1085],{"class":639},[561,4149,2913],{"class":567},[561,4151,4152],{"class":571}," signal",[561,4154,674],{"class":567},[561,4156,4115],{"class":639},[561,4158,444],{"class":567},[561,4160,4161],{"class":639},"signal ",[561,4163,1355],{"class":567},[561,4165,2920],{"class":639},[561,4167,1919],{"class":567},[561,4169,4170,4172,4174,4176,4178,4180,4182,4184,4186,4188,4190,4193,4195,4197],{"class":563,"line":660},[561,4171,1774],{"class":1185},[561,4173,1137],{"class":571},[561,4175,1232],{"class":639},[561,4177,444],{"class":567},[561,4179,955],{"class":639},[561,4181,1891],{"class":567},[561,4183,1057],{"class":567},[561,4185,3729],{"class":620},[561,4187,1088],{"class":567},[561,4189,1209],{"class":571},[561,4191,4192],{"class":1081},"notifyOps",[561,4194,1085],{"class":571},[561,4196,1232],{"class":639},[561,4198,1096],{"class":571},[561,4200,4201],{"class":563,"line":715},[561,4202,823],{"class":567},[433,4204,4205],{},"Works without instrumenting the running app — useful for sidecar \u002F observer processes that watch a directory.",[521,4207,4209],{"id":4208},"what-not-to-do","What not to do",[454,4211,4212,4218,4224],{},[457,4213,4214,4217],{},[2115,4215,4216],{},"Don't run the stream server on Vercel Functions \u002F Cloudflare Workers \u002F Lambda."," Each invocation is a separate isolate; subscribers in one isolate never see events emitted by other isolates. Use a real broker (Redis Streams, NATS, Pub\u002FSub) for cross-instance fan-out.",[457,4219,4220,4223],{},[2115,4221,4222],{},"Don't put auth-sensitive data in wide events"," unless your evlog config redacts them. The server relays exactly what your app emitted — including any unredacted PII.",[457,4225,4226,4229],{},[2115,4227,4228],{},"Don't filter at the server"," (\"only error events please\"). The server is purpose-built to be transparent. Filter on the consumer side; that way one filter doesn't starve another consumer.",[655,4231,4232],{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sqsOY, html code.shiki .sqsOY{--shiki-light:#8796B0;--shiki-default:#B2CCD6;--shiki-dark:#B2CCD6}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":557,"searchDepth":582,"depth":582,"links":4234},[4235,4240,4241,4242,4243,4244,4245],{"id":523,"depth":582,"text":524,"children":4236},[4237,4238,4239],{"id":549,"depth":592,"text":550},{"id":1559,"depth":592,"text":1560},{"id":2171,"depth":592,"text":2172},{"id":2549,"depth":582,"text":2550},{"id":2732,"depth":582,"text":2733},{"id":3168,"depth":582,"text":3169},{"id":3676,"depth":582,"text":3677},{"id":4039,"depth":582,"text":4040},{"id":4208,"depth":582,"text":4209},"Concrete copy-paste recipes — build your own minimal devtool, pipe to curl + jq, replay history then go live, and aggregate on the consumer side.","md",null,{},{"title":156,"icon":310},{"title":156,"description":4246},"F7YBn5uAtpm5JOO-cmpTOZlrjW8e7x84rztV7ZLnhCQ",[4254,4256],{"title":303,"path":304,"stem":305,"description":4255,"icon":306,"children":-1},"Replay and tail the local NDJSON drain with readFsLogs and tailFsLogs — works in-process or from any external Node tool, survives restarts.",{"title":312,"path":313,"stem":314,"description":4257,"icon":288,"children":-1},"Hook into the evlog pipeline — plugins for cross-cutting concerns, enrichers for derived context, tail sampling for outcome-aware keep decisions, identity headers on every drain request.",1778349127155]