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