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