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