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