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