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