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