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