[{"data":1,"prerenderedAt":3648},["ShallowReactive",2],{"navigation_docs":3,"-extend-custom-drains":505,"-extend-custom-drains-surround":3643},[4,30,80,123,288,420,475],{"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],{"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,"children":127,"page":29},"Integrate","\u002Fintegrate","4.integrate",[128,132,200],{"title":36,"path":129,"stem":130,"icon":131},"\u002Fintegrate\u002Foverview","4.integrate\u002F0.overview","i-lucide-plug",{"title":133,"path":134,"stem":135,"children":136,"page":29},"Adapters","\u002Fintegrate\u002Fadapters","4.integrate\u002Fadapters",[137,140,180],{"title":36,"path":138,"stem":139,"icon":39},"\u002Fintegrate\u002Fadapters\u002Foverview","4.integrate\u002Fadapters\u002F01.overview",{"title":141,"path":142,"stem":143,"children":144,"page":29},"Cloud","\u002Fintegrate\u002Fadapters\u002Fcloud","4.integrate\u002Fadapters\u002Fcloud",[145,150,155,160,165,170,175],{"title":146,"path":147,"stem":148,"icon":149},"Axiom","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Faxiom","4.integrate\u002Fadapters\u002Fcloud\u002F01.axiom","i-custom-axiom",{"title":151,"path":152,"stem":153,"icon":154},"OTLP","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fotlp","4.integrate\u002Fadapters\u002Fcloud\u002F02.otlp","i-simple-icons-opentelemetry",{"title":156,"path":157,"stem":158,"icon":159},"PostHog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fposthog","4.integrate\u002Fadapters\u002Fcloud\u002F03.posthog","i-simple-icons-posthog",{"title":161,"path":162,"stem":163,"icon":164},"Sentry","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fsentry","4.integrate\u002Fadapters\u002Fcloud\u002F04.sentry","i-simple-icons-sentry",{"title":166,"path":167,"stem":168,"icon":169},"Better Stack","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fbetter-stack","4.integrate\u002Fadapters\u002Fcloud\u002F05.better-stack","i-simple-icons-betterstack",{"title":171,"path":172,"stem":173,"icon":174},"Datadog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fdatadog","4.integrate\u002Fadapters\u002Fcloud\u002F06.datadog","i-simple-icons-datadog",{"title":176,"path":177,"stem":178,"icon":179},"HyperDX","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fhyperdx","4.integrate\u002Fadapters\u002Fcloud\u002F07.hyperdx","i-custom-hyperdx",{"title":181,"path":182,"stem":183,"children":184,"page":29},"Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fself-hosted","4.integrate\u002Fadapters\u002Fself-hosted",[185,190,195],{"title":186,"path":187,"stem":188,"icon":189},"File System","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Ffs","4.integrate\u002Fadapters\u002Fself-hosted\u002F01.fs","i-lucide-hard-drive",{"title":191,"path":192,"stem":193,"icon":194},"NuxtHub","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fnuxthub","4.integrate\u002Fadapters\u002Fself-hosted\u002F02.nuxthub","i-simple-icons-nuxt",{"title":196,"path":197,"stem":198,"icon":199},"Memory","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fmemory","4.integrate\u002Fadapters\u002Fself-hosted\u002F03.memory","i-lucide-cpu",{"title":201,"path":202,"stem":203,"children":204,"page":29},"Frameworks","\u002Fintegrate\u002Fframeworks","4.integrate\u002Fframeworks",[205,209,214,219,224,229,234,239,244,249,254,259,264,269,273,278,283],{"title":36,"path":206,"stem":207,"icon":208},"\u002Fintegrate\u002Fframeworks\u002Foverview","4.integrate\u002Fframeworks\u002F00.overview","i-lucide-layout-grid",{"title":210,"path":211,"stem":212,"icon":213},"Nuxt","\u002Fintegrate\u002Fframeworks\u002Fnuxt","4.integrate\u002Fframeworks\u002F01.nuxt","i-simple-icons-nuxtdotjs",{"title":215,"path":216,"stem":217,"icon":218},"Next.js","\u002Fintegrate\u002Fframeworks\u002Fnextjs","4.integrate\u002Fframeworks\u002F02.nextjs","i-simple-icons-nextdotjs",{"title":220,"path":221,"stem":222,"icon":223},"SvelteKit","\u002Fintegrate\u002Fframeworks\u002Fsveltekit","4.integrate\u002Fframeworks\u002F03.sveltekit","i-simple-icons-svelte",{"title":225,"path":226,"stem":227,"icon":228},"Nitro","\u002Fintegrate\u002Fframeworks\u002Fnitro","4.integrate\u002Fframeworks\u002F04.nitro","i-custom-nitro",{"title":230,"path":231,"stem":232,"icon":233},"TanStack Start","\u002Fintegrate\u002Fframeworks\u002Ftanstack-start","4.integrate\u002Fframeworks\u002F05.tanstack-start","i-custom-tanstack",{"title":235,"path":236,"stem":237,"icon":238},"NestJS","\u002Fintegrate\u002Fframeworks\u002Fnestjs","4.integrate\u002Fframeworks\u002F06.nestjs","i-simple-icons-nestjs",{"title":240,"path":241,"stem":242,"icon":243},"Express","\u002Fintegrate\u002Fframeworks\u002Fexpress","4.integrate\u002Fframeworks\u002F07.express","i-simple-icons-express",{"title":245,"path":246,"stem":247,"icon":248},"Hono","\u002Fintegrate\u002Fframeworks\u002Fhono","4.integrate\u002Fframeworks\u002F08.hono","i-simple-icons-hono",{"title":250,"path":251,"stem":252,"icon":253},"Fastify","\u002Fintegrate\u002Fframeworks\u002Ffastify","4.integrate\u002Fframeworks\u002F09.fastify","i-simple-icons-fastify",{"title":255,"path":256,"stem":257,"icon":258},"Elysia","\u002Fintegrate\u002Fframeworks\u002Felysia","4.integrate\u002Fframeworks\u002F10.elysia","i-custom-elysia",{"title":260,"path":261,"stem":262,"icon":263},"React Router","\u002Fintegrate\u002Fframeworks\u002Freact-router","4.integrate\u002Fframeworks\u002F11.react-router","i-custom-reactrouter",{"title":265,"path":266,"stem":267,"icon":268},"Cloudflare Workers","\u002Fintegrate\u002Fframeworks\u002Fcloudflare-workers","4.integrate\u002Fframeworks\u002F12.cloudflare-workers","i-simple-icons-cloudflare",{"title":270,"path":271,"stem":272,"icon":74},"Standalone","\u002Fintegrate\u002Fframeworks\u002Fstandalone","4.integrate\u002Fframeworks\u002F13.standalone",{"title":274,"path":275,"stem":276,"icon":277},"Astro","\u002Fintegrate\u002Fframeworks\u002Fastro","4.integrate\u002Fframeworks\u002F14.astro","i-simple-icons-astro",{"title":279,"path":280,"stem":281,"icon":282},"oRPC","\u002Fintegrate\u002Fframeworks\u002Forpc","4.integrate\u002Fframeworks\u002F15.orpc","i-lucide-network",{"title":284,"path":285,"stem":286,"icon":287},"AWS Lambda","\u002Fintegrate\u002Fframeworks\u002Faws-lambda","4.integrate\u002Fframeworks\u002F16.aws-lambda","i-custom-lambda",{"title":289,"path":290,"stem":291,"children":292,"page":29},"Use Cases","\u002Fuse-cases","5.use-cases",[293,296,301,330,357,389,410,415],{"title":36,"path":294,"stem":295,"icon":102},"\u002Fuse-cases\u002Foverview","5.use-cases\u002F0.overview",{"title":297,"path":298,"stem":299,"icon":300},"Client Logging","\u002Fuse-cases\u002Fclient-logging","5.use-cases\u002F1.client-logging","i-lucide-monitor",{"title":302,"icon":303,"path":304,"stem":305,"children":306,"page":29},"AI SDK","i-simple-icons-vercel","\u002Fuse-cases\u002Fai-sdk","5.use-cases\u002F2.ai-sdk",[307,310,315,320,325],{"title":36,"path":308,"stem":309,"icon":39},"\u002Fuse-cases\u002Fai-sdk\u002Foverview","5.use-cases\u002F2.ai-sdk\u002F01.overview",{"title":311,"path":312,"stem":313,"icon":314},"Usage","\u002Fuse-cases\u002Fai-sdk\u002Fusage","5.use-cases\u002F2.ai-sdk\u002F02.usage","i-lucide-code",{"title":316,"path":317,"stem":318,"icon":319},"Options","\u002Fuse-cases\u002Fai-sdk\u002Foptions","5.use-cases\u002F2.ai-sdk\u002F03.options","i-lucide-sliders",{"title":321,"path":322,"stem":323,"icon":324},"Metadata","\u002Fuse-cases\u002Fai-sdk\u002Fmetadata","5.use-cases\u002F2.ai-sdk\u002F04.metadata","i-lucide-database",{"title":326,"path":327,"stem":328,"icon":329},"Telemetry","\u002Fuse-cases\u002Fai-sdk\u002Ftelemetry","5.use-cases\u002F2.ai-sdk\u002F05.telemetry","i-lucide-activity",{"title":331,"icon":332,"path":333,"stem":334,"children":335,"page":29},"Better Auth","i-simple-icons-betterauth","\u002Fuse-cases\u002Fbetter-auth","5.use-cases\u002F3.better-auth",[336,339,344,349,353],{"title":36,"path":337,"stem":338,"icon":39},"\u002Fuse-cases\u002Fbetter-auth\u002Foverview","5.use-cases\u002F3.better-auth\u002F01.overview",{"title":340,"path":341,"stem":342,"icon":343},"Identify User","\u002Fuse-cases\u002Fbetter-auth\u002Fidentify-user","5.use-cases\u002F3.better-auth\u002F02.identify-user","i-lucide-user-check",{"title":345,"path":346,"stem":347,"icon":348},"Middleware","\u002Fuse-cases\u002Fbetter-auth\u002Fmiddleware","5.use-cases\u002F3.better-auth\u002F03.middleware","i-lucide-shield",{"title":350,"path":351,"stem":352,"icon":300},"Client Sync","\u002Fuse-cases\u002Fbetter-auth\u002Fclient-sync","5.use-cases\u002F3.better-auth\u002F04.client-sync",{"title":354,"path":355,"stem":356,"icon":107},"Performance","\u002Fuse-cases\u002Fbetter-auth\u002Fperformance","5.use-cases\u002F3.better-auth\u002F05.performance",{"title":358,"icon":359,"path":360,"stem":361,"children":362,"page":29},"Audit Logs","i-lucide-shield-check","\u002Fuse-cases\u002Faudit","5.use-cases\u002F4.audit",[363,366,371,376,381,385],{"title":36,"path":364,"stem":365,"icon":39},"\u002Fuse-cases\u002Faudit\u002Foverview","5.use-cases\u002F4.audit\u002F01.overview",{"title":367,"path":368,"stem":369,"icon":370},"Schema","\u002Fuse-cases\u002Faudit\u002Fschema","5.use-cases\u002F4.audit\u002F02.schema","i-lucide-file-text",{"title":372,"path":373,"stem":374,"icon":375},"Recording","\u002Fuse-cases\u002Faudit\u002Frecording","5.use-cases\u002F4.audit\u002F03.recording","i-lucide-pen-line",{"title":377,"path":378,"stem":379,"icon":380},"Drains","\u002Fuse-cases\u002Faudit\u002Fpipeline","5.use-cases\u002F4.audit\u002F04.pipeline","i-lucide-link",{"title":382,"path":383,"stem":384,"icon":359},"Compliance","\u002Fuse-cases\u002Faudit\u002Fcompliance","5.use-cases\u002F4.audit\u002F05.compliance",{"title":386,"path":387,"stem":388,"icon":79},"Recipes","\u002Fuse-cases\u002Faudit\u002Frecipes","5.use-cases\u002F4.audit\u002F06.recipes",{"title":326,"icon":107,"path":390,"stem":391,"children":392,"page":29},"\u002Fuse-cases\u002Ftelemetry","5.use-cases\u002F4.telemetry",[393,396,401,406],{"title":36,"path":394,"stem":395,"icon":39},"\u002Fuse-cases\u002Ftelemetry\u002Foverview","5.use-cases\u002F4.telemetry\u002F01.overview",{"title":397,"path":398,"stem":399,"icon":400},"Setup","\u002Fuse-cases\u002Ftelemetry\u002Fsetup","5.use-cases\u002F4.telemetry\u002F02.setup","i-lucide-wrench",{"title":402,"path":403,"stem":404,"icon":405},"Ingest","\u002Fuse-cases\u002Ftelemetry\u002Fingest","5.use-cases\u002F4.telemetry\u002F03.ingest","i-lucide-server",{"title":407,"path":408,"stem":409,"icon":79},"Reference","\u002Fuse-cases\u002Ftelemetry\u002Freference","5.use-cases\u002F4.telemetry\u002F04.reference",{"title":411,"path":412,"stem":413,"icon":414},"Enrichers","\u002Fuse-cases\u002Fenrichers","5.use-cases\u002F5.enrichers","i-lucide-sparkles",{"title":416,"path":417,"stem":418,"icon":419},"eve","\u002Fuse-cases\u002Feve","5.use-cases\u002F5.eve","i-custom-eve",{"title":421,"path":422,"stem":423,"children":424,"page":29},"Extend","\u002Fextend","6.extend",[425,429,434,439,444,448,452,456,460,465,470],{"title":36,"path":426,"stem":427,"icon":428},"\u002Fextend\u002Foverview","6.extend\u002F0.overview","i-lucide-blocks",{"title":430,"path":431,"stem":432,"icon":433},"Stream","\u002Fextend\u002Fstream","6.extend\u002F1.stream","i-lucide-radio-tower",{"title":435,"path":436,"stem":437,"icon":438},"Custom framework","\u002Fextend\u002Fcustom-framework","6.extend\u002F10.custom-framework","i-lucide-puzzle",{"title":440,"path":441,"stem":442,"icon":443},"FS reader","\u002Fextend\u002Ffs-reader","6.extend\u002F2.fs-reader","i-lucide-folder-search",{"title":386,"path":445,"stem":446,"icon":447},"\u002Fextend\u002Fconsumer-recipes","6.extend\u002F3.consumer-recipes","i-lucide-chef-hat",{"title":449,"path":450,"stem":451,"icon":428},"Plugins","\u002Fextend\u002Fplugins","6.extend\u002F4.plugins",{"title":453,"path":454,"stem":455,"icon":414},"Custom enrichers","\u002Fextend\u002Fcustom-enrichers","6.extend\u002F5.custom-enrichers",{"title":457,"path":458,"stem":459,"icon":64},"Tail sampling","\u002Fextend\u002Ftail-sampling","6.extend\u002F6.tail-sampling",{"title":461,"path":462,"stem":463,"icon":464},"Identity headers","\u002Fextend\u002Fidentity-headers","6.extend\u002F7.identity-headers","i-lucide-fingerprint",{"title":466,"path":467,"stem":468,"icon":469},"Custom drains","\u002Fextend\u002Fcustom-drains","6.extend\u002F8.custom-drains","i-lucide-share-2",{"title":471,"path":472,"stem":473,"icon":474},"Drain pipeline","\u002Fextend\u002Fdrain-pipeline","6.extend\u002F9.drain-pipeline","i-lucide-workflow",{"title":407,"path":476,"stem":477,"children":478,"page":29},"\u002Freference","7.reference",[479,484,487,492,496,501],{"title":480,"path":481,"stem":482,"icon":483},"Configuration","\u002Freference\u002Fconfiguration","7.reference\u002F1.configuration","i-lucide-settings",{"title":354,"path":485,"stem":486,"icon":107},"\u002Freference\u002Fperformance","7.reference\u002F2.performance",{"title":488,"path":489,"stem":490,"icon":491},"Vite Plugin","\u002Freference\u002Fvite-plugin","7.reference\u002F3.vite-plugin","i-custom-vite",{"title":493,"path":494,"stem":495,"icon":359},"Best Practices","\u002Freference\u002Fbest-practices","7.reference\u002F4.best-practices",{"title":497,"path":498,"stem":499,"icon":500},"vs Other Loggers","\u002Freference\u002Fvs-other-loggers","7.reference\u002F5.vs-other-loggers","i-lucide-scale",{"title":502,"path":503,"stem":504,"icon":414},"Agent Skills","\u002Freference\u002Fagent-skills","7.reference\u002F6.agent-skills",{"id":506,"title":507,"body":508,"description":3631,"extension":3632,"links":3633,"meta":3639,"navigation":3640,"path":467,"seo":3641,"stem":468,"__hash__":3642},"docs\u002F6.extend\u002F8.custom-drains.md","Custom Drains",{"type":509,"value":510,"toc":3614},"minimark",[511,525,528,579,586,707,714,727,1394,1408,1413,1416,1891,1895,1900,1941,1971,1975,1982,2417,2425,2429,2441,2797,2803,2809,2995,3012,3016,3026,3285,3302,3306,3311,3417,3420,3425,3466,3475,3479,3484,3526,3532,3536,3539,3547,3561,3573,3577,3610],[512,513,514,515,519,520,524],"p",{},"A ",[516,517,518],"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 (",[521,522,523],"a",{"href":138},"Adapters overview","). When you need a destination that isn't covered, you write your own.",[512,526,527],{},"Two factories cover every case:",[529,530,531,544],"table",{},[532,533,534],"thead",{},[535,536,537,541],"tr",{},[538,539,540],"th",{},"You have…",[538,542,543],{},"Use",[545,546,547,566],"tbody",{},[535,548,549,558],{},[550,551,552,553,557],"td",{},"An HTTP backend (REST, JSON ingest, vendor ",[554,555,556],"code",{},"\u002Fv1\u002Flogs"," endpoint)",[550,559,560],{},[521,561,563],{"href":562},"#definehttpdrain-the-http-recipe",[554,564,565],{},"defineHttpDrain",[535,567,568,571],{},[550,569,570],{},"A non-HTTP transport (gRPC, WebSocket, vendor SDK, queue, raw socket)",[550,572,573],{},[521,574,576],{"href":575},"#definedrain-non-http-transports",[554,577,578],{},"defineDrain",[512,580,581,582,585],{},"Both come from ",[554,583,584],{},"evlog\u002Ftoolkit"," and are the exact factories every built-in adapter uses.",[587,588,592,595,694],"prompt",{":actions":589,"description":590,"icon":591},"[\"copy\",\"cursor\",\"claude\"]","Build a custom evlog drain","i-lucide-code-2",[512,593,594],{},"Build a custom evlog drain that ships wide events to a backend without a built-in adapter.",[596,597,598,613,624,639,657,672,677,687],"ul",{},[599,600,601,602,605,606,608,609,612],"li",{},"For HTTP backends, use ",[554,603,604],{},"defineHttpDrain({ name, resolve, encode })"," from ",[554,607,584],{}," — never call ",[554,610,611],{},"fetch"," directly",[599,614,615,616,619,620,623],{},"For non-HTTP transports (queue, DB, native SDK, raw socket), use ",[554,617,618],{},"defineDrain({ name, send })"," and implement ",[554,621,622],{},"send(events)"," myself",[599,625,626,627,630,631,634,635,638],{},"Resolve config lazily inside ",[554,628,629],{},"resolve()"," via ",[554,632,633],{},"resolveAdapterConfig(namespace, fields, overrides)"," so users get the standard precedence (overrides → ",[554,636,637],{},"runtimeConfig.evlog.\u003Cns>"," → env)",[599,640,641,642,645,646,649,650,653,654],{},"Use the standardized field names: ",[554,643,644],{},"apiKey"," for bearer secrets, ",[554,647,648],{},"endpoint"," for the base URL, ",[554,651,652],{},"serviceName",", ",[554,655,656],{},"timeout",[599,658,659,660,663,664,667,668,671],{},"Encode batched events into the destination's wire format inside ",[554,661,662],{},"encode(events, config)"," — return ",[554,665,666],{},"{ url, headers, body }"," (or ",[554,669,670],{},"null"," to opt out of the batch)",[599,673,674,676],{},[554,675,565],{}," handles retries, timeouts, error isolation, batching, and identity headers — don't reimplement them",[599,678,679,680,683,684,686],{},"Wire the drain via ",[554,681,682],{},"defineEvlog({ drain: createMyDrain() })"," or my framework's middleware ",[554,685,518],{}," option",[599,688,689,690,693],{},"For production, wrap the result in ",[554,691,692],{},"createDrainPipeline"," for batching + retries",[512,695,696,697,702,703],{},"Docs: ",[521,698,699],{"href":699,"rel":700},"https:\u002F\u002Fwww.evlog.dev\u002Fextend\u002Fcustom-drains",[701],"nofollow","\nPipeline: ",[521,704,705],{"href":705,"rel":706},"https:\u002F\u002Fwww.evlog.dev\u002Fextend\u002Fdrain-pipeline",[701],[708,709,711,713],"h2",{"id":710},"definehttpdrain-the-http-recipe",[554,712,565],{}," (the HTTP recipe)",[512,715,716,717,719,720,722,723,726],{},"The recipe every built-in adapter follows. Two pure functions: ",[554,718,629],{}," returns the config (or ",[554,721,670],{}," to skip), ",[554,724,725],{},"encode()"," returns the HTTP request payload.",[728,729,730],"code-collapse",{},[731,732,738],"pre",{"className":733,"code":734,"filename":735,"language":736,"meta":737,"style":737},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import {\n  defineHttpDrain,\n  resolveAdapterConfig,\n  type ConfigField,\n} from 'evlog\u002Ftoolkit'\n\ninterface MyServiceConfig {\n  apiKey: string\n  endpoint?: string\n  timeout?: number\n}\n\nconst FIELDS: ConfigField\u003CMyServiceConfig>[] = [\n  { key: 'apiKey', env: ['MYSERVICE_API_KEY'] },\n  { key: 'endpoint', env: ['MYSERVICE_ENDPOINT'] },\n  { key: 'timeout' },\n]\n\nexport function createMyServiceDrain(overrides?: Partial\u003CMyServiceConfig>) {\n  return defineHttpDrain\u003CMyServiceConfig>({\n    name: 'myservice',\n    resolve: async () => {\n      const cfg = await resolveAdapterConfig\u003CMyServiceConfig>('myservice', FIELDS, overrides)\n      if (!cfg.apiKey) {\n        console.error('[evlog\u002Fmyservice] Missing apiKey')\n        return null\n      }\n      return cfg as MyServiceConfig\n    },\n    encode: (events, cfg) => ({\n      url: `${cfg.endpoint ?? 'https:\u002F\u002Fapi.myservice.com'}\u002Fv1\u002Fingest`,\n      headers: {\n        'Content-Type': 'application\u002Fjson',\n        Authorization: `Bearer ${cfg.apiKey}`,\n      },\n      body: JSON.stringify(events),\n    }),\n  })\n}\n","lib\u002Fmy-drain.ts","typescript","",[554,739,740,753,763,771,782,800,807,820,833,844,855,861,866,897,939,973,991,997,1002,1036,1056,1073,1092,1136,1161,1183,1192,1198,1212,1218,1244,1281,1291,1313,1341,1347,1371,1381,1389],{"__ignoreMap":737},[741,742,745,749],"span",{"class":743,"line":744},"line",1,[741,746,748],{"class":747},"s7zQu","import",[741,750,752],{"class":751},"sMK4o"," {\n",[741,754,756,760],{"class":743,"line":755},2,[741,757,759],{"class":758},"sTEyZ","  defineHttpDrain",[741,761,762],{"class":751},",\n",[741,764,766,769],{"class":743,"line":765},3,[741,767,768],{"class":758},"  resolveAdapterConfig",[741,770,762],{"class":751},[741,772,774,777,780],{"class":743,"line":773},4,[741,775,776],{"class":747},"  type",[741,778,779],{"class":758}," ConfigField",[741,781,762],{"class":751},[741,783,785,788,791,794,797],{"class":743,"line":784},5,[741,786,787],{"class":751},"}",[741,789,790],{"class":747}," from",[741,792,793],{"class":751}," '",[741,795,584],{"class":796},"sfazB",[741,798,799],{"class":751},"'\n",[741,801,803],{"class":743,"line":802},6,[741,804,806],{"emptyLinePlaceholder":805},true,"\n",[741,808,810,814,818],{"class":743,"line":809},7,[741,811,813],{"class":812},"spNyl","interface",[741,815,817],{"class":816},"sBMFI"," MyServiceConfig",[741,819,752],{"class":751},[741,821,823,827,830],{"class":743,"line":822},8,[741,824,826],{"class":825},"swJcz","  apiKey",[741,828,829],{"class":751},":",[741,831,832],{"class":816}," string\n",[741,834,836,839,842],{"class":743,"line":835},9,[741,837,838],{"class":825},"  endpoint",[741,840,841],{"class":751},"?:",[741,843,832],{"class":816},[741,845,847,850,852],{"class":743,"line":846},10,[741,848,849],{"class":825},"  timeout",[741,851,841],{"class":751},[741,853,854],{"class":816}," number\n",[741,856,858],{"class":743,"line":857},11,[741,859,860],{"class":751},"}\n",[741,862,864],{"class":743,"line":863},12,[741,865,806],{"emptyLinePlaceholder":805},[741,867,869,872,875,877,879,882,885,888,891,894],{"class":743,"line":868},13,[741,870,871],{"class":812},"const",[741,873,874],{"class":758}," FIELDS",[741,876,829],{"class":751},[741,878,779],{"class":816},[741,880,881],{"class":751},"\u003C",[741,883,884],{"class":816},"MyServiceConfig",[741,886,887],{"class":751},">",[741,889,890],{"class":758},"[] ",[741,892,893],{"class":751},"=",[741,895,896],{"class":758}," [\n",[741,898,900,903,906,908,910,912,915,918,921,923,926,928,931,933,936],{"class":743,"line":899},14,[741,901,902],{"class":751},"  {",[741,904,905],{"class":825}," key",[741,907,829],{"class":751},[741,909,793],{"class":751},[741,911,644],{"class":796},[741,913,914],{"class":751},"'",[741,916,917],{"class":751},",",[741,919,920],{"class":825}," env",[741,922,829],{"class":751},[741,924,925],{"class":758}," [",[741,927,914],{"class":751},[741,929,930],{"class":796},"MYSERVICE_API_KEY",[741,932,914],{"class":751},[741,934,935],{"class":758},"] ",[741,937,938],{"class":751},"},\n",[741,940,942,944,946,948,950,952,954,956,958,960,962,964,967,969,971],{"class":743,"line":941},15,[741,943,902],{"class":751},[741,945,905],{"class":825},[741,947,829],{"class":751},[741,949,793],{"class":751},[741,951,648],{"class":796},[741,953,914],{"class":751},[741,955,917],{"class":751},[741,957,920],{"class":825},[741,959,829],{"class":751},[741,961,925],{"class":758},[741,963,914],{"class":751},[741,965,966],{"class":796},"MYSERVICE_ENDPOINT",[741,968,914],{"class":751},[741,970,935],{"class":758},[741,972,938],{"class":751},[741,974,976,978,980,982,984,986,988],{"class":743,"line":975},16,[741,977,902],{"class":751},[741,979,905],{"class":825},[741,981,829],{"class":751},[741,983,793],{"class":751},[741,985,656],{"class":796},[741,987,914],{"class":751},[741,989,990],{"class":751}," },\n",[741,992,994],{"class":743,"line":993},17,[741,995,996],{"class":758},"]\n",[741,998,1000],{"class":743,"line":999},18,[741,1001,806],{"emptyLinePlaceholder":805},[741,1003,1005,1008,1011,1015,1018,1022,1024,1027,1029,1031,1034],{"class":743,"line":1004},19,[741,1006,1007],{"class":747},"export",[741,1009,1010],{"class":812}," function",[741,1012,1014],{"class":1013},"s2Zo4"," createMyServiceDrain",[741,1016,1017],{"class":751},"(",[741,1019,1021],{"class":1020},"sHdIc","overrides",[741,1023,841],{"class":751},[741,1025,1026],{"class":816}," Partial",[741,1028,881],{"class":751},[741,1030,884],{"class":816},[741,1032,1033],{"class":751},">)",[741,1035,752],{"class":751},[741,1037,1039,1042,1045,1047,1049,1051,1053],{"class":743,"line":1038},20,[741,1040,1041],{"class":747},"  return",[741,1043,1044],{"class":1013}," defineHttpDrain",[741,1046,881],{"class":751},[741,1048,884],{"class":816},[741,1050,887],{"class":751},[741,1052,1017],{"class":825},[741,1054,1055],{"class":751},"{\n",[741,1057,1059,1062,1064,1066,1069,1071],{"class":743,"line":1058},21,[741,1060,1061],{"class":825},"    name",[741,1063,829],{"class":751},[741,1065,793],{"class":751},[741,1067,1068],{"class":796},"myservice",[741,1070,914],{"class":751},[741,1072,762],{"class":751},[741,1074,1076,1079,1081,1084,1087,1090],{"class":743,"line":1075},22,[741,1077,1078],{"class":1013},"    resolve",[741,1080,829],{"class":751},[741,1082,1083],{"class":812}," async",[741,1085,1086],{"class":751}," ()",[741,1088,1089],{"class":812}," =>",[741,1091,752],{"class":751},[741,1093,1095,1098,1101,1104,1107,1110,1112,1114,1116,1118,1120,1122,1124,1126,1128,1130,1133],{"class":743,"line":1094},23,[741,1096,1097],{"class":812},"      const",[741,1099,1100],{"class":758}," cfg",[741,1102,1103],{"class":751}," =",[741,1105,1106],{"class":747}," await",[741,1108,1109],{"class":1013}," resolveAdapterConfig",[741,1111,881],{"class":751},[741,1113,884],{"class":816},[741,1115,887],{"class":751},[741,1117,1017],{"class":825},[741,1119,914],{"class":751},[741,1121,1068],{"class":796},[741,1123,914],{"class":751},[741,1125,917],{"class":751},[741,1127,874],{"class":758},[741,1129,917],{"class":751},[741,1131,1132],{"class":758}," overrides",[741,1134,1135],{"class":825},")\n",[741,1137,1139,1142,1145,1148,1151,1154,1156,1159],{"class":743,"line":1138},24,[741,1140,1141],{"class":747},"      if",[741,1143,1144],{"class":825}," (",[741,1146,1147],{"class":751},"!",[741,1149,1150],{"class":758},"cfg",[741,1152,1153],{"class":751},".",[741,1155,644],{"class":758},[741,1157,1158],{"class":825},") ",[741,1160,1055],{"class":751},[741,1162,1164,1167,1169,1172,1174,1176,1179,1181],{"class":743,"line":1163},25,[741,1165,1166],{"class":758},"        console",[741,1168,1153],{"class":751},[741,1170,1171],{"class":1013},"error",[741,1173,1017],{"class":825},[741,1175,914],{"class":751},[741,1177,1178],{"class":796},"[evlog\u002Fmyservice] Missing apiKey",[741,1180,914],{"class":751},[741,1182,1135],{"class":825},[741,1184,1186,1189],{"class":743,"line":1185},26,[741,1187,1188],{"class":747},"        return",[741,1190,1191],{"class":751}," null\n",[741,1193,1195],{"class":743,"line":1194},27,[741,1196,1197],{"class":751},"      }\n",[741,1199,1201,1204,1206,1209],{"class":743,"line":1200},28,[741,1202,1203],{"class":747},"      return",[741,1205,1100],{"class":758},[741,1207,1208],{"class":747}," as",[741,1210,1211],{"class":816}," MyServiceConfig\n",[741,1213,1215],{"class":743,"line":1214},29,[741,1216,1217],{"class":751},"    },\n",[741,1219,1221,1224,1226,1228,1231,1233,1235,1238,1240,1242],{"class":743,"line":1220},30,[741,1222,1223],{"class":1013},"    encode",[741,1225,829],{"class":751},[741,1227,1144],{"class":751},[741,1229,1230],{"class":1020},"events",[741,1232,917],{"class":751},[741,1234,1100],{"class":1020},[741,1236,1237],{"class":751},")",[741,1239,1089],{"class":812},[741,1241,1144],{"class":825},[741,1243,1055],{"class":751},[741,1245,1247,1250,1252,1255,1257,1259,1262,1265,1267,1270,1273,1276,1279],{"class":743,"line":1246},31,[741,1248,1249],{"class":825},"      url",[741,1251,829],{"class":751},[741,1253,1254],{"class":751}," `${",[741,1256,1150],{"class":758},[741,1258,1153],{"class":751},[741,1260,1261],{"class":758},"endpoint ",[741,1263,1264],{"class":751},"??",[741,1266,793],{"class":751},[741,1268,1269],{"class":796},"https:\u002F\u002Fapi.myservice.com",[741,1271,1272],{"class":751},"'}",[741,1274,1275],{"class":796},"\u002Fv1\u002Fingest",[741,1277,1278],{"class":751},"`",[741,1280,762],{"class":751},[741,1282,1284,1287,1289],{"class":743,"line":1283},32,[741,1285,1286],{"class":825},"      headers",[741,1288,829],{"class":751},[741,1290,752],{"class":751},[741,1292,1294,1297,1300,1302,1304,1306,1309,1311],{"class":743,"line":1293},33,[741,1295,1296],{"class":751},"        '",[741,1298,1299],{"class":825},"Content-Type",[741,1301,914],{"class":751},[741,1303,829],{"class":751},[741,1305,793],{"class":751},[741,1307,1308],{"class":796},"application\u002Fjson",[741,1310,914],{"class":751},[741,1312,762],{"class":751},[741,1314,1316,1319,1321,1324,1327,1330,1332,1334,1336,1339],{"class":743,"line":1315},34,[741,1317,1318],{"class":825},"        Authorization",[741,1320,829],{"class":751},[741,1322,1323],{"class":751}," `",[741,1325,1326],{"class":796},"Bearer ",[741,1328,1329],{"class":751},"${",[741,1331,1150],{"class":758},[741,1333,1153],{"class":751},[741,1335,644],{"class":758},[741,1337,1338],{"class":751},"}`",[741,1340,762],{"class":751},[741,1342,1344],{"class":743,"line":1343},35,[741,1345,1346],{"class":751},"      },\n",[741,1348,1350,1353,1355,1358,1360,1363,1365,1367,1369],{"class":743,"line":1349},36,[741,1351,1352],{"class":825},"      body",[741,1354,829],{"class":751},[741,1356,1357],{"class":758}," JSON",[741,1359,1153],{"class":751},[741,1361,1362],{"class":1013},"stringify",[741,1364,1017],{"class":825},[741,1366,1230],{"class":758},[741,1368,1237],{"class":825},[741,1370,762],{"class":751},[741,1372,1374,1377,1379],{"class":743,"line":1373},37,[741,1375,1376],{"class":751},"    }",[741,1378,1237],{"class":825},[741,1380,762],{"class":751},[741,1382,1384,1387],{"class":743,"line":1383},38,[741,1385,1386],{"class":751},"  }",[741,1388,1135],{"class":825},[741,1390,1392],{"class":743,"line":1391},39,[741,1393,860],{"class":751},[512,1395,1396,1397,1399,1400,1403,1404,1407],{},"That's it. ",[554,1398,565],{}," handles batching, retries (default 2), timeouts (default 5000ms), error isolation, and the identity headers (",[554,1401,1402],{},"User-Agent: evlog\u002F\u003Cversion>"," + ",[554,1405,1406],{},"X-Evlog-Source: \u003Cname>","). Your app pipeline keeps running even if your destination is down.",[1409,1410,1412],"h3",{"id":1411},"a-5-minute-example-internal-loki-drain","A 5-minute example — internal Loki drain",[512,1414,1415],{},"A complete working drain in 25 lines, with no external config helper:",[731,1417,1422],{"className":1418,"code":1419,"filename":1420,"language":1421,"meta":737,"style":737},"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","lib\u002Floki-drain.ts","ts",[554,1423,1424,1444,1448,1487,1517,1532,1546,1579,1608,1616,1639,1663,1671,1689,1711,1715,1731,1756,1794,1854,1864,1873,1881,1887],{"__ignoreMap":737},[741,1425,1426,1428,1431,1433,1436,1438,1440,1442],{"class":743,"line":744},[741,1427,748],{"class":747},[741,1429,1430],{"class":751}," {",[741,1432,1044],{"class":758},[741,1434,1435],{"class":751}," }",[741,1437,790],{"class":747},[741,1439,793],{"class":751},[741,1441,584],{"class":796},[741,1443,799],{"class":751},[741,1445,1446],{"class":743,"line":755},[741,1447,806],{"emptyLinePlaceholder":805},[741,1449,1450,1452,1454,1457,1459,1461,1463,1465,1468,1470,1473,1475,1478,1480,1482,1485],{"class":743,"line":765},[741,1451,1007],{"class":747},[741,1453,1010],{"class":812},[741,1455,1456],{"class":1013}," createLokiDrain",[741,1458,1017],{"class":751},[741,1460,1021],{"class":1020},[741,1462,841],{"class":751},[741,1464,1430],{"class":751},[741,1466,1467],{"class":825}," url",[741,1469,841],{"class":751},[741,1471,1472],{"class":816}," string",[741,1474,917],{"class":751},[741,1476,1477],{"class":825}," token",[741,1479,841],{"class":751},[741,1481,1472],{"class":816},[741,1483,1484],{"class":751}," })",[741,1486,752],{"class":751},[741,1488,1489,1491,1493,1496,1498,1500,1502,1504,1506,1508,1510,1513,1515],{"class":743,"line":773},[741,1490,1041],{"class":747},[741,1492,1044],{"class":1013},[741,1494,1495],{"class":751},"\u003C{",[741,1497,1467],{"class":825},[741,1499,829],{"class":751},[741,1501,1472],{"class":816},[741,1503,917],{"class":751},[741,1505,1477],{"class":825},[741,1507,829],{"class":751},[741,1509,1472],{"class":816},[741,1511,1512],{"class":751}," }>",[741,1514,1017],{"class":825},[741,1516,1055],{"class":751},[741,1518,1519,1521,1523,1525,1528,1530],{"class":743,"line":784},[741,1520,1061],{"class":825},[741,1522,829],{"class":751},[741,1524,793],{"class":751},[741,1526,1527],{"class":796},"loki",[741,1529,914],{"class":751},[741,1531,762],{"class":751},[741,1533,1534,1536,1538,1540,1542,1544],{"class":743,"line":802},[741,1535,1078],{"class":1013},[741,1537,829],{"class":751},[741,1539,1086],{"class":751},[741,1541,1089],{"class":812},[741,1543,1144],{"class":825},[741,1545,1055],{"class":751},[741,1547,1548,1550,1552,1554,1557,1560,1563,1566,1568,1571,1573,1576],{"class":743,"line":809},[741,1549,1249],{"class":825},[741,1551,829],{"class":751},[741,1553,1132],{"class":758},[741,1555,1556],{"class":751},"?.",[741,1558,1559],{"class":758},"url",[741,1561,1562],{"class":751}," ??",[741,1564,1565],{"class":758}," process",[741,1567,1153],{"class":751},[741,1569,1570],{"class":758},"env",[741,1572,1153],{"class":751},[741,1574,1575],{"class":758},"LOKI_URL",[741,1577,1578],{"class":751},"!,\n",[741,1580,1581,1584,1586,1588,1590,1593,1595,1597,1599,1601,1603,1606],{"class":743,"line":822},[741,1582,1583],{"class":825},"      token",[741,1585,829],{"class":751},[741,1587,1132],{"class":758},[741,1589,1556],{"class":751},[741,1591,1592],{"class":758},"token",[741,1594,1562],{"class":751},[741,1596,1565],{"class":758},[741,1598,1153],{"class":751},[741,1600,1570],{"class":758},[741,1602,1153],{"class":751},[741,1604,1605],{"class":758},"LOKI_TOKEN",[741,1607,1578],{"class":751},[741,1609,1610,1612,1614],{"class":743,"line":835},[741,1611,1376],{"class":751},[741,1613,1237],{"class":825},[741,1615,762],{"class":751},[741,1617,1618,1620,1622,1624,1626,1628,1631,1633,1635,1637],{"class":743,"line":846},[741,1619,1223],{"class":1013},[741,1621,829],{"class":751},[741,1623,1144],{"class":751},[741,1625,1230],{"class":1020},[741,1627,917],{"class":751},[741,1629,1630],{"class":1020}," config",[741,1632,1237],{"class":751},[741,1634,1089],{"class":812},[741,1636,1144],{"class":825},[741,1638,1055],{"class":751},[741,1640,1641,1643,1645,1647,1650,1652,1654,1656,1659,1661],{"class":743,"line":857},[741,1642,1249],{"class":825},[741,1644,829],{"class":751},[741,1646,1254],{"class":751},[741,1648,1649],{"class":758},"config",[741,1651,1153],{"class":751},[741,1653,1559],{"class":758},[741,1655,787],{"class":751},[741,1657,1658],{"class":796},"\u002Floki\u002Fapi\u002Fv1\u002Fpush",[741,1660,1278],{"class":751},[741,1662,762],{"class":751},[741,1664,1665,1667,1669],{"class":743,"line":863},[741,1666,1286],{"class":825},[741,1668,829],{"class":751},[741,1670,752],{"class":751},[741,1672,1673,1675,1677,1679,1681,1683,1685,1687],{"class":743,"line":868},[741,1674,1296],{"class":751},[741,1676,1299],{"class":825},[741,1678,914],{"class":751},[741,1680,829],{"class":751},[741,1682,793],{"class":751},[741,1684,1308],{"class":796},[741,1686,914],{"class":751},[741,1688,762],{"class":751},[741,1690,1691,1693,1695,1697,1699,1701,1703,1705,1707,1709],{"class":743,"line":899},[741,1692,1318],{"class":825},[741,1694,829],{"class":751},[741,1696,1323],{"class":751},[741,1698,1326],{"class":796},[741,1700,1329],{"class":751},[741,1702,1649],{"class":758},[741,1704,1153],{"class":751},[741,1706,1592],{"class":758},[741,1708,1338],{"class":751},[741,1710,762],{"class":751},[741,1712,1713],{"class":743,"line":941},[741,1714,1346],{"class":751},[741,1716,1717,1719,1721,1723,1725,1727,1729],{"class":743,"line":975},[741,1718,1352],{"class":825},[741,1720,829],{"class":751},[741,1722,1357],{"class":758},[741,1724,1153],{"class":751},[741,1726,1362],{"class":1013},[741,1728,1017],{"class":825},[741,1730,1055],{"class":751},[741,1732,1733,1736,1738,1741,1743,1745,1747,1750,1752,1754],{"class":743,"line":993},[741,1734,1735],{"class":825},"        streams",[741,1737,829],{"class":751},[741,1739,1740],{"class":758}," events",[741,1742,1153],{"class":751},[741,1744,94],{"class":1013},[741,1746,1017],{"class":825},[741,1748,1749],{"class":1020},"e",[741,1751,1089],{"class":812},[741,1753,1144],{"class":825},[741,1755,1055],{"class":751},[741,1757,1758,1761,1763,1765,1768,1770,1773,1775,1778,1780,1783,1785,1787,1789,1792],{"class":743,"line":999},[741,1759,1760],{"class":825},"          stream",[741,1762,829],{"class":751},[741,1764,1430],{"class":751},[741,1766,1767],{"class":825}," service",[741,1769,829],{"class":751},[741,1771,1772],{"class":758}," e",[741,1774,1153],{"class":751},[741,1776,1777],{"class":758},"service",[741,1779,917],{"class":751},[741,1781,1782],{"class":825}," level",[741,1784,829],{"class":751},[741,1786,1772],{"class":758},[741,1788,1153],{"class":751},[741,1790,1791],{"class":758},"level",[741,1793,990],{"class":751},[741,1795,1796,1799,1801,1804,1807,1809,1812,1814,1817,1819,1821,1823,1826,1828,1831,1835,1837,1839,1841,1843,1845,1847,1849,1852],{"class":743,"line":1004},[741,1797,1798],{"class":825},"          values",[741,1800,829],{"class":751},[741,1802,1803],{"class":825}," [[",[741,1805,1806],{"class":1013},"String",[741,1808,1017],{"class":825},[741,1810,1811],{"class":758},"Date",[741,1813,1153],{"class":751},[741,1815,1816],{"class":1013},"parse",[741,1818,1017],{"class":825},[741,1820,1749],{"class":758},[741,1822,1153],{"class":751},[741,1824,1825],{"class":758},"timestamp",[741,1827,1158],{"class":825},[741,1829,1830],{"class":751},"*",[741,1832,1834],{"class":1833},"sbssI"," 1e6",[741,1836,1237],{"class":825},[741,1838,917],{"class":751},[741,1840,1357],{"class":758},[741,1842,1153],{"class":751},[741,1844,1362],{"class":1013},[741,1846,1017],{"class":825},[741,1848,1749],{"class":758},[741,1850,1851],{"class":825},")]]",[741,1853,762],{"class":751},[741,1855,1856,1859,1862],{"class":743,"line":1038},[741,1857,1858],{"class":751},"        }",[741,1860,1861],{"class":825},"))",[741,1863,762],{"class":751},[741,1865,1866,1869,1871],{"class":743,"line":1058},[741,1867,1868],{"class":751},"      }",[741,1870,1237],{"class":825},[741,1872,762],{"class":751},[741,1874,1875,1877,1879],{"class":743,"line":1075},[741,1876,1376],{"class":751},[741,1878,1237],{"class":825},[741,1880,762],{"class":751},[741,1882,1883,1885],{"class":743,"line":1094},[741,1884,1386],{"class":751},[741,1886,1135],{"class":825},[741,1888,1889],{"class":743,"line":1138},[741,1890,860],{"class":751},[708,1892,1894],{"id":1893},"standardized-config-priority","Standardized config priority",[512,1896,1897,1899],{},[554,1898,633],{}," walks the standard chain so users get the same configuration UX as built-in adapters:",[1901,1902,1903,1909,1915,1921],"ol",{},[599,1904,1905,1906,1908],{},"Explicit ",[554,1907,1021],{}," passed to your factory",[599,1910,1911,1914],{},[554,1912,1913],{},"runtimeConfig.evlog.\u003Cnamespace>"," (Nuxt\u002FNitro)",[599,1916,1917,1920],{},[554,1918,1919],{},"runtimeConfig.\u003Cnamespace>"," (legacy Nuxt\u002FNitro)",[599,1922,1923,1926,1927,1930,1931,1934,1935,1937,1938,1237],{},[554,1924,1925],{},"\u003CNS>_\u003CFIELD>"," env vars (list ",[554,1928,1929],{},"NUXT_\u003CNS>_\u003CFIELD>"," in ",[554,1932,1933],{},"ConfigField.env"," for silent Nuxt compat; show only ",[554,1936,1925],{}," in error messages via ",[554,1939,1940],{},"formatPublicEnvKeys",[512,1942,1943,1944,653,1946,653,1948,653,1950,1952,1953,1955,1956,1958,1959,1962,1963,1966,1967,1970],{},"Field names should follow the project conventions: ",[554,1945,644],{},[554,1947,648],{},[554,1949,652],{},[554,1951,656],{},". If you're renaming an existing field (e.g. ",[554,1954,1592],{}," → ",[554,1957,644],{},"), keep both as ",[554,1960,1961],{},"ConfigField"," entries for one major version — see ",[554,1964,1965],{},"axiom.ts"," and ",[554,1968,1969],{},"better-stack.ts"," for the deprecation pattern.",[708,1972,1974],{"id":1973},"wiring-the-drain-into-your-framework","Wiring the drain into your framework",[512,1976,1977,1978,1981],{},"Once ",[554,1979,1980],{},"createMyServiceDrain()"," returns the drain, wire it like any other:",[1983,1984,1985,2098,2224,2282,2319,2350],"code-group",{},[731,1986,1989],{"className":733,"code":1987,"filename":1988,"language":736,"meta":737,"style":737},"\u002F\u002F server\u002Fplugins\u002Fevlog-drain.ts\nimport { createMyServiceDrain } from '~\u002Fserver\u002Futils\u002Fmy-drain'\n\nconst drain = createMyServiceDrain()\n\nexport default defineNitroPlugin((nitroApp) => {\n  nitroApp.hooks.hook('evlog:drain', drain)\n})\n","Nuxt \u002F Nitro",[554,1990,1991,1997,2016,2020,2034,2038,2061,2092],{"__ignoreMap":737},[741,1992,1993],{"class":743,"line":744},[741,1994,1996],{"class":1995},"sHwdD","\u002F\u002F server\u002Fplugins\u002Fevlog-drain.ts\n",[741,1998,1999,2001,2003,2005,2007,2009,2011,2014],{"class":743,"line":755},[741,2000,748],{"class":747},[741,2002,1430],{"class":751},[741,2004,1014],{"class":758},[741,2006,1435],{"class":751},[741,2008,790],{"class":747},[741,2010,793],{"class":751},[741,2012,2013],{"class":796},"~\u002Fserver\u002Futils\u002Fmy-drain",[741,2015,799],{"class":751},[741,2017,2018],{"class":743,"line":765},[741,2019,806],{"emptyLinePlaceholder":805},[741,2021,2022,2024,2027,2029,2031],{"class":743,"line":773},[741,2023,871],{"class":812},[741,2025,2026],{"class":758}," drain ",[741,2028,893],{"class":751},[741,2030,1014],{"class":1013},[741,2032,2033],{"class":758},"()\n",[741,2035,2036],{"class":743,"line":784},[741,2037,806],{"emptyLinePlaceholder":805},[741,2039,2040,2042,2045,2048,2050,2052,2055,2057,2059],{"class":743,"line":802},[741,2041,1007],{"class":747},[741,2043,2044],{"class":747}," default",[741,2046,2047],{"class":1013}," defineNitroPlugin",[741,2049,1017],{"class":758},[741,2051,1017],{"class":751},[741,2053,2054],{"class":1020},"nitroApp",[741,2056,1237],{"class":751},[741,2058,1089],{"class":812},[741,2060,752],{"class":751},[741,2062,2063,2066,2068,2071,2073,2076,2078,2080,2083,2085,2087,2090],{"class":743,"line":809},[741,2064,2065],{"class":758},"  nitroApp",[741,2067,1153],{"class":751},[741,2069,2070],{"class":758},"hooks",[741,2072,1153],{"class":751},[741,2074,2075],{"class":1013},"hook",[741,2077,1017],{"class":825},[741,2079,914],{"class":751},[741,2081,2082],{"class":796},"evlog:drain",[741,2084,914],{"class":751},[741,2086,917],{"class":751},[741,2088,2089],{"class":758}," drain",[741,2091,1135],{"class":825},[741,2093,2094,2096],{"class":743,"line":822},[741,2095,787],{"class":751},[741,2097,1135],{"class":758},[731,2099,2101],{"className":733,"code":2100,"filename":215,"language":736,"meta":737,"style":737},"\u002F\u002F lib\u002Fevlog.ts\nimport { createEvlog } from 'evlog\u002Fnext'\nimport { createMyServiceDrain } from '.\u002Fmy-drain'\n\nexport const { withEvlog, useLogger, log, createError } = createEvlog({\n  service: 'my-app',\n  drain: createMyServiceDrain(),\n})\n",[554,2102,2103,2108,2128,2147,2151,2188,2204,2218],{"__ignoreMap":737},[741,2104,2105],{"class":743,"line":744},[741,2106,2107],{"class":1995},"\u002F\u002F lib\u002Fevlog.ts\n",[741,2109,2110,2112,2114,2117,2119,2121,2123,2126],{"class":743,"line":755},[741,2111,748],{"class":747},[741,2113,1430],{"class":751},[741,2115,2116],{"class":758}," createEvlog",[741,2118,1435],{"class":751},[741,2120,790],{"class":747},[741,2122,793],{"class":751},[741,2124,2125],{"class":796},"evlog\u002Fnext",[741,2127,799],{"class":751},[741,2129,2130,2132,2134,2136,2138,2140,2142,2145],{"class":743,"line":765},[741,2131,748],{"class":747},[741,2133,1430],{"class":751},[741,2135,1014],{"class":758},[741,2137,1435],{"class":751},[741,2139,790],{"class":747},[741,2141,793],{"class":751},[741,2143,2144],{"class":796},".\u002Fmy-drain",[741,2146,799],{"class":751},[741,2148,2149],{"class":743,"line":773},[741,2150,806],{"emptyLinePlaceholder":805},[741,2152,2153,2155,2158,2160,2163,2165,2168,2170,2173,2175,2178,2180,2182,2184,2186],{"class":743,"line":784},[741,2154,1007],{"class":747},[741,2156,2157],{"class":812}," const",[741,2159,1430],{"class":751},[741,2161,2162],{"class":758}," withEvlog",[741,2164,917],{"class":751},[741,2166,2167],{"class":758}," useLogger",[741,2169,917],{"class":751},[741,2171,2172],{"class":758}," log",[741,2174,917],{"class":751},[741,2176,2177],{"class":758}," createError ",[741,2179,787],{"class":751},[741,2181,1103],{"class":751},[741,2183,2116],{"class":1013},[741,2185,1017],{"class":758},[741,2187,1055],{"class":751},[741,2189,2190,2193,2195,2197,2200,2202],{"class":743,"line":802},[741,2191,2192],{"class":825},"  service",[741,2194,829],{"class":751},[741,2196,793],{"class":751},[741,2198,2199],{"class":796},"my-app",[741,2201,914],{"class":751},[741,2203,762],{"class":751},[741,2205,2206,2209,2211,2213,2216],{"class":743,"line":809},[741,2207,2208],{"class":825},"  drain",[741,2210,829],{"class":751},[741,2212,1014],{"class":1013},[741,2214,2215],{"class":758},"()",[741,2217,762],{"class":751},[741,2219,2220,2222],{"class":743,"line":822},[741,2221,787],{"class":751},[741,2223,1135],{"class":758},[731,2225,2228],{"className":733,"code":2226,"filename":2227,"language":736,"meta":737,"style":737},"import { createMyServiceDrain } from '.\u002Fmy-drain'\napp.use(evlog({ drain: createMyServiceDrain() }))\n","Hono \u002F Express \u002F Elysia",[554,2229,2230,2248],{"__ignoreMap":737},[741,2231,2232,2234,2236,2238,2240,2242,2244,2246],{"class":743,"line":744},[741,2233,748],{"class":747},[741,2235,1430],{"class":751},[741,2237,1014],{"class":758},[741,2239,1435],{"class":751},[741,2241,790],{"class":747},[741,2243,793],{"class":751},[741,2245,2144],{"class":796},[741,2247,799],{"class":751},[741,2249,2250,2253,2255,2258,2260,2263,2265,2268,2270,2272,2274,2277,2279],{"class":743,"line":755},[741,2251,2252],{"class":758},"app",[741,2254,1153],{"class":751},[741,2256,2257],{"class":1013},"use",[741,2259,1017],{"class":758},[741,2261,2262],{"class":1013},"evlog",[741,2264,1017],{"class":758},[741,2266,2267],{"class":751},"{",[741,2269,2089],{"class":825},[741,2271,829],{"class":751},[741,2273,1014],{"class":1013},[741,2275,2276],{"class":758},"() ",[741,2278,787],{"class":751},[741,2280,2281],{"class":758},"))\n",[731,2283,2285],{"className":733,"code":2284,"filename":250,"language":736,"meta":737,"style":737},"await app.register(evlog, { drain: createMyServiceDrain() })\n",[554,2286,2287],{"__ignoreMap":737},[741,2288,2289,2292,2295,2297,2300,2303,2305,2307,2309,2311,2313,2315,2317],{"class":743,"line":744},[741,2290,2291],{"class":747},"await",[741,2293,2294],{"class":758}," app",[741,2296,1153],{"class":751},[741,2298,2299],{"class":1013},"register",[741,2301,2302],{"class":758},"(evlog",[741,2304,917],{"class":751},[741,2306,1430],{"class":751},[741,2308,2089],{"class":825},[741,2310,829],{"class":751},[741,2312,1014],{"class":1013},[741,2314,2276],{"class":758},[741,2316,787],{"class":751},[741,2318,1135],{"class":758},[731,2320,2322],{"className":733,"code":2321,"filename":235,"language":736,"meta":737,"style":737},"EvlogModule.forRoot({ drain: createMyServiceDrain() })\n",[554,2323,2324],{"__ignoreMap":737},[741,2325,2326,2329,2331,2334,2336,2338,2340,2342,2344,2346,2348],{"class":743,"line":744},[741,2327,2328],{"class":758},"EvlogModule",[741,2330,1153],{"class":751},[741,2332,2333],{"class":1013},"forRoot",[741,2335,1017],{"class":758},[741,2337,2267],{"class":751},[741,2339,2089],{"class":825},[741,2341,829],{"class":751},[741,2343,1014],{"class":1013},[741,2345,2276],{"class":758},[741,2347,787],{"class":751},[741,2349,1135],{"class":758},[731,2351,2353],{"className":733,"code":2352,"filename":270,"language":736,"meta":737,"style":737},"import { initLogger } from 'evlog'\nimport { createMyServiceDrain } from '.\u002Fmy-drain'\n\ninitLogger({ drain: createMyServiceDrain() })\n",[554,2354,2355,2374,2392,2396],{"__ignoreMap":737},[741,2356,2357,2359,2361,2364,2366,2368,2370,2372],{"class":743,"line":744},[741,2358,748],{"class":747},[741,2360,1430],{"class":751},[741,2362,2363],{"class":758}," initLogger",[741,2365,1435],{"class":751},[741,2367,790],{"class":747},[741,2369,793],{"class":751},[741,2371,2262],{"class":796},[741,2373,799],{"class":751},[741,2375,2376,2378,2380,2382,2384,2386,2388,2390],{"class":743,"line":755},[741,2377,748],{"class":747},[741,2379,1430],{"class":751},[741,2381,1014],{"class":758},[741,2383,1435],{"class":751},[741,2385,790],{"class":747},[741,2387,793],{"class":751},[741,2389,2144],{"class":796},[741,2391,799],{"class":751},[741,2393,2394],{"class":743,"line":765},[741,2395,806],{"emptyLinePlaceholder":805},[741,2397,2398,2401,2403,2405,2407,2409,2411,2413,2415],{"class":743,"line":773},[741,2399,2400],{"class":1013},"initLogger",[741,2402,1017],{"class":758},[741,2404,2267],{"class":751},[741,2406,2089],{"class":825},[741,2408,829],{"class":751},[741,2410,1014],{"class":1013},[741,2412,2276],{"class":758},[741,2414,787],{"class":751},[741,2416,1135],{"class":758},[512,2418,2419,2420,2424],{},"For production, wrap it once in ",[521,2421,2422],{"href":472},[554,2423,692],{}," so events are batched and retried.",[708,2426,2428],{"id":2427},"filtering-and-transforming-events","Filtering and transforming events",[512,2430,2431,2433,2434,2437,2438,2440],{},[554,2432,725],{}," receives the full batch of ",[554,2435,2436],{},"WideEvent[]"," plus the resolved config. Filter or transform inline — returning ",[554,2439,670],{}," is a clean opt-out for that batch:",[731,2442,2444],{"className":733,"code":2443,"language":736,"meta":737,"style":737},"encode: (events, cfg) => {\n  const filtered = events.filter(e => e.level === 'error' && e.path !== '\u002Fhealth')\n  if (filtered.length === 0) return null\n\n  const payload = filtered.map(e => ({\n    ts: new Date(e.timestamp).getTime(),\n    severity: e.level.toUpperCase(),\n    attributes: { method: e.method, path: e.path, status: e.status, duration: e.duration },\n  }))\n\n  return {\n    url: `${cfg.endpoint}\u002Fv1\u002Fpush`,\n    headers: { 'Content-Type': 'application\u002Fjson' },\n    body: JSON.stringify(payload),\n  }\n}\n",[554,2445,2446,2467,2527,2554,2558,2583,2615,2637,2701,2707,2711,2717,2741,2766,2788,2793],{"__ignoreMap":737},[741,2447,2448,2451,2453,2455,2457,2459,2461,2463,2465],{"class":743,"line":744},[741,2449,2450],{"class":816},"encode",[741,2452,829],{"class":751},[741,2454,1144],{"class":751},[741,2456,1230],{"class":1020},[741,2458,917],{"class":751},[741,2460,1100],{"class":1020},[741,2462,1237],{"class":751},[741,2464,1089],{"class":812},[741,2466,752],{"class":751},[741,2468,2469,2472,2475,2477,2479,2481,2484,2486,2488,2490,2492,2494,2496,2499,2501,2503,2505,2508,2510,2512,2515,2518,2520,2523,2525],{"class":743,"line":755},[741,2470,2471],{"class":812},"  const",[741,2473,2474],{"class":758}," filtered",[741,2476,1103],{"class":751},[741,2478,1740],{"class":758},[741,2480,1153],{"class":751},[741,2482,2483],{"class":1013},"filter",[741,2485,1017],{"class":825},[741,2487,1749],{"class":1020},[741,2489,1089],{"class":812},[741,2491,1772],{"class":758},[741,2493,1153],{"class":751},[741,2495,1791],{"class":758},[741,2497,2498],{"class":751}," ===",[741,2500,793],{"class":751},[741,2502,1171],{"class":796},[741,2504,914],{"class":751},[741,2506,2507],{"class":751}," &&",[741,2509,1772],{"class":758},[741,2511,1153],{"class":751},[741,2513,2514],{"class":758},"path",[741,2516,2517],{"class":751}," !==",[741,2519,793],{"class":751},[741,2521,2522],{"class":796},"\u002Fhealth",[741,2524,914],{"class":751},[741,2526,1135],{"class":825},[741,2528,2529,2532,2534,2537,2539,2542,2544,2547,2549,2552],{"class":743,"line":765},[741,2530,2531],{"class":747},"  if",[741,2533,1144],{"class":825},[741,2535,2536],{"class":758},"filtered",[741,2538,1153],{"class":751},[741,2540,2541],{"class":758},"length",[741,2543,2498],{"class":751},[741,2545,2546],{"class":1833}," 0",[741,2548,1158],{"class":825},[741,2550,2551],{"class":747},"return",[741,2553,1191],{"class":751},[741,2555,2556],{"class":743,"line":773},[741,2557,806],{"emptyLinePlaceholder":805},[741,2559,2560,2562,2565,2567,2569,2571,2573,2575,2577,2579,2581],{"class":743,"line":784},[741,2561,2471],{"class":812},[741,2563,2564],{"class":758}," payload",[741,2566,1103],{"class":751},[741,2568,2474],{"class":758},[741,2570,1153],{"class":751},[741,2572,94],{"class":1013},[741,2574,1017],{"class":825},[741,2576,1749],{"class":1020},[741,2578,1089],{"class":812},[741,2580,1144],{"class":825},[741,2582,1055],{"class":751},[741,2584,2585,2588,2590,2593,2596,2598,2600,2602,2604,2606,2608,2611,2613],{"class":743,"line":802},[741,2586,2587],{"class":825},"    ts",[741,2589,829],{"class":751},[741,2591,2592],{"class":751}," new",[741,2594,2595],{"class":1013}," Date",[741,2597,1017],{"class":825},[741,2599,1749],{"class":758},[741,2601,1153],{"class":751},[741,2603,1825],{"class":758},[741,2605,1237],{"class":825},[741,2607,1153],{"class":751},[741,2609,2610],{"class":1013},"getTime",[741,2612,2215],{"class":825},[741,2614,762],{"class":751},[741,2616,2617,2620,2622,2624,2626,2628,2630,2633,2635],{"class":743,"line":809},[741,2618,2619],{"class":825},"    severity",[741,2621,829],{"class":751},[741,2623,1772],{"class":758},[741,2625,1153],{"class":751},[741,2627,1791],{"class":758},[741,2629,1153],{"class":751},[741,2631,2632],{"class":1013},"toUpperCase",[741,2634,2215],{"class":825},[741,2636,762],{"class":751},[741,2638,2639,2642,2644,2646,2649,2651,2653,2655,2658,2660,2663,2665,2667,2669,2671,2673,2676,2678,2680,2682,2685,2687,2690,2692,2694,2696,2699],{"class":743,"line":822},[741,2640,2641],{"class":825},"    attributes",[741,2643,829],{"class":751},[741,2645,1430],{"class":751},[741,2647,2648],{"class":825}," method",[741,2650,829],{"class":751},[741,2652,1772],{"class":758},[741,2654,1153],{"class":751},[741,2656,2657],{"class":758},"method",[741,2659,917],{"class":751},[741,2661,2662],{"class":825}," path",[741,2664,829],{"class":751},[741,2666,1772],{"class":758},[741,2668,1153],{"class":751},[741,2670,2514],{"class":758},[741,2672,917],{"class":751},[741,2674,2675],{"class":825}," status",[741,2677,829],{"class":751},[741,2679,1772],{"class":758},[741,2681,1153],{"class":751},[741,2683,2684],{"class":758},"status",[741,2686,917],{"class":751},[741,2688,2689],{"class":825}," duration",[741,2691,829],{"class":751},[741,2693,1772],{"class":758},[741,2695,1153],{"class":751},[741,2697,2698],{"class":758},"duration",[741,2700,990],{"class":751},[741,2702,2703,2705],{"class":743,"line":835},[741,2704,1386],{"class":751},[741,2706,2281],{"class":825},[741,2708,2709],{"class":743,"line":846},[741,2710,806],{"emptyLinePlaceholder":805},[741,2712,2713,2715],{"class":743,"line":857},[741,2714,1041],{"class":747},[741,2716,752],{"class":751},[741,2718,2719,2722,2724,2726,2728,2730,2732,2734,2737,2739],{"class":743,"line":863},[741,2720,2721],{"class":825},"    url",[741,2723,829],{"class":751},[741,2725,1254],{"class":751},[741,2727,1150],{"class":758},[741,2729,1153],{"class":751},[741,2731,648],{"class":758},[741,2733,787],{"class":751},[741,2735,2736],{"class":796},"\u002Fv1\u002Fpush",[741,2738,1278],{"class":751},[741,2740,762],{"class":751},[741,2742,2743,2746,2748,2750,2752,2754,2756,2758,2760,2762,2764],{"class":743,"line":868},[741,2744,2745],{"class":825},"    headers",[741,2747,829],{"class":751},[741,2749,1430],{"class":751},[741,2751,793],{"class":751},[741,2753,1299],{"class":825},[741,2755,914],{"class":751},[741,2757,829],{"class":751},[741,2759,793],{"class":751},[741,2761,1308],{"class":796},[741,2763,914],{"class":751},[741,2765,990],{"class":751},[741,2767,2768,2771,2773,2775,2777,2779,2781,2784,2786],{"class":743,"line":899},[741,2769,2770],{"class":825},"    body",[741,2772,829],{"class":751},[741,2774,1357],{"class":758},[741,2776,1153],{"class":751},[741,2778,1362],{"class":1013},[741,2780,1017],{"class":825},[741,2782,2783],{"class":758},"payload",[741,2785,1237],{"class":825},[741,2787,762],{"class":751},[741,2789,2790],{"class":743,"line":941},[741,2791,2792],{"class":751},"  }\n",[741,2794,2795],{"class":743,"line":975},[741,2796,860],{"class":751},[708,2798,2800,2802],{"id":2799},"definedrain-non-http-transports",[554,2801,578],{}," (non-HTTP transports)",[512,2804,2805,2806,2808],{},"If your destination requires gRPC, a vendor SDK, a queue client, a WebSocket, or a raw socket, drop one level lower with ",[554,2807,578],{},". You own the transport; the toolkit still gives you config resolution, error isolation, and a consistent shape.",[731,2810,2812],{"className":733,"code":2811,"language":736,"meta":737,"style":737},"import { defineDrain } from 'evlog\u002Ftoolkit'\n\nexport const createCustomTransportDrain = () =>\n  defineDrain\u003C{ apiKey: string }>({\n    name: 'custom',\n    resolve: async () => ({ apiKey: process.env.MY_KEY! }),\n    send: async (events, cfg) => {\n      await myVendorSdk.publish(events, { token: cfg.apiKey })\n    },\n  })\n",[554,2813,2814,2833,2837,2853,2873,2888,2927,2950,2985,2989],{"__ignoreMap":737},[741,2815,2816,2818,2820,2823,2825,2827,2829,2831],{"class":743,"line":744},[741,2817,748],{"class":747},[741,2819,1430],{"class":751},[741,2821,2822],{"class":758}," defineDrain",[741,2824,1435],{"class":751},[741,2826,790],{"class":747},[741,2828,793],{"class":751},[741,2830,584],{"class":796},[741,2832,799],{"class":751},[741,2834,2835],{"class":743,"line":755},[741,2836,806],{"emptyLinePlaceholder":805},[741,2838,2839,2841,2843,2846,2848,2850],{"class":743,"line":765},[741,2840,1007],{"class":747},[741,2842,2157],{"class":812},[741,2844,2845],{"class":758}," createCustomTransportDrain ",[741,2847,893],{"class":751},[741,2849,1086],{"class":751},[741,2851,2852],{"class":812}," =>\n",[741,2854,2855,2858,2860,2863,2865,2867,2869,2871],{"class":743,"line":773},[741,2856,2857],{"class":1013},"  defineDrain",[741,2859,1495],{"class":751},[741,2861,2862],{"class":825}," apiKey",[741,2864,829],{"class":751},[741,2866,1472],{"class":816},[741,2868,1512],{"class":751},[741,2870,1017],{"class":758},[741,2872,1055],{"class":751},[741,2874,2875,2877,2879,2881,2884,2886],{"class":743,"line":784},[741,2876,1061],{"class":825},[741,2878,829],{"class":751},[741,2880,793],{"class":751},[741,2882,2883],{"class":796},"custom",[741,2885,914],{"class":751},[741,2887,762],{"class":751},[741,2889,2890,2892,2894,2896,2898,2900,2902,2904,2906,2908,2910,2912,2914,2916,2919,2921,2923,2925],{"class":743,"line":802},[741,2891,1078],{"class":1013},[741,2893,829],{"class":751},[741,2895,1083],{"class":812},[741,2897,1086],{"class":751},[741,2899,1089],{"class":812},[741,2901,1144],{"class":758},[741,2903,2267],{"class":751},[741,2905,2862],{"class":825},[741,2907,829],{"class":751},[741,2909,1565],{"class":758},[741,2911,1153],{"class":751},[741,2913,1570],{"class":758},[741,2915,1153],{"class":751},[741,2917,2918],{"class":758},"MY_KEY",[741,2920,1147],{"class":751},[741,2922,1435],{"class":751},[741,2924,1237],{"class":758},[741,2926,762],{"class":751},[741,2928,2929,2932,2934,2936,2938,2940,2942,2944,2946,2948],{"class":743,"line":809},[741,2930,2931],{"class":1013},"    send",[741,2933,829],{"class":751},[741,2935,1083],{"class":812},[741,2937,1144],{"class":751},[741,2939,1230],{"class":1020},[741,2941,917],{"class":751},[741,2943,1100],{"class":1020},[741,2945,1237],{"class":751},[741,2947,1089],{"class":812},[741,2949,752],{"class":751},[741,2951,2952,2955,2958,2960,2963,2965,2967,2969,2971,2973,2975,2977,2979,2981,2983],{"class":743,"line":822},[741,2953,2954],{"class":747},"      await",[741,2956,2957],{"class":758}," myVendorSdk",[741,2959,1153],{"class":751},[741,2961,2962],{"class":1013},"publish",[741,2964,1017],{"class":825},[741,2966,1230],{"class":758},[741,2968,917],{"class":751},[741,2970,1430],{"class":751},[741,2972,1477],{"class":825},[741,2974,829],{"class":751},[741,2976,1100],{"class":758},[741,2978,1153],{"class":751},[741,2980,644],{"class":758},[741,2982,1435],{"class":751},[741,2984,1135],{"class":825},[741,2986,2987],{"class":743,"line":835},[741,2988,1217],{"class":751},[741,2990,2991,2993],{"class":743,"line":846},[741,2992,1386],{"class":751},[741,2994,1135],{"class":758},[512,2996,2997,2998,3000,3001,3003,3004,3007,3008,3011],{},"When you fall back to ",[554,2999,578],{},", follow the same rules manually that ",[554,3002,565],{}," enforces: wrap the transport in ",[554,3005,3006],{},"try\u002Fcatch",", log with ",[554,3009,3010],{},"console.error('[evlog\u002F\u003Cname>] …')",", and never re-throw.",[708,3013,3015],{"id":3014},"draincontext-reference","DrainContext reference",[512,3017,3018,3019,3021,3022,3025],{},"When evlog calls your drain through ",[554,3020,2082],{},", it passes a ",[554,3023,3024],{},"DrainContext"," per event:",[731,3027,3030],{"className":733,"code":3028,"filename":3029,"language":736,"meta":737,"style":737},"interface DrainContext {\n  \u002F** The complete wide event with all accumulated context *\u002F\n  event: WideEvent\n\n  \u002F** Request metadata *\u002F\n  request?: {\n    method: string\n    path: string\n    requestId: string\n  }\n\n  \u002F** Safe HTTP headers (sensitive headers filtered) *\u002F\n  headers?: Record\u003Cstring, string>\n}\n\ninterface WideEvent {\n  timestamp: string\n  level: 'debug' | 'info' | 'warn' | 'error'\n  service: string\n  environment?: string\n  version?: string\n  region?: string\n  commitHash?: string\n  requestId?: string\n  \u002F\u002F ... plus all fields added via log.set()\n  [key: string]: unknown\n}\n","types.ts",[554,3031,3032,3041,3046,3056,3060,3065,3074,3083,3092,3101,3105,3109,3114,3136,3140,3144,3153,3162,3203,3211,3220,3229,3238,3247,3256,3261,3281],{"__ignoreMap":737},[741,3033,3034,3036,3039],{"class":743,"line":744},[741,3035,813],{"class":812},[741,3037,3038],{"class":816}," DrainContext",[741,3040,752],{"class":751},[741,3042,3043],{"class":743,"line":755},[741,3044,3045],{"class":1995},"  \u002F** The complete wide event with all accumulated context *\u002F\n",[741,3047,3048,3051,3053],{"class":743,"line":765},[741,3049,3050],{"class":825},"  event",[741,3052,829],{"class":751},[741,3054,3055],{"class":816}," WideEvent\n",[741,3057,3058],{"class":743,"line":773},[741,3059,806],{"emptyLinePlaceholder":805},[741,3061,3062],{"class":743,"line":784},[741,3063,3064],{"class":1995},"  \u002F** Request metadata *\u002F\n",[741,3066,3067,3070,3072],{"class":743,"line":802},[741,3068,3069],{"class":825},"  request",[741,3071,841],{"class":751},[741,3073,752],{"class":751},[741,3075,3076,3079,3081],{"class":743,"line":809},[741,3077,3078],{"class":825},"    method",[741,3080,829],{"class":751},[741,3082,832],{"class":816},[741,3084,3085,3088,3090],{"class":743,"line":822},[741,3086,3087],{"class":825},"    path",[741,3089,829],{"class":751},[741,3091,832],{"class":816},[741,3093,3094,3097,3099],{"class":743,"line":835},[741,3095,3096],{"class":825},"    requestId",[741,3098,829],{"class":751},[741,3100,832],{"class":816},[741,3102,3103],{"class":743,"line":846},[741,3104,2792],{"class":751},[741,3106,3107],{"class":743,"line":857},[741,3108,806],{"emptyLinePlaceholder":805},[741,3110,3111],{"class":743,"line":863},[741,3112,3113],{"class":1995},"  \u002F** Safe HTTP headers (sensitive headers filtered) *\u002F\n",[741,3115,3116,3119,3121,3124,3126,3129,3131,3133],{"class":743,"line":868},[741,3117,3118],{"class":825},"  headers",[741,3120,841],{"class":751},[741,3122,3123],{"class":816}," Record",[741,3125,881],{"class":751},[741,3127,3128],{"class":816},"string",[741,3130,917],{"class":751},[741,3132,1472],{"class":816},[741,3134,3135],{"class":751},">\n",[741,3137,3138],{"class":743,"line":899},[741,3139,860],{"class":751},[741,3141,3142],{"class":743,"line":941},[741,3143,806],{"emptyLinePlaceholder":805},[741,3145,3146,3148,3151],{"class":743,"line":975},[741,3147,813],{"class":812},[741,3149,3150],{"class":816}," WideEvent",[741,3152,752],{"class":751},[741,3154,3155,3158,3160],{"class":743,"line":993},[741,3156,3157],{"class":825},"  timestamp",[741,3159,829],{"class":751},[741,3161,832],{"class":816},[741,3163,3164,3167,3169,3171,3174,3176,3179,3181,3184,3186,3188,3190,3193,3195,3197,3199,3201],{"class":743,"line":999},[741,3165,3166],{"class":825},"  level",[741,3168,829],{"class":751},[741,3170,793],{"class":751},[741,3172,3173],{"class":796},"debug",[741,3175,914],{"class":751},[741,3177,3178],{"class":751}," |",[741,3180,793],{"class":751},[741,3182,3183],{"class":796},"info",[741,3185,914],{"class":751},[741,3187,3178],{"class":751},[741,3189,793],{"class":751},[741,3191,3192],{"class":796},"warn",[741,3194,914],{"class":751},[741,3196,3178],{"class":751},[741,3198,793],{"class":751},[741,3200,1171],{"class":796},[741,3202,799],{"class":751},[741,3204,3205,3207,3209],{"class":743,"line":1004},[741,3206,2192],{"class":825},[741,3208,829],{"class":751},[741,3210,832],{"class":816},[741,3212,3213,3216,3218],{"class":743,"line":1038},[741,3214,3215],{"class":825},"  environment",[741,3217,841],{"class":751},[741,3219,832],{"class":816},[741,3221,3222,3225,3227],{"class":743,"line":1058},[741,3223,3224],{"class":825},"  version",[741,3226,841],{"class":751},[741,3228,832],{"class":816},[741,3230,3231,3234,3236],{"class":743,"line":1075},[741,3232,3233],{"class":825},"  region",[741,3235,841],{"class":751},[741,3237,832],{"class":816},[741,3239,3240,3243,3245],{"class":743,"line":1094},[741,3241,3242],{"class":825},"  commitHash",[741,3244,841],{"class":751},[741,3246,832],{"class":816},[741,3248,3249,3252,3254],{"class":743,"line":1138},[741,3250,3251],{"class":825},"  requestId",[741,3253,841],{"class":751},[741,3255,832],{"class":816},[741,3257,3258],{"class":743,"line":1163},[741,3259,3260],{"class":1995},"  \u002F\u002F ... plus all fields added via log.set()\n",[741,3262,3263,3266,3269,3271,3273,3276,3278],{"class":743,"line":1185},[741,3264,3265],{"class":758},"  [",[741,3267,3268],{"class":1020},"key",[741,3270,829],{"class":751},[741,3272,1472],{"class":816},[741,3274,3275],{"class":758},"]",[741,3277,829],{"class":751},[741,3279,3280],{"class":816}," unknown\n",[741,3282,3283],{"class":743,"line":1194},[741,3284,860],{"class":751},[512,3286,3287,3288,3290,3291,3294,3295,3297,3298,3301],{},"In the batched form your ",[554,3289,725],{}," \u002F ",[554,3292,3293],{},"send()"," receives, you get ",[554,3296,2436],{}," directly (the toolkit unwraps ",[554,3299,3300],{},"event"," from each context).",[708,3303,3305],{"id":3304},"toolkit-helpers","Toolkit helpers",[512,3307,3308,3310],{},[554,3309,584],{}," exposes the same helpers every built-in adapter uses. The ones relevant to drains:",[529,3312,3313,3323],{},[532,3314,3315],{},[535,3316,3317,3320],{},[538,3318,3319],{},"Export",[538,3321,3322],{},"Purpose",[545,3324,3325,3335,3345,3357,3367,3380,3390,3404],{},[535,3326,3327,3332],{},[550,3328,3329],{},[554,3330,3331],{},"defineHttpDrain(spec)",[550,3333,3334],{},"The HTTP recipe — auto retries, timeouts, identity headers, error isolation",[535,3336,3337,3342],{},[550,3338,3339],{},[554,3340,3341],{},"defineDrain(spec)",[550,3343,3344],{},"Same contract for non-HTTP transports",[535,3346,3347,3352],{},[550,3348,3349],{},[554,3350,3351],{},"resolveAdapterConfig(ns, fields, overrides)",[550,3353,3354,3355,638],{},"Standard config priority chain (overrides → ",[554,3356,637],{},[535,3358,3359,3364],{},[550,3360,3361],{},[554,3362,3363],{},"httpPost(opts)",[550,3365,3366],{},"The retried POST helper used by every built-in HTTP adapter — handles timeout, retries, redacted error messages",[535,3368,3369,3374],{},[550,3370,3371],{},[554,3372,3373],{},"composeDrains(drains)",[550,3375,3376,3377,1237],{},"Combine multiple drains into one (errors isolated, runs concurrently with ",[554,3378,3379],{},"Promise.allSettled",[535,3381,3382,3387],{},[550,3383,3384],{},[554,3385,3386],{},"toTypedAttributeValue(value)",[550,3388,3389],{},"Convert any value to the typed attribute shape used by Axiom \u002F Sentry",[535,3391,3392,3397],{},[550,3393,3394],{},[554,3395,3396],{},"toOtlpAttributeValue(value)",[550,3398,3399,3400,3403],{},"Convert any value to the OTLP ",[554,3401,3402],{},"AnyValue"," shape (used by OTLP \u002F HyperDX \u002F PostHog logs)",[535,3405,3406,3414],{},[550,3407,3408,653,3411],{},[554,3409,3410],{},"OTEL_SEVERITY_NUMBER",[554,3412,3413],{},"OTEL_SEVERITY_TEXT",[550,3415,3416],{},"OTEL log severity tables",[708,3418,461],{"id":3419},"identity-headers",[512,3421,3422,3424],{},[554,3423,565],{}," automatically tags every request with two headers so receivers can identify the traffic:",[529,3426,3427,3437],{},[532,3428,3429],{},[535,3430,3431,3434],{},[538,3432,3433],{},"Header",[538,3435,3436],{},"Value",[545,3438,3439,3452],{},[535,3440,3441,3446],{},[550,3442,3443],{},[554,3444,3445],{},"User-Agent",[550,3447,3448,3451],{},[554,3449,3450],{},"evlog\u002F\u003Cversion>"," (Node \u002F server runtimes only — browsers strip this header)",[535,3453,3454,3459],{},[550,3455,3456],{},[554,3457,3458],{},"X-Evlog-Source",[550,3460,3461,3462,3465],{},"The drain ",[554,3463,3464],{},"name"," you provided",[512,3467,3468,3469,3472,3473,1153],{},"If you build a drain on top of ",[554,3470,3471],{},"httpPost"," directly, you can override or suppress them — see ",[521,3474,461],{"href":462},[708,3476,3478],{"id":3477},"error-handling-already-done-for-you","Error handling — already done for you",[512,3480,3481,3483],{},[554,3482,565],{}," enforces every best practice automatically:",[1901,3485,3486,3496,3506,3514],{},[599,3487,3488,3491,3492,3495],{},[516,3489,3490],{},"Never throws"," — failures are caught and logged with the ",[554,3493,3494],{},"[evlog\u002F\u003Cname>]"," prefix.",[599,3497,3498,3501,3502,3505],{},[516,3499,3500],{},"Retries"," — defaults to 2 attempts on transient errors (configurable via ",[554,3503,3504],{},"retries",").",[599,3507,3508,3511,3512,3505],{},[516,3509,3510],{},"Timeouts"," — defaults to 5000ms (configurable via ",[554,3513,656],{},[599,3515,3516,3519,3520,3522,3523,3525],{},[516,3517,3518],{},"Graceful degradation"," — ",[554,3521,629],{}," returning ",[554,3524,670],{}," makes the drain a no-op.",[512,3527,3528,3529,3531],{},"If you fall back to ",[554,3530,578],{},", follow the same rules manually.",[708,3533,3535],{"id":3534},"publishing-as-a-community-package","Publishing as a community package",[512,3537,3538],{},"Recommended structure for a community drain:",[731,3540,3545],{"className":3541,"code":3543,"language":3544,"meta":737},[3542],"language-text","my-evlog-drain\u002F\n├─ src\u002F\n│  ├─ drain.ts        # createMyDrain via defineHttpDrain\n│  └─ index.ts        # re-exports\n├─ test\u002F              # vitest, mock fetch\n├─ package.json       # peerDependency: \"evlog\"\n└─ README.md\n","text",[554,3546,3543],{"__ignoreMap":737},[512,3548,3549,3550,3552,3553,3556,3557,3560],{},"Add ",[554,3551,2262],{}," as a ",[554,3554,3555],{},"peerDependency"," (not a ",[554,3558,3559],{},"dependency",") — your package shouldn't pull in a copy of evlog at install time.",[3562,3563,3566,3567,3572],"callout",{"color":3564,"icon":3565},"neutral","i-lucide-heart","Built something great? ",[521,3568,3571],{"href":3569,"rel":3570},"https:\u002F\u002Fgithub.com\u002Fhugorcd\u002Fevlog\u002Fpulls",[701],"Open a PR"," to add a row to the Adapters table — the community will thank you.",[708,3574,3576],{"id":3575},"next-steps","Next steps",[596,3578,3579,3585,3593,3599,3605],{},[599,3580,3581,3584],{},[521,3582,3583],{"href":472},"Drain Pipeline"," — wrap your drain in batch + retry + fanout for production",[599,3586,3587,3590,3591],{},[521,3588,3589],{"href":138},"Adapters Overview"," — see how the built-in adapters use ",[554,3592,565],{},[599,3594,3595,3598],{},[521,3596,3597],{"href":454},"Custom Enrichers"," — same toolkit shape for derived event fields",[599,3600,3601,3604],{},[521,3602,3603],{"href":436},"Custom Framework Integration"," — same toolkit shape for HTTP frameworks",[599,3606,3607,3609],{},[521,3608,493],{"href":494}," — security and production tips",[3611,3612,3613],"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 .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 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 .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}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}",{"title":737,"searchDepth":755,"depth":755,"links":3615},[3616,3620,3621,3622,3623,3625,3626,3627,3628,3629,3630],{"id":710,"depth":755,"text":3617,"children":3618},"defineHttpDrain (the HTTP recipe)",[3619],{"id":1411,"depth":765,"text":1412},{"id":1893,"depth":755,"text":1894},{"id":1973,"depth":755,"text":1974},{"id":2427,"depth":755,"text":2428},{"id":2799,"depth":755,"text":3624},"defineDrain (non-HTTP transports)",{"id":3014,"depth":755,"text":3015},{"id":3304,"depth":755,"text":3305},{"id":3419,"depth":755,"text":461},{"id":3477,"depth":755,"text":3478},{"id":3534,"depth":755,"text":3535},{"id":3575,"depth":755,"text":3576},"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.","md",[3634,3636,3638],{"label":3583,"icon":474,"to":472,"color":3564,"variant":3635},"subtle",{"label":3589,"icon":3637,"to":138,"color":3564,"variant":3635},"i-custom-plug",{"label":493,"icon":359,"to":494,"color":3564,"variant":3635},{},{"title":466,"icon":469},{"title":507,"description":3631},"uCmp0ogWAKmIRL4AQNUhlp9bvOT-kc-JJsFP-mZ-pns",[3644,3646],{"title":461,"path":462,"stem":463,"description":3645,"icon":464,"children":-1},"Every drain request sent by evlog is tagged with User-Agent and X-Evlog-Source headers so receivers can identify and triage the traffic. Override or suppress them when your custom drain needs different identity.",{"title":471,"path":472,"stem":473,"description":3647,"icon":474,"children":-1},"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.",1785224909883]