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