[{"data":1,"prerenderedAt":2514},["ShallowReactive",2],{"navigation_docs":3,"-build-on-top-sinks":427,"-build-on-top-sinks-surround":2509},[4,35,159,201,289,324,411],{"title":5,"path":6,"stem":7,"children":8,"page":34},"Getting Started","\u002Fgetting-started","1.getting-started",[9,14,19,24,29],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-info",{"title":15,"path":16,"stem":17,"icon":18},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":20,"path":21,"stem":22,"icon":23},"Quick Start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-zap",{"title":25,"path":26,"stem":27,"icon":28},"Agent Skills","\u002Fgetting-started\u002Fagent-skills","1.getting-started\u002F4.agent-skills","i-lucide-sparkles",{"title":30,"path":31,"stem":32,"icon":33},"vs Other Loggers","\u002Fgetting-started\u002Fvs-other-loggers","1.getting-started\u002F5.vs-other-loggers","i-lucide-scale",false,{"title":36,"path":37,"stem":38,"children":39,"page":34},"Logging","\u002Flogging","2.logging",[40,45,50,55,60,65,70,99,127],{"title":41,"path":42,"stem":43,"icon":44},"Overview","\u002Flogging\u002Foverview","2.logging\u002F0.overview","i-lucide-list",{"title":46,"path":47,"stem":48,"icon":49},"Simple Logging","\u002Flogging\u002Fsimple-logging","2.logging\u002F1.simple-logging","i-lucide-terminal",{"title":51,"path":52,"stem":53,"icon":54},"Wide Events","\u002Flogging\u002Fwide-events","2.logging\u002F2.wide-events","i-lucide-layers",{"title":56,"path":57,"stem":58,"icon":59},"Structured Errors","\u002Flogging\u002Fstructured-errors","2.logging\u002F3.structured-errors","i-lucide-shield-alert",{"title":61,"path":62,"stem":63,"icon":64},"Catalogs","\u002Flogging\u002Fcatalogs","2.logging\u002F4.catalogs","i-lucide-book-open",{"title":66,"path":67,"stem":68,"icon":69},"Client Logging","\u002Flogging\u002Fclient-logging","2.logging\u002F5.client-logging","i-lucide-monitor",{"title":71,"icon":72,"path":73,"stem":74,"children":75,"page":34},"AI SDK","i-simple-icons-vercel","\u002Flogging\u002Fai-sdk","2.logging\u002F6.ai-sdk",[76,79,84,89,94],{"title":41,"path":77,"stem":78,"icon":44},"\u002Flogging\u002Fai-sdk\u002Foverview","2.logging\u002F6.ai-sdk\u002F01.overview",{"title":80,"path":81,"stem":82,"icon":83},"Usage","\u002Flogging\u002Fai-sdk\u002Fusage","2.logging\u002F6.ai-sdk\u002F02.usage","i-lucide-code",{"title":85,"path":86,"stem":87,"icon":88},"Options","\u002Flogging\u002Fai-sdk\u002Foptions","2.logging\u002F6.ai-sdk\u002F03.options","i-lucide-sliders",{"title":90,"path":91,"stem":92,"icon":93},"Metadata","\u002Flogging\u002Fai-sdk\u002Fmetadata","2.logging\u002F6.ai-sdk\u002F04.metadata","i-lucide-database",{"title":95,"path":96,"stem":97,"icon":98},"Telemetry","\u002Flogging\u002Fai-sdk\u002Ftelemetry","2.logging\u002F6.ai-sdk\u002F05.telemetry","i-lucide-activity",{"title":100,"icon":101,"path":102,"stem":103,"children":104,"page":34},"Better Auth","i-simple-icons-betterauth","\u002Flogging\u002Fbetter-auth","2.logging\u002F7.better-auth",[105,108,113,118,122],{"title":41,"path":106,"stem":107,"icon":44},"\u002Flogging\u002Fbetter-auth\u002Foverview","2.logging\u002F7.better-auth\u002F01.overview",{"title":109,"path":110,"stem":111,"icon":112},"Identify User","\u002Flogging\u002Fbetter-auth\u002Fidentify-user","2.logging\u002F7.better-auth\u002F02.identify-user","i-lucide-user-check",{"title":114,"path":115,"stem":116,"icon":117},"Middleware","\u002Flogging\u002Fbetter-auth\u002Fmiddleware","2.logging\u002F7.better-auth\u002F03.middleware","i-lucide-shield",{"title":119,"path":120,"stem":121,"icon":69},"Client Sync","\u002Flogging\u002Fbetter-auth\u002Fclient-sync","2.logging\u002F7.better-auth\u002F04.client-sync",{"title":123,"path":124,"stem":125,"icon":126},"Performance","\u002Flogging\u002Fbetter-auth\u002Fperformance","2.logging\u002F7.better-auth\u002F05.performance","i-lucide-gauge",{"title":128,"icon":129,"path":130,"stem":131,"children":132,"page":34},"Audit Logs","i-lucide-shield-check","\u002Flogging\u002Faudit","2.logging\u002F8.audit",[133,136,141,146,151,155],{"title":41,"path":134,"stem":135,"icon":44},"\u002Flogging\u002Faudit\u002Foverview","2.logging\u002F8.audit\u002F01.overview",{"title":137,"path":138,"stem":139,"icon":140},"Schema","\u002Flogging\u002Faudit\u002Fschema","2.logging\u002F8.audit\u002F02.schema","i-lucide-file-text",{"title":142,"path":143,"stem":144,"icon":145},"Recording","\u002Flogging\u002Faudit\u002Frecording","2.logging\u002F8.audit\u002F03.recording","i-lucide-pen-line",{"title":147,"path":148,"stem":149,"icon":150},"Drains","\u002Flogging\u002Faudit\u002Fpipeline","2.logging\u002F8.audit\u002F04.pipeline","i-lucide-link",{"title":152,"path":153,"stem":154,"icon":129},"Compliance","\u002Flogging\u002Faudit\u002Fcompliance","2.logging\u002F8.audit\u002F05.compliance",{"title":156,"path":157,"stem":158,"icon":64},"Recipes","\u002Flogging\u002Faudit\u002Frecipes","2.logging\u002F8.audit\u002F06.recipes",{"title":160,"path":161,"stem":162,"children":163,"page":34},"Core Concepts","\u002Fcore-concepts","3.core-concepts",[164,169,174,179,184,188,191,196],{"title":165,"path":166,"stem":167,"icon":168},"Lifecycle","\u002Fcore-concepts\u002Flifecycle","3.core-concepts\u002F0.lifecycle","i-lucide-arrow-right-left",{"title":170,"path":171,"stem":172,"icon":173},"Configuration","\u002Fcore-concepts\u002Fconfiguration","3.core-concepts\u002F1.configuration","i-lucide-settings",{"title":175,"path":176,"stem":177,"icon":178},"Sampling","\u002Fcore-concepts\u002Fsampling","3.core-concepts\u002F2.sampling","i-lucide-filter",{"title":180,"path":181,"stem":182,"icon":183},"Typed Fields","\u002Fcore-concepts\u002Ftyped-fields","3.core-concepts\u002F3.typed-fields","i-simple-icons-typescript",{"title":185,"path":186,"stem":187,"icon":129},"Best Practices","\u002Fcore-concepts\u002Fbest-practices","3.core-concepts\u002F4.best-practices",{"title":123,"path":189,"stem":190,"icon":126},"\u002Fcore-concepts\u002Fperformance","3.core-concepts\u002F5.performance",{"title":192,"path":193,"stem":194,"icon":195},"Vite Plugin","\u002Fcore-concepts\u002Fvite-plugin","3.core-concepts\u002F6.vite-plugin","i-custom-vite",{"title":197,"path":198,"stem":199,"icon":200},"Auto-Redaction","\u002Fcore-concepts\u002Fredaction","3.core-concepts\u002F7.redaction","i-lucide-eye-off",{"title":202,"path":203,"stem":204,"children":205,"page":34},"Frameworks","\u002Fframeworks","4.frameworks",[206,210,215,220,225,230,235,240,245,250,255,260,265,270,274,279,284],{"title":41,"path":207,"stem":208,"icon":209},"\u002Fframeworks\u002Foverview","4.frameworks\u002F00.overview","i-lucide-layout-grid",{"title":211,"path":212,"stem":213,"icon":214},"Nuxt","\u002Fframeworks\u002Fnuxt","4.frameworks\u002F01.nuxt","i-simple-icons-nuxtdotjs",{"title":216,"path":217,"stem":218,"icon":219},"Next.js","\u002Fframeworks\u002Fnextjs","4.frameworks\u002F02.nextjs","i-simple-icons-nextdotjs",{"title":221,"path":222,"stem":223,"icon":224},"SvelteKit","\u002Fframeworks\u002Fsveltekit","4.frameworks\u002F03.sveltekit","i-simple-icons-svelte",{"title":226,"path":227,"stem":228,"icon":229},"Nitro","\u002Fframeworks\u002Fnitro","4.frameworks\u002F04.nitro","i-custom-nitro",{"title":231,"path":232,"stem":233,"icon":234},"TanStack Start","\u002Fframeworks\u002Ftanstack-start","4.frameworks\u002F05.tanstack-start","i-custom-tanstack",{"title":236,"path":237,"stem":238,"icon":239},"NestJS","\u002Fframeworks\u002Fnestjs","4.frameworks\u002F06.nestjs","i-simple-icons-nestjs",{"title":241,"path":242,"stem":243,"icon":244},"Express","\u002Fframeworks\u002Fexpress","4.frameworks\u002F07.express","i-simple-icons-express",{"title":246,"path":247,"stem":248,"icon":249},"Hono","\u002Fframeworks\u002Fhono","4.frameworks\u002F08.hono","i-simple-icons-hono",{"title":251,"path":252,"stem":253,"icon":254},"Fastify","\u002Fframeworks\u002Ffastify","4.frameworks\u002F09.fastify","i-simple-icons-fastify",{"title":256,"path":257,"stem":258,"icon":259},"Elysia","\u002Fframeworks\u002Felysia","4.frameworks\u002F10.elysia","i-custom-elysia",{"title":261,"path":262,"stem":263,"icon":264},"React Router","\u002Fframeworks\u002Freact-router","4.frameworks\u002F11.react-router","i-custom-reactrouter",{"title":266,"path":267,"stem":268,"icon":269},"Cloudflare Workers","\u002Fframeworks\u002Fcloudflare-workers","4.frameworks\u002F12.cloudflare-workers","i-simple-icons-cloudflare",{"title":271,"path":272,"stem":273,"icon":183},"Standalone","\u002Fframeworks\u002Fstandalone","4.frameworks\u002F13.standalone",{"title":275,"path":276,"stem":277,"icon":278},"Astro","\u002Fframeworks\u002Fastro","4.frameworks\u002F14.astro","i-simple-icons-astro",{"title":280,"path":281,"stem":282,"icon":283},"AWS Lambda","\u002Fframeworks\u002Faws-lambda","4.frameworks\u002F16.aws-lambda","i-custom-lambda",{"title":285,"path":286,"stem":287,"icon":288},"Custom Integration","\u002Fframeworks\u002Fcustom-integration","4.frameworks\u002F17.custom-integration","i-lucide-puzzle",{"title":290,"path":291,"stem":292,"children":293,"page":34},"Build on top","\u002Fbuild-on-top","5.build-on-top",[294,297,302,307,311,315,320],{"title":41,"path":295,"stem":296,"icon":54},"\u002Fbuild-on-top\u002Foverview","5.build-on-top\u002F0.overview",{"title":298,"path":299,"stem":300,"icon":301},"Stream","\u002Fbuild-on-top\u002Fstream","5.build-on-top\u002F1.stream","i-lucide-radio-tower",{"title":303,"path":304,"stem":305,"icon":306},"FS reader","\u002Fbuild-on-top\u002Ffs-reader","5.build-on-top\u002F2.fs-reader","i-lucide-folder-search",{"title":156,"path":308,"stem":309,"icon":310},"\u002Fbuild-on-top\u002Fconsumer-recipes","5.build-on-top\u002F3.consumer-recipes","i-lucide-chef-hat",{"title":312,"path":313,"stem":314,"icon":288},"Pipeline extension","\u002Fbuild-on-top\u002Fpipeline-extension","5.build-on-top\u002F4.pipeline-extension",{"title":316,"path":317,"stem":318,"icon":319},"Sinks","\u002Fbuild-on-top\u002Fsinks","5.build-on-top\u002F5.sinks","i-lucide-share-2",{"title":321,"path":322,"stem":323,"icon":288},"Framework integration","\u002Fbuild-on-top\u002Fframework-integration","5.build-on-top\u002F6.framework-integration",{"title":325,"path":326,"stem":327,"children":328,"page":34},"Adapters","\u002Fadapters","6.adapters",[329,332,372,387],{"title":41,"path":330,"stem":331,"icon":44},"\u002Fadapters\u002Foverview","6.adapters\u002F01.overview",{"title":333,"path":334,"stem":335,"children":336,"page":34},"Cloud destinations","\u002Fadapters\u002Fcloud","6.adapters\u002F02.cloud",[337,342,347,352,357,362,367],{"title":338,"path":339,"stem":340,"icon":341},"Axiom","\u002Fadapters\u002Fcloud\u002Faxiom","6.adapters\u002F02.cloud\u002F01.axiom","i-custom-axiom",{"title":343,"path":344,"stem":345,"icon":346},"OTLP","\u002Fadapters\u002Fcloud\u002Fotlp","6.adapters\u002F02.cloud\u002F02.otlp","i-simple-icons-opentelemetry",{"title":348,"path":349,"stem":350,"icon":351},"PostHog","\u002Fadapters\u002Fcloud\u002Fposthog","6.adapters\u002F02.cloud\u002F03.posthog","i-simple-icons-posthog",{"title":353,"path":354,"stem":355,"icon":356},"Sentry","\u002Fadapters\u002Fcloud\u002Fsentry","6.adapters\u002F02.cloud\u002F04.sentry","i-simple-icons-sentry",{"title":358,"path":359,"stem":360,"icon":361},"Better Stack","\u002Fadapters\u002Fcloud\u002Fbetter-stack","6.adapters\u002F02.cloud\u002F05.better-stack","i-simple-icons-betterstack",{"title":363,"path":364,"stem":365,"icon":366},"Datadog","\u002Fadapters\u002Fcloud\u002Fdatadog","6.adapters\u002F02.cloud\u002F06.datadog","i-simple-icons-datadog",{"title":368,"path":369,"stem":370,"icon":371},"HyperDX","\u002Fadapters\u002Fcloud\u002Fhyperdx","6.adapters\u002F02.cloud\u002F07.hyperdx","i-custom-hyperdx",{"title":373,"path":374,"stem":375,"children":376,"page":34},"Self-hosted","\u002Fadapters\u002Fself-hosted","6.adapters\u002F03.self-hosted",[377,382],{"title":378,"path":379,"stem":380,"icon":381},"File System","\u002Fadapters\u002Fself-hosted\u002Ffs","6.adapters\u002F03.self-hosted\u002F01.fs","i-lucide-hard-drive",{"title":383,"path":384,"stem":385,"icon":386},"NuxtHub","\u002Fadapters\u002Fself-hosted\u002Fnuxthub","6.adapters\u002F03.self-hosted\u002F02.nuxthub","i-simple-icons-nuxt",{"title":388,"path":389,"stem":390,"children":391,"page":34},"Building blocks","\u002Fadapters\u002Fbuilding-blocks","6.adapters\u002F04.building-blocks",[392,397,402,406],{"title":393,"path":394,"stem":395,"icon":396},"Pipeline","\u002Fadapters\u002Fbuilding-blocks\u002Fpipeline","6.adapters\u002F04.building-blocks\u002F01.pipeline","i-lucide-workflow",{"title":398,"path":399,"stem":400,"icon":401},"HTTP","\u002Fadapters\u002Fbuilding-blocks\u002Fhttp","6.adapters\u002F04.building-blocks\u002F02.http","i-lucide-globe",{"title":403,"path":404,"stem":405,"icon":83},"Custom Adapters","\u002Fadapters\u002Fbuilding-blocks\u002Fcustom","6.adapters\u002F04.building-blocks\u002F03.custom",{"title":407,"path":408,"stem":409,"icon":410},"Toolkit","\u002Fadapters\u002Fbuilding-blocks\u002Ftoolkit","6.adapters\u002F04.building-blocks\u002F04.toolkit","i-lucide-blocks",{"title":412,"path":413,"stem":414,"children":415,"page":34},"Enrichers","\u002Fenrichers","7.enrichers",[416,419,423],{"title":41,"path":417,"stem":418,"icon":28},"\u002Fenrichers\u002Foverview","7.enrichers\u002F1.overview",{"title":420,"path":421,"stem":422,"icon":288},"Built-in","\u002Fenrichers\u002Fbuilt-in","7.enrichers\u002F2.built-in",{"title":424,"path":425,"stem":426,"icon":83},"Custom","\u002Fenrichers\u002Fcustom","7.enrichers\u002F3.custom",{"id":428,"title":316,"body":429,"description":2502,"extension":2503,"links":2504,"meta":2505,"navigation":2506,"path":317,"seo":2507,"stem":318,"__hash__":2508},"docs\u002F5.build-on-top\u002F5.sinks.md",{"type":430,"value":431,"toc":2487},"minimark",[432,446,499,503,515,605,610,1175,1189,1198,1201,1204,1211,1284,1288,1587,1610,1614,1635,1638,1641,1648,1717,1721,2134,2147,2151,2173,2177,2180,2448,2454,2458,2483],[433,434,435,436,440,441,445],"p",{},"A ",[437,438,439],"strong",{},"drain"," is the terminal step of evlog's pipeline: a function that receives wide events and ships them somewhere — an HTTP API, a message queue, a database, a webhook, a local file. evlog ships built-in drains for popular providers (",[442,443,444],"a",{"href":330},"Adapters overview","). This page covers the three things you do on top of them in production:",[447,448,449,462],"table",{},[450,451,452],"thead",{},[453,454,455,459],"tr",{},[456,457,458],"th",{},"You want to…",[456,460,461],{},"Use",[463,464,465,477,488],"tbody",{},[453,466,467,471],{},[468,469,470],"td",{},"Write a drain for a backend without a built-in adapter",[468,472,473],{},[442,474,476],{"href":475},"#custom-drains","Custom drains",[453,478,479,482],{},[468,480,481],{},"Batch + retry every drain so one HTTP call per event isn't a thing",[468,483,484],{},[442,485,487],{"href":486},"#drain-pipeline","Drain pipeline",[453,489,490,493],{},[468,491,492],{},"Send each event to several destinations in parallel",[468,494,495],{},[442,496,498],{"href":497},"#fanout","Fanout",[500,501,476],"h2",{"id":502},"custom-drains",[433,504,505,506,510,511,514],{},"When you need a destination that isn't covered by a built-in adapter, write your own with ",[507,508,509],"code",{},"defineDrain"," (any transport) or ",[507,512,513],{},"defineHttpDrain"," (HTTP backends with auto timeouts + retries + identity headers).",[516,517,521,524,597],"prompt",{":actions":518,"description":519,"icon":520},"[\"copy\",\"cursor\",\"windsurf\"]","Build a custom evlog drain","i-lucide-code-2",[433,522,523],{},"Ship wide events to a backend that doesn't have a built-in evlog adapter.",[525,526,527,547,558,569,579,590],"ul",{},[528,529,530,531,534,535,538,539,542,543,546],"li",{},"For HTTP backends, use ",[507,532,533],{},"defineHttpDrain({ name, resolve, encode })"," from ",[507,536,537],{},"evlog\u002Ftoolkit"," — it handles timeouts, retries, and adds the ",[507,540,541],{},"User-Agent: evlog\u002F\u003Cversion>"," + ",[507,544,545],{},"X-Evlog-Source: \u003Cname>"," identity headers automatically",[528,548,549,550,553,554,557],{},"For non-HTTP transports (queue, DB, native SDK, raw socket), use ",[507,551,552],{},"defineDrain({ name, send })"," and implement ",[507,555,556],{},"send(events)"," myself",[528,559,560,561,564,565,568],{},"Resolve config lazily inside ",[507,562,563],{},"resolve()"," so env vars and ",[507,566,567],{},"runtimeConfig"," are read at request time, not at module load",[528,570,571,572,575,576],{},"Encode batched events into the destination's wire format inside ",[507,573,574],{},"encode(events, config)"," — return ",[507,577,578],{},"{ url, headers, body }",[528,580,581,582,585,586,589],{},"Wire it on my framework like any other drain (Nuxt: ",[507,583,584],{},"evlog.adapters.custom",", Next\u002Fstandalone: ",[507,587,588],{},"initLogger({ drain })",", others: pass to the framework middleware)",[528,591,592,593,596],{},"Always wrap it in ",[507,594,595],{},"createDrainPipeline"," in production for batching + retries",[433,598,599,600],{},"Docs: ",[442,601,602],{"href":602,"rel":603},"https:\u002F\u002Fwww.evlog.dev\u002Fbuild-on-top\u002Fsinks",[604],"nofollow",[606,607,609],"h3",{"id":608},"a-5-minute-example-internal-loki-drain","A 5-minute example — internal Loki drain",[611,612,617],"pre",{"className":613,"code":614,"language":615,"meta":616,"style":616},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { defineHttpDrain } from 'evlog\u002Ftoolkit'\n\nexport function createLokiDrain(overrides?: { url?: string; token?: string }) {\n  return defineHttpDrain\u003C{ url: string; token: string }>({\n    name: 'loki',\n    resolve: () => ({\n      url: overrides?.url ?? process.env.LOKI_URL!,\n      token: overrides?.token ?? process.env.LOKI_TOKEN!,\n    }),\n    encode: (events, config) => ({\n      url: `${config.url}\u002Floki\u002Fapi\u002Fv1\u002Fpush`,\n      headers: {\n        'Content-Type': 'application\u002Fjson',\n        Authorization: `Bearer ${config.token}`,\n      },\n      body: JSON.stringify({\n        streams: events.map(e => ({\n          stream: { service: e.service, level: e.level },\n          values: [[String(Date.parse(e.timestamp) * 1e6), JSON.stringify(e)]],\n        })),\n      }),\n    }),\n  })\n}\n","ts","",[507,618,619,651,658,710,744,763,782,819,849,860,887,915,925,947,975,981,1001,1028,1068,1130,1141,1151,1160,1169],{"__ignoreMap":616},[620,621,624,628,632,636,639,642,645,648],"span",{"class":622,"line":623},"line",1,[620,625,627],{"class":626},"s7zQu","import",[620,629,631],{"class":630},"sMK4o"," {",[620,633,635],{"class":634},"sTEyZ"," defineHttpDrain",[620,637,638],{"class":630}," }",[620,640,641],{"class":626}," from",[620,643,644],{"class":630}," '",[620,646,537],{"class":647},"sfazB",[620,649,650],{"class":630},"'\n",[620,652,654],{"class":622,"line":653},2,[620,655,657],{"emptyLinePlaceholder":656},true,"\n",[620,659,661,664,668,672,675,679,682,684,688,690,694,697,700,702,704,707],{"class":622,"line":660},3,[620,662,663],{"class":626},"export",[620,665,667],{"class":666},"spNyl"," function",[620,669,671],{"class":670},"s2Zo4"," createLokiDrain",[620,673,674],{"class":630},"(",[620,676,678],{"class":677},"sHdIc","overrides",[620,680,681],{"class":630},"?:",[620,683,631],{"class":630},[620,685,687],{"class":686},"swJcz"," url",[620,689,681],{"class":630},[620,691,693],{"class":692},"sBMFI"," string",[620,695,696],{"class":630},";",[620,698,699],{"class":686}," token",[620,701,681],{"class":630},[620,703,693],{"class":692},[620,705,706],{"class":630}," })",[620,708,709],{"class":630}," {\n",[620,711,713,716,718,721,723,726,728,730,732,734,736,739,741],{"class":622,"line":712},4,[620,714,715],{"class":626},"  return",[620,717,635],{"class":670},[620,719,720],{"class":630},"\u003C{",[620,722,687],{"class":686},[620,724,725],{"class":630},":",[620,727,693],{"class":692},[620,729,696],{"class":630},[620,731,699],{"class":686},[620,733,725],{"class":630},[620,735,693],{"class":692},[620,737,738],{"class":630}," }>",[620,740,674],{"class":686},[620,742,743],{"class":630},"{\n",[620,745,747,750,752,754,757,760],{"class":622,"line":746},5,[620,748,749],{"class":686},"    name",[620,751,725],{"class":630},[620,753,644],{"class":630},[620,755,756],{"class":647},"loki",[620,758,759],{"class":630},"'",[620,761,762],{"class":630},",\n",[620,764,766,769,771,774,777,780],{"class":622,"line":765},6,[620,767,768],{"class":670},"    resolve",[620,770,725],{"class":630},[620,772,773],{"class":630}," ()",[620,775,776],{"class":666}," =>",[620,778,779],{"class":686}," (",[620,781,743],{"class":630},[620,783,785,788,790,793,796,799,802,805,808,811,813,816],{"class":622,"line":784},7,[620,786,787],{"class":686},"      url",[620,789,725],{"class":630},[620,791,792],{"class":634}," overrides",[620,794,795],{"class":630},"?.",[620,797,798],{"class":634},"url",[620,800,801],{"class":630}," ??",[620,803,804],{"class":634}," process",[620,806,807],{"class":630},".",[620,809,810],{"class":634},"env",[620,812,807],{"class":630},[620,814,815],{"class":634},"LOKI_URL",[620,817,818],{"class":630},"!,\n",[620,820,822,825,827,829,831,834,836,838,840,842,844,847],{"class":622,"line":821},8,[620,823,824],{"class":686},"      token",[620,826,725],{"class":630},[620,828,792],{"class":634},[620,830,795],{"class":630},[620,832,833],{"class":634},"token",[620,835,801],{"class":630},[620,837,804],{"class":634},[620,839,807],{"class":630},[620,841,810],{"class":634},[620,843,807],{"class":630},[620,845,846],{"class":634},"LOKI_TOKEN",[620,848,818],{"class":630},[620,850,852,855,858],{"class":622,"line":851},9,[620,853,854],{"class":630},"    }",[620,856,857],{"class":686},")",[620,859,762],{"class":630},[620,861,863,866,868,870,873,876,879,881,883,885],{"class":622,"line":862},10,[620,864,865],{"class":670},"    encode",[620,867,725],{"class":630},[620,869,779],{"class":630},[620,871,872],{"class":677},"events",[620,874,875],{"class":630},",",[620,877,878],{"class":677}," config",[620,880,857],{"class":630},[620,882,776],{"class":666},[620,884,779],{"class":686},[620,886,743],{"class":630},[620,888,890,892,894,897,900,902,904,907,910,913],{"class":622,"line":889},11,[620,891,787],{"class":686},[620,893,725],{"class":630},[620,895,896],{"class":630}," `${",[620,898,899],{"class":634},"config",[620,901,807],{"class":630},[620,903,798],{"class":634},[620,905,906],{"class":630},"}",[620,908,909],{"class":647},"\u002Floki\u002Fapi\u002Fv1\u002Fpush",[620,911,912],{"class":630},"`",[620,914,762],{"class":630},[620,916,918,921,923],{"class":622,"line":917},12,[620,919,920],{"class":686},"      headers",[620,922,725],{"class":630},[620,924,709],{"class":630},[620,926,928,931,934,936,938,940,943,945],{"class":622,"line":927},13,[620,929,930],{"class":630},"        '",[620,932,933],{"class":686},"Content-Type",[620,935,759],{"class":630},[620,937,725],{"class":630},[620,939,644],{"class":630},[620,941,942],{"class":647},"application\u002Fjson",[620,944,759],{"class":630},[620,946,762],{"class":630},[620,948,950,953,955,958,961,964,966,968,970,973],{"class":622,"line":949},14,[620,951,952],{"class":686},"        Authorization",[620,954,725],{"class":630},[620,956,957],{"class":630}," `",[620,959,960],{"class":647},"Bearer ",[620,962,963],{"class":630},"${",[620,965,899],{"class":634},[620,967,807],{"class":630},[620,969,833],{"class":634},[620,971,972],{"class":630},"}`",[620,974,762],{"class":630},[620,976,978],{"class":622,"line":977},15,[620,979,980],{"class":630},"      },\n",[620,982,984,987,989,992,994,997,999],{"class":622,"line":983},16,[620,985,986],{"class":686},"      body",[620,988,725],{"class":630},[620,990,991],{"class":634}," JSON",[620,993,807],{"class":630},[620,995,996],{"class":670},"stringify",[620,998,674],{"class":686},[620,1000,743],{"class":630},[620,1002,1004,1007,1009,1012,1014,1017,1019,1022,1024,1026],{"class":622,"line":1003},17,[620,1005,1006],{"class":686},"        streams",[620,1008,725],{"class":630},[620,1010,1011],{"class":634}," events",[620,1013,807],{"class":630},[620,1015,1016],{"class":670},"map",[620,1018,674],{"class":686},[620,1020,1021],{"class":677},"e",[620,1023,776],{"class":666},[620,1025,779],{"class":686},[620,1027,743],{"class":630},[620,1029,1031,1034,1036,1038,1041,1043,1046,1048,1051,1053,1056,1058,1060,1062,1065],{"class":622,"line":1030},18,[620,1032,1033],{"class":686},"          stream",[620,1035,725],{"class":630},[620,1037,631],{"class":630},[620,1039,1040],{"class":686}," service",[620,1042,725],{"class":630},[620,1044,1045],{"class":634}," e",[620,1047,807],{"class":630},[620,1049,1050],{"class":634},"service",[620,1052,875],{"class":630},[620,1054,1055],{"class":686}," level",[620,1057,725],{"class":630},[620,1059,1045],{"class":634},[620,1061,807],{"class":630},[620,1063,1064],{"class":634},"level",[620,1066,1067],{"class":630}," },\n",[620,1069,1071,1074,1076,1079,1082,1084,1087,1089,1092,1094,1096,1098,1101,1104,1107,1111,1113,1115,1117,1119,1121,1123,1125,1128],{"class":622,"line":1070},19,[620,1072,1073],{"class":686},"          values",[620,1075,725],{"class":630},[620,1077,1078],{"class":686}," [[",[620,1080,1081],{"class":670},"String",[620,1083,674],{"class":686},[620,1085,1086],{"class":634},"Date",[620,1088,807],{"class":630},[620,1090,1091],{"class":670},"parse",[620,1093,674],{"class":686},[620,1095,1021],{"class":634},[620,1097,807],{"class":630},[620,1099,1100],{"class":634},"timestamp",[620,1102,1103],{"class":686},") ",[620,1105,1106],{"class":630},"*",[620,1108,1110],{"class":1109},"sbssI"," 1e6",[620,1112,857],{"class":686},[620,1114,875],{"class":630},[620,1116,991],{"class":634},[620,1118,807],{"class":630},[620,1120,996],{"class":670},[620,1122,674],{"class":686},[620,1124,1021],{"class":634},[620,1126,1127],{"class":686},")]]",[620,1129,762],{"class":630},[620,1131,1133,1136,1139],{"class":622,"line":1132},20,[620,1134,1135],{"class":630},"        }",[620,1137,1138],{"class":686},"))",[620,1140,762],{"class":630},[620,1142,1144,1147,1149],{"class":622,"line":1143},21,[620,1145,1146],{"class":630},"      }",[620,1148,857],{"class":686},[620,1150,762],{"class":630},[620,1152,1154,1156,1158],{"class":622,"line":1153},22,[620,1155,854],{"class":630},[620,1157,857],{"class":686},[620,1159,762],{"class":630},[620,1161,1163,1166],{"class":622,"line":1162},23,[620,1164,1165],{"class":630},"  }",[620,1167,1168],{"class":686},")\n",[620,1170,1172],{"class":622,"line":1171},24,[620,1173,1174],{"class":630},"}\n",[433,1176,1177,1179,1180,1183,1184,1188],{},[507,1178,513],{}," handles abort timeouts, exponential backoff on ",[507,1181,1182],{},"5xx"," \u002F network errors, and automatic ",[442,1185,1187],{"href":1186},"\u002Fbuild-on-top\u002Fpipeline-extension#identity-headers","identity headers"," — you only describe how to encode events into the request.",[433,1190,1191,1192,1194,1195,807],{},"The full reference — ",[507,1193,509],{}," for arbitrary transports, configuration resolution patterns, error handling — lives at ",[442,1196,1197],{"href":404},"Custom adapters",[500,1199,487],{"id":1200},"drain-pipeline",[1202,1203],"drain-pipeline-batching",{},[433,1205,1206,1207,1210],{},"Every drain in production should be wrapped in ",[507,1208,1209],{},"createDrainPipeline()",". It batches events, retries on transient failures, and drops the oldest events when the buffer overflows. Without it, you make one HTTP request per emitted event, which doesn't scale beyond local dev.",[516,1212,1214,1217,1279],{":actions":518,"description":1213,"icon":396},"Wrap an evlog drain in batch + retry pipeline",[433,1215,1216],{},"Wrap my evlog drain in the drain pipeline so it batches, retries, and survives transient failures.",[525,1218,1219,1227,1245,1259,1269,1276],{},[528,1220,1221,1222,534,1224],{},"Import ",[507,1223,595],{},[507,1225,1226],{},"evlog\u002Fpipeline",[528,1228,1229,1230,1233,1234,1237,1238,1241,1242],{},"Create a pipeline with ",[507,1231,1232],{},"batch"," (size + intervalMs), ",[507,1235,1236],{},"retry"," (maxAttempts + backoff), and ",[507,1239,1240],{},"maxBufferSize"," (oldest events drop on overflow). Sane defaults: ",[507,1243,1244],{},"{ batch: { size: 50, intervalMs: 5000 }, retry: { maxAttempts: 3 } }",[528,1246,1247,1248,1251,1252,1255,1256],{},"Wrap your underlying drain by calling ",[507,1249,1250],{},"pipeline(myDrain)"," — the result is a hook-compatible function with ",[507,1253,1254],{},".flush()"," and ",[507,1257,1258],{},".pending",[528,1260,1261,1262,1265,1266],{},"For multiple destinations, write a single drain function that fans out internally with ",[507,1263,1264],{},"Promise.allSettled([drainA(batch), drainB(batch)])"," and pass that to ",[507,1267,1268],{},"pipeline(...)",[528,1270,1271,1272,1275],{},"On shutdown, call ",[507,1273,1274],{},"drain.flush()"," to push buffered events (frameworks with proper lifecycle do this automatically)",[528,1277,1278],{},"Always use the pipeline in production — direct drains make one HTTP call per event and fall over fast",[433,1280,599,1281],{},[442,1282,602],{"href":602,"rel":1283},[604],[606,1285,1287],{"id":1286},"quick-example","Quick example",[611,1289,1291],{"className":613,"code":1290,"language":615,"meta":616,"style":616},"import { createDrainPipeline } from 'evlog\u002Fpipeline'\nimport { createAxiomDrain } from 'evlog\u002Faxiom'\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 drain = pipeline(async (batch) => {\n  await axiom(batch)\n})\n\nnitroApp.hooks.hook('evlog:drain', drain)\nnitroApp.hooks.hook('close', () => drain.flush())\n",[507,1292,1293,1312,1332,1355,1359,1385,1414,1433,1445,1451,1455,1469,1496,1510,1516,1520,1549],{"__ignoreMap":616},[620,1294,1295,1297,1299,1302,1304,1306,1308,1310],{"class":622,"line":623},[620,1296,627],{"class":626},[620,1298,631],{"class":630},[620,1300,1301],{"class":634}," createDrainPipeline",[620,1303,638],{"class":630},[620,1305,641],{"class":626},[620,1307,644],{"class":630},[620,1309,1226],{"class":647},[620,1311,650],{"class":630},[620,1313,1314,1316,1318,1321,1323,1325,1327,1330],{"class":622,"line":653},[620,1315,627],{"class":626},[620,1317,631],{"class":630},[620,1319,1320],{"class":634}," createAxiomDrain",[620,1322,638],{"class":630},[620,1324,641],{"class":626},[620,1326,644],{"class":630},[620,1328,1329],{"class":647},"evlog\u002Faxiom",[620,1331,650],{"class":630},[620,1333,1334,1336,1339,1341,1344,1346,1348,1350,1353],{"class":622,"line":660},[620,1335,627],{"class":626},[620,1337,1338],{"class":626}," type",[620,1340,631],{"class":630},[620,1342,1343],{"class":634}," DrainContext",[620,1345,638],{"class":630},[620,1347,641],{"class":626},[620,1349,644],{"class":630},[620,1351,1352],{"class":647},"evlog",[620,1354,650],{"class":630},[620,1356,1357],{"class":622,"line":712},[620,1358,657],{"emptyLinePlaceholder":656},[620,1360,1361,1364,1367,1370,1372,1375,1378,1381,1383],{"class":622,"line":746},[620,1362,1363],{"class":666},"const",[620,1365,1366],{"class":634}," pipeline ",[620,1368,1369],{"class":630},"=",[620,1371,1301],{"class":670},[620,1373,1374],{"class":630},"\u003C",[620,1376,1377],{"class":692},"DrainContext",[620,1379,1380],{"class":630},">",[620,1382,674],{"class":634},[620,1384,743],{"class":630},[620,1386,1387,1390,1392,1394,1397,1399,1402,1404,1407,1409,1412],{"class":622,"line":765},[620,1388,1389],{"class":686},"  batch",[620,1391,725],{"class":630},[620,1393,631],{"class":630},[620,1395,1396],{"class":686}," size",[620,1398,725],{"class":630},[620,1400,1401],{"class":1109}," 50",[620,1403,875],{"class":630},[620,1405,1406],{"class":686}," intervalMs",[620,1408,725],{"class":630},[620,1410,1411],{"class":1109}," 5000",[620,1413,1067],{"class":630},[620,1415,1416,1419,1421,1423,1426,1428,1431],{"class":622,"line":784},[620,1417,1418],{"class":686},"  retry",[620,1420,725],{"class":630},[620,1422,631],{"class":630},[620,1424,1425],{"class":686}," maxAttempts",[620,1427,725],{"class":630},[620,1429,1430],{"class":1109}," 3",[620,1432,1067],{"class":630},[620,1434,1435,1438,1440,1443],{"class":622,"line":821},[620,1436,1437],{"class":686},"  maxBufferSize",[620,1439,725],{"class":630},[620,1441,1442],{"class":1109}," 1000",[620,1444,762],{"class":630},[620,1446,1447,1449],{"class":622,"line":851},[620,1448,906],{"class":630},[620,1450,1168],{"class":634},[620,1452,1453],{"class":622,"line":862},[620,1454,657],{"emptyLinePlaceholder":656},[620,1456,1457,1459,1462,1464,1466],{"class":622,"line":889},[620,1458,1363],{"class":666},[620,1460,1461],{"class":634}," axiom ",[620,1463,1369],{"class":630},[620,1465,1320],{"class":670},[620,1467,1468],{"class":634},"()\n",[620,1470,1471,1473,1476,1478,1481,1483,1486,1488,1490,1492,1494],{"class":622,"line":917},[620,1472,1363],{"class":666},[620,1474,1475],{"class":634}," drain ",[620,1477,1369],{"class":630},[620,1479,1480],{"class":670}," pipeline",[620,1482,674],{"class":634},[620,1484,1485],{"class":666},"async",[620,1487,779],{"class":630},[620,1489,1232],{"class":677},[620,1491,857],{"class":630},[620,1493,776],{"class":666},[620,1495,709],{"class":630},[620,1497,1498,1501,1504,1506,1508],{"class":622,"line":927},[620,1499,1500],{"class":626},"  await",[620,1502,1503],{"class":670}," axiom",[620,1505,674],{"class":686},[620,1507,1232],{"class":634},[620,1509,1168],{"class":686},[620,1511,1512,1514],{"class":622,"line":949},[620,1513,906],{"class":630},[620,1515,1168],{"class":634},[620,1517,1518],{"class":622,"line":977},[620,1519,657],{"emptyLinePlaceholder":656},[620,1521,1522,1525,1527,1530,1532,1535,1537,1539,1542,1544,1546],{"class":622,"line":983},[620,1523,1524],{"class":634},"nitroApp",[620,1526,807],{"class":630},[620,1528,1529],{"class":634},"hooks",[620,1531,807],{"class":630},[620,1533,1534],{"class":670},"hook",[620,1536,674],{"class":634},[620,1538,759],{"class":630},[620,1540,1541],{"class":647},"evlog:drain",[620,1543,759],{"class":630},[620,1545,875],{"class":630},[620,1547,1548],{"class":634}," drain)\n",[620,1550,1551,1553,1555,1557,1559,1561,1563,1565,1568,1570,1572,1574,1576,1579,1581,1584],{"class":622,"line":1003},[620,1552,1524],{"class":634},[620,1554,807],{"class":630},[620,1556,1529],{"class":634},[620,1558,807],{"class":630},[620,1560,1534],{"class":670},[620,1562,674],{"class":634},[620,1564,759],{"class":630},[620,1566,1567],{"class":647},"close",[620,1569,759],{"class":630},[620,1571,875],{"class":630},[620,1573,773],{"class":630},[620,1575,776],{"class":666},[620,1577,1578],{"class":634}," drain",[620,1580,807],{"class":630},[620,1582,1583],{"class":670},"flush",[620,1585,1586],{"class":634},"())\n",[433,1588,1589,1590,1592,1593,1592,1595,1592,1597,1600,1601,1255,1604,1607,1608,807],{},"The full reference — pipeline options (",[507,1591,1232],{},", ",[507,1594,1236],{},[507,1596,1240],{},[507,1598,1599],{},"onDropped","), lifecycle (",[507,1602,1603],{},"flush()",[507,1605,1606],{},"pending",") — lives at ",[442,1609,487],{"href":394},[606,1611,1613],{"id":1612},"common-pitfalls","Common pitfalls",[525,1615,1616,1625],{},[528,1617,1618,1624],{},[437,1619,1620,1621,1623],{},"Don't forget ",[507,1622,1274],{}," on shutdown"," — buffered events are lost otherwise",[528,1626,1627,1634],{},[437,1628,1629,1630,1633],{},"Tune ",[507,1631,1632],{},"batch.size"," to match your provider's recommended payload"," — too small wastes overhead, too big risks rejection",[500,1636,498],{"id":1637},"fanout",[1639,1640],"drain-fan-out",{},[433,1642,1643,1644,1647],{},"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 ",[507,1645,1646],{},"Promise.allSettled"," so a single slow \u002F failing destination cannot block the others.",[516,1649,1651,1654,1712],{":actions":518,"description":1650,"icon":319},"Fan out evlog events to multiple destinations",[433,1652,1653],{},"Send each wide event to several destinations in parallel through a single drain pipeline.",[525,1655,1656,1672,1682,1696,1707],{},[528,1657,1658,1659,534,1661,1663,1664,1667,1668,1671],{},"Wrap a single ",[507,1660,595],{},[507,1662,1226],{}," around a fan-out function that calls every destination drain inside ",[507,1665,1666],{},"Promise.allSettled([drainA(batch), drainB(batch), …])"," — ",[507,1669,1670],{},"allSettled"," so one failing drain doesn't reject the whole batch",[528,1673,1674,1675,1678,1679,857],{},"Pick destinations by purpose: long-term store (Axiom \u002F Better Stack \u002F Datadog), error tracker (Sentry — typically ",[507,1676,1677],{},"{ minLevel: 'error' }"," so it doesn't get all events), local replay (",[507,1680,1681],{},"createFsDrain",[528,1683,1629,1684,1592,1686,1592,1689,1692,1693,1695],{},[507,1685,1632],{},[507,1687,1688],{},"batch.intervalMs",[507,1690,1691],{},"retry.maxAttempts",", and ",[507,1694,1240],{}," once at the pipeline level — applies to all destinations",[528,1697,1698,1699,1702,1703,1706],{},"For destinations that need different filtering, prefer per-drain ",[507,1700,1701],{},"minLevel"," \u002F ",[507,1704,1705],{},"filter"," options over wrapping",[528,1708,1620,1709,1711],{},[507,1710,1274],{}," on shutdown — events buffered for fanout are lost on abrupt exit",[433,1713,599,1714],{},[442,1715,602],{"href":602,"rel":1716},[604],[606,1718,1720],{"id":1719},"the-recipe","The recipe",[611,1722,1724],{"className":613,"code":1723,"language":615,"meta":616,"style":616},"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",[507,1725,1726,1744,1762,1782,1802,1822,1842,1846,1866,1890,1906,1916,1922,1926,1938,1951,1983,2024,2028,2055,2069,2082,2095,2108,2121,2127],{"__ignoreMap":616},[620,1727,1728,1730,1732,1734,1736,1738,1740,1742],{"class":622,"line":623},[620,1729,627],{"class":626},[620,1731,631],{"class":630},[620,1733,1301],{"class":634},[620,1735,638],{"class":630},[620,1737,641],{"class":626},[620,1739,644],{"class":630},[620,1741,1226],{"class":647},[620,1743,650],{"class":630},[620,1745,1746,1748,1750,1752,1754,1756,1758,1760],{"class":622,"line":653},[620,1747,627],{"class":626},[620,1749,631],{"class":630},[620,1751,1320],{"class":634},[620,1753,638],{"class":630},[620,1755,641],{"class":626},[620,1757,644],{"class":630},[620,1759,1329],{"class":647},[620,1761,650],{"class":630},[620,1763,1764,1766,1768,1771,1773,1775,1777,1780],{"class":622,"line":660},[620,1765,627],{"class":626},[620,1767,631],{"class":630},[620,1769,1770],{"class":634}," createDatadogDrain",[620,1772,638],{"class":630},[620,1774,641],{"class":626},[620,1776,644],{"class":630},[620,1778,1779],{"class":647},"evlog\u002Fdatadog",[620,1781,650],{"class":630},[620,1783,1784,1786,1788,1791,1793,1795,1797,1800],{"class":622,"line":712},[620,1785,627],{"class":626},[620,1787,631],{"class":630},[620,1789,1790],{"class":634}," createSentryDrain",[620,1792,638],{"class":630},[620,1794,641],{"class":626},[620,1796,644],{"class":630},[620,1798,1799],{"class":647},"evlog\u002Fsentry",[620,1801,650],{"class":630},[620,1803,1804,1806,1808,1811,1813,1815,1817,1820],{"class":622,"line":746},[620,1805,627],{"class":626},[620,1807,631],{"class":630},[620,1809,1810],{"class":634}," createFsDrain",[620,1812,638],{"class":630},[620,1814,641],{"class":626},[620,1816,644],{"class":630},[620,1818,1819],{"class":647},"evlog\u002Ffs",[620,1821,650],{"class":630},[620,1823,1824,1826,1828,1830,1832,1834,1836,1838,1840],{"class":622,"line":765},[620,1825,627],{"class":626},[620,1827,1338],{"class":626},[620,1829,631],{"class":630},[620,1831,1343],{"class":634},[620,1833,638],{"class":630},[620,1835,641],{"class":626},[620,1837,644],{"class":630},[620,1839,1352],{"class":647},[620,1841,650],{"class":630},[620,1843,1844],{"class":622,"line":784},[620,1845,657],{"emptyLinePlaceholder":656},[620,1847,1848,1850,1852,1854,1856,1858,1860,1862,1864],{"class":622,"line":821},[620,1849,1363],{"class":666},[620,1851,1366],{"class":634},[620,1853,1369],{"class":630},[620,1855,1301],{"class":670},[620,1857,1374],{"class":630},[620,1859,1377],{"class":692},[620,1861,1380],{"class":630},[620,1863,674],{"class":634},[620,1865,743],{"class":630},[620,1867,1868,1870,1872,1874,1876,1878,1880,1882,1884,1886,1888],{"class":622,"line":851},[620,1869,1389],{"class":686},[620,1871,725],{"class":630},[620,1873,631],{"class":630},[620,1875,1396],{"class":686},[620,1877,725],{"class":630},[620,1879,1401],{"class":1109},[620,1881,875],{"class":630},[620,1883,1406],{"class":686},[620,1885,725],{"class":630},[620,1887,1411],{"class":1109},[620,1889,1067],{"class":630},[620,1891,1892,1894,1896,1898,1900,1902,1904],{"class":622,"line":862},[620,1893,1418],{"class":686},[620,1895,725],{"class":630},[620,1897,631],{"class":630},[620,1899,1425],{"class":686},[620,1901,725],{"class":630},[620,1903,1430],{"class":1109},[620,1905,1067],{"class":630},[620,1907,1908,1910,1912,1914],{"class":622,"line":889},[620,1909,1437],{"class":686},[620,1911,725],{"class":630},[620,1913,1442],{"class":1109},[620,1915,762],{"class":630},[620,1917,1918,1920],{"class":622,"line":917},[620,1919,906],{"class":630},[620,1921,1168],{"class":634},[620,1923,1924],{"class":622,"line":927},[620,1925,657],{"emptyLinePlaceholder":656},[620,1927,1928,1930,1932,1934,1936],{"class":622,"line":949},[620,1929,1363],{"class":666},[620,1931,1461],{"class":634},[620,1933,1369],{"class":630},[620,1935,1320],{"class":670},[620,1937,1468],{"class":634},[620,1939,1940,1942,1945,1947,1949],{"class":622,"line":977},[620,1941,1363],{"class":666},[620,1943,1944],{"class":634}," datadog ",[620,1946,1369],{"class":630},[620,1948,1770],{"class":670},[620,1950,1468],{"class":634},[620,1952,1953,1955,1958,1960,1962,1964,1967,1970,1972,1974,1977,1979,1981],{"class":622,"line":983},[620,1954,1363],{"class":666},[620,1956,1957],{"class":634}," sentry ",[620,1959,1369],{"class":630},[620,1961,1790],{"class":670},[620,1963,674],{"class":634},[620,1965,1966],{"class":630},"{",[620,1968,1969],{"class":686}," minLevel",[620,1971,725],{"class":630},[620,1973,644],{"class":630},[620,1975,1976],{"class":647},"error",[620,1978,759],{"class":630},[620,1980,638],{"class":630},[620,1982,1168],{"class":634},[620,1984,1985,1987,1990,1992,1994,1996,1998,2001,2003,2005,2008,2010,2012,2015,2017,2020,2022],{"class":622,"line":1003},[620,1986,1363],{"class":666},[620,1988,1989],{"class":634}," fs ",[620,1991,1369],{"class":630},[620,1993,1810],{"class":670},[620,1995,674],{"class":634},[620,1997,1966],{"class":630},[620,1999,2000],{"class":686}," dir",[620,2002,725],{"class":630},[620,2004,644],{"class":630},[620,2006,2007],{"class":647},".evlog\u002Flogs",[620,2009,759],{"class":630},[620,2011,875],{"class":630},[620,2013,2014],{"class":686}," maxFiles",[620,2016,725],{"class":630},[620,2018,2019],{"class":1109}," 14",[620,2021,638],{"class":630},[620,2023,1168],{"class":634},[620,2025,2026],{"class":622,"line":1030},[620,2027,657],{"emptyLinePlaceholder":656},[620,2029,2030,2032,2035,2037,2039,2041,2043,2045,2047,2049,2051,2053],{"class":622,"line":1070},[620,2031,663],{"class":626},[620,2033,2034],{"class":666}," const",[620,2036,1475],{"class":634},[620,2038,1369],{"class":630},[620,2040,1480],{"class":670},[620,2042,674],{"class":634},[620,2044,1485],{"class":666},[620,2046,779],{"class":630},[620,2048,1232],{"class":677},[620,2050,857],{"class":630},[620,2052,776],{"class":666},[620,2054,709],{"class":630},[620,2056,2057,2059,2062,2064,2066],{"class":622,"line":1132},[620,2058,1500],{"class":626},[620,2060,2061],{"class":692}," Promise",[620,2063,807],{"class":630},[620,2065,1670],{"class":670},[620,2067,2068],{"class":686},"([\n",[620,2070,2071,2074,2076,2078,2080],{"class":622,"line":1143},[620,2072,2073],{"class":670},"    axiom",[620,2075,674],{"class":686},[620,2077,1232],{"class":634},[620,2079,857],{"class":686},[620,2081,762],{"class":630},[620,2083,2084,2087,2089,2091,2093],{"class":622,"line":1153},[620,2085,2086],{"class":670},"    datadog",[620,2088,674],{"class":686},[620,2090,1232],{"class":634},[620,2092,857],{"class":686},[620,2094,762],{"class":630},[620,2096,2097,2100,2102,2104,2106],{"class":622,"line":1162},[620,2098,2099],{"class":670},"    sentry",[620,2101,674],{"class":686},[620,2103,1232],{"class":634},[620,2105,857],{"class":686},[620,2107,762],{"class":630},[620,2109,2110,2113,2115,2117,2119],{"class":622,"line":1171},[620,2111,2112],{"class":670},"    fs",[620,2114,674],{"class":686},[620,2116,1232],{"class":634},[620,2118,857],{"class":686},[620,2120,762],{"class":630},[620,2122,2124],{"class":622,"line":2123},25,[620,2125,2126],{"class":686},"  ])\n",[620,2128,2130,2132],{"class":622,"line":2129},26,[620,2131,906],{"class":630},[620,2133,1168],{"class":634},[433,2135,2136,2137,2139,2140,2143,2144,2146],{},"Then register ",[507,2138,439],{}," wherever your framework integration takes a drain — ",[507,2141,2142],{},"nitroApp.hooks.hook('evlog:drain', drain)"," for Nitro, ",[507,2145,588],{}," for Next.js \u002F standalone, etc.",[606,2148,2150],{"id":2149},"what-you-get","What you get",[525,2152,2153,2161,2167],{},[528,2154,2155,2158,2159],{},[437,2156,2157],{},"Parallel dispatch"," — every destination receives the batch concurrently via ",[507,2160,1646],{},[528,2162,2163,2166],{},[437,2164,2165],{},"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",[528,2168,2169,2172],{},[437,2170,2171],{},"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",[606,2174,2176],{"id":2175},"per-drain-filtering","Per-drain filtering",[433,2178,2179],{},"Wrap a destination drain so it only sees events you care about:",[611,2181,2183],{"className":613,"code":2182,"language":615,"meta":616,"style":616},"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",[507,2184,2185,2205,2209,2246,2250,2284,2332,2367,2371,2375,2401,2413,2425,2438,2442],{"__ignoreMap":616},[620,2186,2187,2189,2191,2193,2195,2197,2199,2201,2203],{"class":622,"line":623},[620,2188,627],{"class":626},[620,2190,1338],{"class":626},[620,2192,631],{"class":630},[620,2194,1343],{"class":634},[620,2196,638],{"class":630},[620,2198,641],{"class":626},[620,2200,644],{"class":630},[620,2202,1352],{"class":647},[620,2204,650],{"class":630},[620,2206,2207],{"class":622,"line":653},[620,2208,657],{"emptyLinePlaceholder":656},[620,2210,2211,2213,2215,2217,2219,2221,2223,2226,2228,2230,2232,2234,2236,2239,2242,2244],{"class":622,"line":660},[620,2212,1363],{"class":666},[620,2214,1957],{"class":634},[620,2216,1369],{"class":630},[620,2218,1790],{"class":670},[620,2220,674],{"class":634},[620,2222,1966],{"class":630},[620,2224,2225],{"class":686}," dsn",[620,2227,725],{"class":630},[620,2229,804],{"class":634},[620,2231,807],{"class":630},[620,2233,810],{"class":634},[620,2235,807],{"class":630},[620,2237,2238],{"class":634},"SENTRY_DSN",[620,2240,2241],{"class":630},"!",[620,2243,638],{"class":630},[620,2245,1168],{"class":634},[620,2247,2248],{"class":622,"line":712},[620,2249,657],{"emptyLinePlaceholder":656},[620,2251,2252,2254,2256,2259,2261,2263,2265,2267,2270,2273,2275,2277,2280,2282],{"class":622,"line":746},[620,2253,1485],{"class":666},[620,2255,667],{"class":666},[620,2257,2258],{"class":670}," sentryErrorsOnly",[620,2260,674],{"class":630},[620,2262,1232],{"class":677},[620,2264,725],{"class":630},[620,2266,1343],{"class":692},[620,2268,2269],{"class":634},"[]",[620,2271,2272],{"class":630},"):",[620,2274,2061],{"class":692},[620,2276,1374],{"class":630},[620,2278,2279],{"class":692},"void",[620,2281,1380],{"class":630},[620,2283,709],{"class":630},[620,2285,2286,2289,2292,2295,2298,2300,2302,2304,2307,2309,2312,2314,2317,2319,2321,2324,2326,2328,2330],{"class":622,"line":765},[620,2287,2288],{"class":666},"  const",[620,2290,2291],{"class":634}," errors",[620,2293,2294],{"class":630}," =",[620,2296,2297],{"class":634}," batch",[620,2299,807],{"class":630},[620,2301,1705],{"class":670},[620,2303,674],{"class":686},[620,2305,2306],{"class":677},"c",[620,2308,776],{"class":666},[620,2310,2311],{"class":634}," c",[620,2313,807],{"class":630},[620,2315,2316],{"class":634},"event",[620,2318,795],{"class":630},[620,2320,1064],{"class":634},[620,2322,2323],{"class":630}," ===",[620,2325,644],{"class":630},[620,2327,1976],{"class":647},[620,2329,759],{"class":630},[620,2331,1168],{"class":686},[620,2333,2334,2337,2339,2342,2344,2347,2350,2353,2355,2358,2361,2363,2365],{"class":622,"line":784},[620,2335,2336],{"class":626},"  if",[620,2338,779],{"class":686},[620,2340,2341],{"class":634},"errors",[620,2343,807],{"class":630},[620,2345,2346],{"class":634},"length",[620,2348,2349],{"class":630}," >",[620,2351,2352],{"class":1109}," 0",[620,2354,1103],{"class":686},[620,2356,2357],{"class":626},"await",[620,2359,2360],{"class":670}," sentry",[620,2362,674],{"class":686},[620,2364,2341],{"class":634},[620,2366,1168],{"class":686},[620,2368,2369],{"class":622,"line":821},[620,2370,1174],{"class":630},[620,2372,2373],{"class":622,"line":851},[620,2374,657],{"emptyLinePlaceholder":656},[620,2376,2377,2379,2381,2383,2385,2387,2389,2391,2393,2395,2397,2399],{"class":622,"line":862},[620,2378,663],{"class":626},[620,2380,2034],{"class":666},[620,2382,1475],{"class":634},[620,2384,1369],{"class":630},[620,2386,1480],{"class":670},[620,2388,674],{"class":634},[620,2390,1485],{"class":666},[620,2392,779],{"class":630},[620,2394,1232],{"class":677},[620,2396,857],{"class":630},[620,2398,776],{"class":666},[620,2400,709],{"class":630},[620,2402,2403,2405,2407,2409,2411],{"class":622,"line":889},[620,2404,1500],{"class":626},[620,2406,2061],{"class":692},[620,2408,807],{"class":630},[620,2410,1670],{"class":670},[620,2412,2068],{"class":686},[620,2414,2415,2417,2419,2421,2423],{"class":622,"line":917},[620,2416,2073],{"class":670},[620,2418,674],{"class":686},[620,2420,1232],{"class":634},[620,2422,857],{"class":686},[620,2424,762],{"class":630},[620,2426,2427,2430,2432,2434,2436],{"class":622,"line":927},[620,2428,2429],{"class":670},"    sentryErrorsOnly",[620,2431,674],{"class":686},[620,2433,1232],{"class":634},[620,2435,857],{"class":686},[620,2437,762],{"class":630},[620,2439,2440],{"class":622,"line":949},[620,2441,2126],{"class":686},[620,2443,2444,2446],{"class":622,"line":977},[620,2445,906],{"class":630},[620,2447,1168],{"class":634},[433,2449,2450,2451,2453],{},"Most built-in drains expose ",[507,2452,1701],{}," directly, so you only need this pattern for non-level filters (path, custom field, etc.).",[606,2455,2457],{"id":2456},"what-not-to-do","What not to do",[525,2459,2460,2466,2473],{},[528,2461,2462,2465],{},[437,2463,2464],{},"Don't run one pipeline per drain unless you need per-destination retries"," — sharing one pipeline keeps batching + buffering coherent",[528,2467,2468,2472],{},[437,2469,1620,2470,1623],{},[507,2471,1274],{}," — events buffered for fanout are lost on abrupt exit",[528,2474,2475,2478,2479,2482],{},[437,2476,2477],{},"Don't fan out to a serverless-incompatible target without checking"," — the ",[442,2480,2481],{"href":299},"stream server"," reaches every connected client through the in-process stream; it's not a drain",[2484,2485,2486],"style",{},"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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}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 .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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);}",{"title":616,"searchDepth":653,"depth":653,"links":2488},[2489,2492,2496],{"id":502,"depth":653,"text":476,"children":2490},[2491],{"id":608,"depth":660,"text":609},{"id":1200,"depth":653,"text":487,"children":2493},[2494,2495],{"id":1286,"depth":660,"text":1287},{"id":1612,"depth":660,"text":1613},{"id":1637,"depth":653,"text":498,"children":2497},[2498,2499,2500,2501],{"id":1719,"depth":660,"text":1720},{"id":2149,"depth":660,"text":2150},{"id":2175,"depth":660,"text":2176},{"id":2456,"depth":660,"text":2457},"Build, batch, and fan out drains — write a custom drain for any backend, wrap it in createDrainPipeline for batch + retry, and compose multiple destinations through one pipeline.","md",null,{},{"title":316,"icon":319},{"title":316,"description":2502},"TiwVWsJeJCF48v_UuadKe9OGZ0M6onsDuqp1B87J0qY",[2510,2512],{"title":312,"path":313,"stem":314,"description":2511,"icon":288,"children":-1},"Hook into the evlog pipeline — plugins for cross-cutting concerns, enrichers for derived context, tail sampling for outcome-aware keep decisions, identity headers on every drain request.",{"title":321,"path":322,"stem":323,"description":2513,"icon":288,"children":-1},"Build evlog support for an HTTP framework that doesn't ship a built-in integration — Medusa, AdonisJS, h3 directly, custom dispatchers, queue workers.",1778349127248]