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