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