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