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