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