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