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