[{"data":1,"prerenderedAt":3058},["ShallowReactive",2],{"navigation_docs":3,"-extend-custom-framework":510,"-extend-custom-framework-surround":3053},[4,30,80,123,293,425,480],{"title":5,"path":6,"stem":7,"children":8,"page":29},"Start","\u002Fstart","1.start",[9,14,19,24],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","\u002Fstart\u002Fintroduction","1.start\u002F1.introduction","i-lucide-info",{"title":15,"path":16,"stem":17,"icon":18},"Why start with evlog","\u002Fstart\u002Fwhy-evlog","1.start\u002F2.why-evlog","i-lucide-rocket",{"title":20,"path":21,"stem":22,"icon":23},"Installation","\u002Fstart\u002Finstallation","1.start\u002F3.installation","i-lucide-download",{"title":25,"path":26,"stem":27,"icon":28},"Quick Start","\u002Fstart\u002Fquick-start","1.start\u002F4.quick-start","i-lucide-zap",false,{"title":31,"path":32,"stem":33,"children":34,"page":29},"Learn","\u002Flearn","2.learn",[35,40,45,50,55,60,65,70,75],{"title":36,"path":37,"stem":38,"icon":39},"Overview","\u002Flearn\u002Foverview","2.learn\u002F0.overview","i-lucide-list",{"title":41,"path":42,"stem":43,"icon":44},"Simple Logging","\u002Flearn\u002Fsimple-logging","2.learn\u002F1.simple-logging","i-lucide-terminal",{"title":46,"path":47,"stem":48,"icon":49},"Wide Events","\u002Flearn\u002Fwide-events","2.learn\u002F2.wide-events","i-lucide-layers",{"title":51,"path":52,"stem":53,"icon":54},"Structured Errors","\u002Flearn\u002Fstructured-errors","2.learn\u002F3.structured-errors","i-lucide-shield-alert",{"title":56,"path":57,"stem":58,"icon":59},"Lifecycle","\u002Flearn\u002Flifecycle","2.learn\u002F4.lifecycle","i-lucide-arrow-right-left",{"title":61,"path":62,"stem":63,"icon":64},"Sampling","\u002Flearn\u002Fsampling","2.learn\u002F5.sampling","i-lucide-filter",{"title":66,"path":67,"stem":68,"icon":69},"Auto-Redaction","\u002Flearn\u002Fredaction","2.learn\u002F6.redaction","i-lucide-eye-off",{"title":71,"path":72,"stem":73,"icon":74},"Typed Fields","\u002Flearn\u002Ftyped-fields","2.learn\u002F7.typed-fields","i-simple-icons-typescript",{"title":76,"path":77,"stem":78,"icon":79},"Catalogs","\u002Flearn\u002Fcatalogs","2.learn\u002F8.catalogs","i-lucide-book-open",{"title":81,"path":82,"stem":83,"children":84,"page":29},"CLI","\u002Fcli","3.cli",[85,88,93,98,103,108,113,118],{"title":36,"path":86,"stem":87,"icon":44},"\u002Fcli\u002Foverview","3.cli\u002F0.overview",{"title":89,"path":90,"stem":91,"icon":92},"init","\u002Fcli\u002Finit","3.cli\u002F1.init","i-lucide-wand-sparkles",{"title":94,"path":95,"stem":96,"icon":97},"map","\u002Fcli\u002Fmap","3.cli\u002F2.map","i-lucide-radar",{"title":99,"path":100,"stem":101,"icon":102},"Rules","\u002Fcli\u002Frules","3.cli\u002F3.rules","i-lucide-list-checks",{"title":104,"path":105,"stem":106,"icon":107},"Scoring","\u002Fcli\u002Fscoring","3.cli\u002F4.scoring","i-lucide-gauge",{"title":109,"path":110,"stem":111,"icon":112},"CI","\u002Fcli\u002Fci","3.cli\u002F5.ci","i-lucide-git-pull-request",{"title":114,"path":115,"stem":116,"icon":117},"doctor","\u002Fcli\u002Fdoctor","3.cli\u002F6.doctor","i-lucide-stethoscope",{"title":119,"path":120,"stem":121,"icon":122},"telemetry","\u002Fcli\u002Ftelemetry","3.cli\u002F7.telemetry","i-lucide-bar-chart-3",{"title":124,"path":125,"stem":126,"children":127,"page":29},"Integrate","\u002Fintegrate","4.integrate",[128,132,205],{"title":36,"path":129,"stem":130,"icon":131},"\u002Fintegrate\u002Foverview","4.integrate\u002F0.overview","i-lucide-plug",{"title":133,"path":134,"stem":135,"children":136,"page":29},"Adapters","\u002Fintegrate\u002Fadapters","4.integrate\u002Fadapters",[137,140,180],{"title":36,"path":138,"stem":139,"icon":39},"\u002Fintegrate\u002Fadapters\u002Foverview","4.integrate\u002Fadapters\u002F01.overview",{"title":141,"path":142,"stem":143,"children":144,"page":29},"Cloud","\u002Fintegrate\u002Fadapters\u002Fcloud","4.integrate\u002Fadapters\u002Fcloud",[145,150,155,160,165,170,175],{"title":146,"path":147,"stem":148,"icon":149},"Axiom","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Faxiom","4.integrate\u002Fadapters\u002Fcloud\u002F01.axiom","i-custom-axiom",{"title":151,"path":152,"stem":153,"icon":154},"OTLP","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fotlp","4.integrate\u002Fadapters\u002Fcloud\u002F02.otlp","i-simple-icons-opentelemetry",{"title":156,"path":157,"stem":158,"icon":159},"PostHog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fposthog","4.integrate\u002Fadapters\u002Fcloud\u002F03.posthog","i-simple-icons-posthog",{"title":161,"path":162,"stem":163,"icon":164},"Sentry","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fsentry","4.integrate\u002Fadapters\u002Fcloud\u002F04.sentry","i-simple-icons-sentry",{"title":166,"path":167,"stem":168,"icon":169},"Better Stack","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fbetter-stack","4.integrate\u002Fadapters\u002Fcloud\u002F05.better-stack","i-simple-icons-betterstack",{"title":171,"path":172,"stem":173,"icon":174},"Datadog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fdatadog","4.integrate\u002Fadapters\u002Fcloud\u002F06.datadog","i-simple-icons-datadog",{"title":176,"path":177,"stem":178,"icon":179},"HyperDX","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fhyperdx","4.integrate\u002Fadapters\u002Fcloud\u002F07.hyperdx","i-custom-hyperdx",{"title":181,"path":182,"stem":183,"children":184,"page":29},"Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fself-hosted","4.integrate\u002Fadapters\u002Fself-hosted",[185,190,195,200],{"title":186,"path":187,"stem":188,"icon":189},"File System","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Ffs","4.integrate\u002Fadapters\u002Fself-hosted\u002F01.fs","i-lucide-hard-drive",{"title":191,"path":192,"stem":193,"icon":194},"NuxtHub","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fnuxthub","4.integrate\u002Fadapters\u002Fself-hosted\u002F02.nuxthub","i-simple-icons-nuxt",{"title":196,"path":197,"stem":198,"icon":199},"Memory","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fmemory","4.integrate\u002Fadapters\u002Fself-hosted\u002F03.memory","i-lucide-cpu",{"title":201,"path":202,"stem":203,"icon":204},"Grafana Loki","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Floki","4.integrate\u002Fadapters\u002Fself-hosted\u002F04.loki","i-simple-icons-grafana",{"title":206,"path":207,"stem":208,"children":209,"page":29},"Frameworks","\u002Fintegrate\u002Fframeworks","4.integrate\u002Fframeworks",[210,214,219,224,229,234,239,244,249,254,259,264,269,274,278,283,288],{"title":36,"path":211,"stem":212,"icon":213},"\u002Fintegrate\u002Fframeworks\u002Foverview","4.integrate\u002Fframeworks\u002F00.overview","i-lucide-layout-grid",{"title":215,"path":216,"stem":217,"icon":218},"Nuxt","\u002Fintegrate\u002Fframeworks\u002Fnuxt","4.integrate\u002Fframeworks\u002F01.nuxt","i-simple-icons-nuxtdotjs",{"title":220,"path":221,"stem":222,"icon":223},"Next.js","\u002Fintegrate\u002Fframeworks\u002Fnextjs","4.integrate\u002Fframeworks\u002F02.nextjs","i-simple-icons-nextdotjs",{"title":225,"path":226,"stem":227,"icon":228},"SvelteKit","\u002Fintegrate\u002Fframeworks\u002Fsveltekit","4.integrate\u002Fframeworks\u002F03.sveltekit","i-simple-icons-svelte",{"title":230,"path":231,"stem":232,"icon":233},"Nitro","\u002Fintegrate\u002Fframeworks\u002Fnitro","4.integrate\u002Fframeworks\u002F04.nitro","i-custom-nitro",{"title":235,"path":236,"stem":237,"icon":238},"TanStack Start","\u002Fintegrate\u002Fframeworks\u002Ftanstack-start","4.integrate\u002Fframeworks\u002F05.tanstack-start","i-custom-tanstack",{"title":240,"path":241,"stem":242,"icon":243},"NestJS","\u002Fintegrate\u002Fframeworks\u002Fnestjs","4.integrate\u002Fframeworks\u002F06.nestjs","i-simple-icons-nestjs",{"title":245,"path":246,"stem":247,"icon":248},"Express","\u002Fintegrate\u002Fframeworks\u002Fexpress","4.integrate\u002Fframeworks\u002F07.express","i-simple-icons-express",{"title":250,"path":251,"stem":252,"icon":253},"Hono","\u002Fintegrate\u002Fframeworks\u002Fhono","4.integrate\u002Fframeworks\u002F08.hono","i-simple-icons-hono",{"title":255,"path":256,"stem":257,"icon":258},"Fastify","\u002Fintegrate\u002Fframeworks\u002Ffastify","4.integrate\u002Fframeworks\u002F09.fastify","i-simple-icons-fastify",{"title":260,"path":261,"stem":262,"icon":263},"Elysia","\u002Fintegrate\u002Fframeworks\u002Felysia","4.integrate\u002Fframeworks\u002F10.elysia","i-custom-elysia",{"title":265,"path":266,"stem":267,"icon":268},"React Router","\u002Fintegrate\u002Fframeworks\u002Freact-router","4.integrate\u002Fframeworks\u002F11.react-router","i-custom-reactrouter",{"title":270,"path":271,"stem":272,"icon":273},"Cloudflare Workers","\u002Fintegrate\u002Fframeworks\u002Fcloudflare-workers","4.integrate\u002Fframeworks\u002F12.cloudflare-workers","i-simple-icons-cloudflare",{"title":275,"path":276,"stem":277,"icon":74},"Standalone","\u002Fintegrate\u002Fframeworks\u002Fstandalone","4.integrate\u002Fframeworks\u002F13.standalone",{"title":279,"path":280,"stem":281,"icon":282},"Astro","\u002Fintegrate\u002Fframeworks\u002Fastro","4.integrate\u002Fframeworks\u002F14.astro","i-simple-icons-astro",{"title":284,"path":285,"stem":286,"icon":287},"oRPC","\u002Fintegrate\u002Fframeworks\u002Forpc","4.integrate\u002Fframeworks\u002F15.orpc","i-lucide-network",{"title":289,"path":290,"stem":291,"icon":292},"AWS Lambda","\u002Fintegrate\u002Fframeworks\u002Faws-lambda","4.integrate\u002Fframeworks\u002F16.aws-lambda","i-custom-lambda",{"title":294,"path":295,"stem":296,"children":297,"page":29},"Use Cases","\u002Fuse-cases","5.use-cases",[298,301,306,335,362,394,415,420],{"title":36,"path":299,"stem":300,"icon":102},"\u002Fuse-cases\u002Foverview","5.use-cases\u002F0.overview",{"title":302,"path":303,"stem":304,"icon":305},"Client Logging","\u002Fuse-cases\u002Fclient-logging","5.use-cases\u002F1.client-logging","i-lucide-monitor",{"title":307,"icon":308,"path":309,"stem":310,"children":311,"page":29},"AI SDK","i-simple-icons-vercel","\u002Fuse-cases\u002Fai-sdk","5.use-cases\u002F2.ai-sdk",[312,315,320,325,330],{"title":36,"path":313,"stem":314,"icon":39},"\u002Fuse-cases\u002Fai-sdk\u002Foverview","5.use-cases\u002F2.ai-sdk\u002F01.overview",{"title":316,"path":317,"stem":318,"icon":319},"Usage","\u002Fuse-cases\u002Fai-sdk\u002Fusage","5.use-cases\u002F2.ai-sdk\u002F02.usage","i-lucide-code",{"title":321,"path":322,"stem":323,"icon":324},"Options","\u002Fuse-cases\u002Fai-sdk\u002Foptions","5.use-cases\u002F2.ai-sdk\u002F03.options","i-lucide-sliders",{"title":326,"path":327,"stem":328,"icon":329},"Metadata","\u002Fuse-cases\u002Fai-sdk\u002Fmetadata","5.use-cases\u002F2.ai-sdk\u002F04.metadata","i-lucide-database",{"title":331,"path":332,"stem":333,"icon":334},"Telemetry","\u002Fuse-cases\u002Fai-sdk\u002Ftelemetry","5.use-cases\u002F2.ai-sdk\u002F05.telemetry","i-lucide-activity",{"title":336,"icon":337,"path":338,"stem":339,"children":340,"page":29},"Better Auth","i-simple-icons-betterauth","\u002Fuse-cases\u002Fbetter-auth","5.use-cases\u002F3.better-auth",[341,344,349,354,358],{"title":36,"path":342,"stem":343,"icon":39},"\u002Fuse-cases\u002Fbetter-auth\u002Foverview","5.use-cases\u002F3.better-auth\u002F01.overview",{"title":345,"path":346,"stem":347,"icon":348},"Identify User","\u002Fuse-cases\u002Fbetter-auth\u002Fidentify-user","5.use-cases\u002F3.better-auth\u002F02.identify-user","i-lucide-user-check",{"title":350,"path":351,"stem":352,"icon":353},"Middleware","\u002Fuse-cases\u002Fbetter-auth\u002Fmiddleware","5.use-cases\u002F3.better-auth\u002F03.middleware","i-lucide-shield",{"title":355,"path":356,"stem":357,"icon":305},"Client Sync","\u002Fuse-cases\u002Fbetter-auth\u002Fclient-sync","5.use-cases\u002F3.better-auth\u002F04.client-sync",{"title":359,"path":360,"stem":361,"icon":107},"Performance","\u002Fuse-cases\u002Fbetter-auth\u002Fperformance","5.use-cases\u002F3.better-auth\u002F05.performance",{"title":363,"icon":364,"path":365,"stem":366,"children":367,"page":29},"Audit Logs","i-lucide-shield-check","\u002Fuse-cases\u002Faudit","5.use-cases\u002F4.audit",[368,371,376,381,386,390],{"title":36,"path":369,"stem":370,"icon":39},"\u002Fuse-cases\u002Faudit\u002Foverview","5.use-cases\u002F4.audit\u002F01.overview",{"title":372,"path":373,"stem":374,"icon":375},"Schema","\u002Fuse-cases\u002Faudit\u002Fschema","5.use-cases\u002F4.audit\u002F02.schema","i-lucide-file-text",{"title":377,"path":378,"stem":379,"icon":380},"Recording","\u002Fuse-cases\u002Faudit\u002Frecording","5.use-cases\u002F4.audit\u002F03.recording","i-lucide-pen-line",{"title":382,"path":383,"stem":384,"icon":385},"Drains","\u002Fuse-cases\u002Faudit\u002Fpipeline","5.use-cases\u002F4.audit\u002F04.pipeline","i-lucide-link",{"title":387,"path":388,"stem":389,"icon":364},"Compliance","\u002Fuse-cases\u002Faudit\u002Fcompliance","5.use-cases\u002F4.audit\u002F05.compliance",{"title":391,"path":392,"stem":393,"icon":79},"Recipes","\u002Fuse-cases\u002Faudit\u002Frecipes","5.use-cases\u002F4.audit\u002F06.recipes",{"title":331,"icon":107,"path":395,"stem":396,"children":397,"page":29},"\u002Fuse-cases\u002Ftelemetry","5.use-cases\u002F4.telemetry",[398,401,406,411],{"title":36,"path":399,"stem":400,"icon":39},"\u002Fuse-cases\u002Ftelemetry\u002Foverview","5.use-cases\u002F4.telemetry\u002F01.overview",{"title":402,"path":403,"stem":404,"icon":405},"Setup","\u002Fuse-cases\u002Ftelemetry\u002Fsetup","5.use-cases\u002F4.telemetry\u002F02.setup","i-lucide-wrench",{"title":407,"path":408,"stem":409,"icon":410},"Ingest","\u002Fuse-cases\u002Ftelemetry\u002Fingest","5.use-cases\u002F4.telemetry\u002F03.ingest","i-lucide-server",{"title":412,"path":413,"stem":414,"icon":79},"Reference","\u002Fuse-cases\u002Ftelemetry\u002Freference","5.use-cases\u002F4.telemetry\u002F04.reference",{"title":416,"path":417,"stem":418,"icon":419},"Enrichers","\u002Fuse-cases\u002Fenrichers","5.use-cases\u002F5.enrichers","i-lucide-sparkles",{"title":421,"path":422,"stem":423,"icon":424},"eve","\u002Fuse-cases\u002Feve","5.use-cases\u002F5.eve","i-custom-eve",{"title":426,"path":427,"stem":428,"children":429,"page":29},"Extend","\u002Fextend","6.extend",[430,434,439,444,449,453,457,461,465,470,475],{"title":36,"path":431,"stem":432,"icon":433},"\u002Fextend\u002Foverview","6.extend\u002F0.overview","i-lucide-blocks",{"title":435,"path":436,"stem":437,"icon":438},"Stream","\u002Fextend\u002Fstream","6.extend\u002F1.stream","i-lucide-radio-tower",{"title":440,"path":441,"stem":442,"icon":443},"Custom framework","\u002Fextend\u002Fcustom-framework","6.extend\u002F10.custom-framework","i-lucide-puzzle",{"title":445,"path":446,"stem":447,"icon":448},"FS reader","\u002Fextend\u002Ffs-reader","6.extend\u002F2.fs-reader","i-lucide-folder-search",{"title":391,"path":450,"stem":451,"icon":452},"\u002Fextend\u002Fconsumer-recipes","6.extend\u002F3.consumer-recipes","i-lucide-chef-hat",{"title":454,"path":455,"stem":456,"icon":433},"Plugins","\u002Fextend\u002Fplugins","6.extend\u002F4.plugins",{"title":458,"path":459,"stem":460,"icon":419},"Custom enrichers","\u002Fextend\u002Fcustom-enrichers","6.extend\u002F5.custom-enrichers",{"title":462,"path":463,"stem":464,"icon":64},"Tail sampling","\u002Fextend\u002Ftail-sampling","6.extend\u002F6.tail-sampling",{"title":466,"path":467,"stem":468,"icon":469},"Identity headers","\u002Fextend\u002Fidentity-headers","6.extend\u002F7.identity-headers","i-lucide-fingerprint",{"title":471,"path":472,"stem":473,"icon":474},"Custom drains","\u002Fextend\u002Fcustom-drains","6.extend\u002F8.custom-drains","i-lucide-share-2",{"title":476,"path":477,"stem":478,"icon":479},"Drain pipeline","\u002Fextend\u002Fdrain-pipeline","6.extend\u002F9.drain-pipeline","i-lucide-workflow",{"title":412,"path":481,"stem":482,"children":483,"page":29},"\u002Freference","7.reference",[484,489,492,497,501,506],{"title":485,"path":486,"stem":487,"icon":488},"Configuration","\u002Freference\u002Fconfiguration","7.reference\u002F1.configuration","i-lucide-settings",{"title":359,"path":490,"stem":491,"icon":107},"\u002Freference\u002Fperformance","7.reference\u002F2.performance",{"title":493,"path":494,"stem":495,"icon":496},"Vite Plugin","\u002Freference\u002Fvite-plugin","7.reference\u002F3.vite-plugin","i-custom-vite",{"title":498,"path":499,"stem":500,"icon":364},"Best Practices","\u002Freference\u002Fbest-practices","7.reference\u002F4.best-practices",{"title":502,"path":503,"stem":504,"icon":505},"vs Other Loggers","\u002Freference\u002Fvs-other-loggers","7.reference\u002F5.vs-other-loggers","i-lucide-scale",{"title":507,"path":508,"stem":509,"icon":419},"Agent Skills","\u002Freference\u002Fagent-skills","7.reference\u002F6.agent-skills",{"id":511,"title":512,"body":513,"description":3043,"extension":3044,"links":3045,"meta":3049,"navigation":3050,"path":441,"seo":3051,"stem":442,"__hash__":3052},"docs\u002F6.extend\u002F10.custom-framework.md","Custom Framework Integration",{"type":514,"value":515,"toc":3030},"minimark",[516,529,537,547,630,793,798,869,873,1089,1112,1116,1125,1950,1956,1964,1967,2027,2030,2034,2046,2156,2170,2174,2186,2194,2311,2326,2568,2578,2582,2589,2839,2846,2850,2853,2977,2988,2992,3026],[517,518,519,520,524,525,528],"p",{},"When the framework you use doesn't have an ",[521,522,523],"code",{},"evlog\u002F\u003Cframework>"," package yet, you build the integration yourself. ",[521,526,527],{},"evlog\u002Ftoolkit"," ships the same building blocks that power every built-in integration (Hono, Express, Fastify, Elysia, NestJS, SvelteKit) — you only write the framework-specific glue.",[517,530,531,532,536],{},"The mental model is always the same: ",[533,534,535],"strong",{},"request lifecycle → logger creation → enrich → drain",". The toolkit handles the request-context plumbing.",[538,539,542,543,546],"callout",{"color":540,"icon":541},"warning","i-lucide-flask-conical","The toolkit API is marked as ",[533,544,545],{},"beta",". The surface is stable (used by all built-in integrations) but may evolve based on community feedback.",[548,549,550,566],"table",{},[551,552,553],"thead",{},[554,555,556,560,563],"tr",{},[557,558,559],"th",{},"Surface",[557,561,562],{},"What it does",[557,564,565],{},"When to use",[567,568,569,591,614],"tbody",{},[554,570,571,581,584],{},[572,573,574],"td",{},[575,576,578],"a",{"href":577},"#manifest-mode-recommended",[521,579,580],{},"defineFrameworkIntegration()",[572,582,583],{},"Declaratively wire request extraction + logger attachment",[572,585,586,587,590],{},"HTTP frameworks with a ",[521,588,589],{},"(ctx, next)"," middleware shape (Hono, Express, Fastify, Elysia, NestJS-shaped)",[554,592,593,601,604],{},[572,594,595],{},[575,596,598],{"href":597},"#custom-mode",[521,599,600],{},"createMiddlewareLogger()",[572,602,603],{},"Imperative path: create the logger at request start, emit on response end",[572,605,606,607,609,610,613],{},"Frameworks whose lifecycle doesn't fit ",[521,608,589],{}," (NestJS interceptors, Next.js App Router, SvelteKit ",[521,611,612],{},"handle",")",[554,615,616,624,627],{},[572,617,618],{},[575,619,621],{"href":620},"#non-http-runtimes",[521,622,623],{},"createRequestLogger()",[572,625,626],{},"Wrap any unit of work in a logger lifecycle",[572,628,629],{},"Non-HTTP runtimes (queue workers, CLI, cron, durable workflows)",[631,632,635,638,785],"prompt",{":actions":633,"description":634,"icon":443},"[\"copy\",\"cursor\",\"claude\"]","Build an evlog integration for a custom framework",[517,636,637],{},"Wire evlog into an HTTP framework (or non-HTTP runtime) that doesn't have a built-in integration.",[639,640,641,675,689,699,713,728,739,765,776],"ul",{},[642,643,644,645,647,648,651,652,654,655,658,659,662,663,666,667,670,671,674],"li",{},"For HTTP frameworks with ",[521,646,589],{},", use ",[521,649,650],{},"defineFrameworkIntegration"," from ",[521,653,527],{}," — declare ",[521,656,657],{},"extractRequest(ctx)"," returning ",[521,660,661],{},"{ method, path, headers, requestId? }",", ",[521,664,665],{},"attachLogger(ctx, logger)",", and an optional storage from ",[521,668,669],{},"createLoggerStorage()"," (prefer ",[521,672,673],{},"evlog\u002Ftoolkit\u002Fstorage"," on Workers \u002F edge)",[642,676,677,678,681,682,685,686,688],{},"Headers may be either Web ",[521,679,680],{},"Headers"," or Node ",[521,683,684],{},"IncomingHttpHeaders"," — ",[521,687,650],{}," normalizes both",[642,690,691,692,695,696],{},"In your middleware, call ",[521,693,694],{},"integration.start(ctx, options)"," which returns ",[521,697,698],{},"{ skipped, finish, runWith, logger, middlewareOptions }",[642,700,701,702,705,706,709,710],{},"If ",[521,703,704],{},"skipped"," is ",[521,707,708],{},"true",", skip directly to ",[521,711,712],{},"next",[642,714,715,716,719,720,723,724,727],{},"Run downstream handlers inside ",[521,717,718],{},"runWith(() => next())"," so ",[521,721,722],{},"AsyncLocalStorage"," and ",[521,725,726],{},"log.fork()"," work",[642,729,730,731,734,735,738],{},"On success: ",[521,732,733],{},"await finish({ status })","; on error: ",[521,736,737],{},"await finish({ error })"," then re-throw",[642,740,741,742,662,745,662,748,662,751,662,754,662,757,760,761,764],{},"Expose ",[521,743,744],{},"drain",[521,746,747],{},"enrich",[521,749,750],{},"keep",[521,752,753],{},"include",[521,755,756],{},"exclude",[521,758,759],{},"routes",", and ",[521,762,763],{},"plugins"," options",[642,766,767,768,771,772,775],{},"On Cloudflare Workers \u002F Vercel Edge, pass ",[521,769,770],{},"waitUntil"," (or ",[521,773,774],{},"extractWaitUntil"," on the manifest) so async drains complete after the response",[642,777,778,779,651,782,784],{},"For non-HTTP runtimes (queue workers, CLI, cron), use ",[521,780,781],{},"createRequestLogger",[521,783,527],{}," directly — wrap each unit of work in a logger lifecycle",[517,786,787,788],{},"Docs: ",[575,789,790],{"href":790,"rel":791},"https:\u002F\u002Fwww.evlog.dev\u002Fextend\u002Fcustom-framework",[792],"nofollow",[794,795,797],"h2",{"id":796},"install","Install",[799,800,801,826,840,854],"code-group",{},[802,803,809],"pre",{"className":804,"code":805,"filename":806,"language":807,"meta":808,"style":808},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm add evlog\n","pnpm","bash","",[521,810,811],{"__ignoreMap":808},[812,813,816,819,823],"span",{"class":814,"line":815},"line",1,[812,817,806],{"class":818},"sBMFI",[812,820,822],{"class":821},"sfazB"," add",[812,824,825],{"class":821}," evlog\n",[802,827,830],{"className":804,"code":828,"filename":829,"language":807,"meta":808,"style":808},"bun add evlog\n","bun",[521,831,832],{"__ignoreMap":808},[812,833,834,836,838],{"class":814,"line":815},[812,835,829],{"class":818},[812,837,822],{"class":821},[812,839,825],{"class":821},[802,841,844],{"className":804,"code":842,"filename":843,"language":807,"meta":808,"style":808},"yarn add evlog\n","yarn",[521,845,846],{"__ignoreMap":808},[812,847,848,850,852],{"class":814,"line":815},[812,849,843],{"class":818},[812,851,822],{"class":821},[812,853,825],{"class":821},[802,855,858],{"className":804,"code":856,"filename":857,"language":807,"meta":808,"style":808},"npm install evlog\n","npm",[521,859,860],{"__ignoreMap":808},[812,861,862,864,867],{"class":814,"line":815},[812,863,857],{"class":818},[812,865,866],{"class":821}," install",[812,868,825],{"class":821},[794,870,872],{"id":871},"whats-in-the-toolkit","What's in the toolkit",[548,874,875,885],{},[551,876,877],{},[554,878,879,882],{},[557,880,881],{},"Export",[557,883,884],{},"Purpose",[567,886,887,897,907,921,931,955,968,981,993,1016,1034,1048,1079],{},[554,888,889,894],{},[572,890,891],{},[521,892,893],{},"defineFrameworkIntegration(spec)",[572,895,896],{},"Manifest factory — extract request, create logger, attach, run with ALS",[554,898,899,904],{},[572,900,901],{},[521,902,903],{},"createMiddlewareLogger(opts)",[572,905,906],{},"Lower-level lifecycle (custom mode)",[554,908,909,914],{},[572,910,911,913],{},[521,912,770],{}," on middleware options",[572,915,916,917,613],{},"Defer drain on Cloudflare Workers \u002F Vercel Edge (see ",[575,918,920],{"href":919},"#serverless-workers-edge","Serverless",[554,922,923,928],{},[572,924,925],{},[521,926,927],{},"createRequestLogger(opts)",[572,929,930],{},"Wrap a non-HTTP unit of work in a logger lifecycle",[554,932,933,938],{},[572,934,935],{},[521,936,937],{},"BaseEvlogOptions",[572,939,940,941,662,943,662,945,662,947,662,949,662,951,662,953],{},"Base user-facing options — ",[521,942,744],{},[521,944,747],{},[521,946,750],{},[521,948,753],{},[521,950,756],{},[521,952,759],{},[521,954,763],{},[554,956,957,962],{},[572,958,959],{},[521,960,961],{},"MiddlewareLoggerResult",[572,963,964,965],{},"Return type: ",[521,966,967],{},"{ logger, finish, skipped }",[554,969,970,975],{},[572,971,972],{},[521,973,974],{},"extractSafeHeaders(headers)",[572,976,977,978,980],{},"Filter sensitive headers from a Web API ",[521,979,680],{}," object",[554,982,983,988],{},[572,984,985],{},[521,986,987],{},"extractSafeNodeHeaders(headers)",[572,989,990,991],{},"Filter sensitive headers from Node.js ",[521,992,684],{},[554,994,995,1000],{},[572,996,997],{},[521,998,999],{},"createLoggerStorage(hint)",[572,1001,1002,1003,1006,1007,1009,1010,1012,1013,613],{},"Factory returning ",[521,1004,1005],{},"{ storage, useLogger }"," backed by ",[521,1008,722],{}," — also on ",[521,1011,673],{}," (prefer that entry on Workers \u002F edge to isolate ",[521,1014,1015],{},"node:async_hooks",[554,1017,1018,1023],{},[572,1019,1020],{},[521,1021,1022],{},"attachForkToLogger(storage, parent, opts)",[572,1024,1025,1026,1029,1030,1033],{},"Wires ",[521,1027,1028],{},"log.fork(label, fn)"," onto the request logger so consumers can spawn correlated background work — used by manifest mode automatically; call manually in custom mode after ",[521,1031,1032],{},"createMiddlewareLogger"," returns the logger and before the lifecycle finishes",[554,1035,1036,1041],{},[572,1037,1038],{},[521,1039,1040],{},"defineEvlog(config)",[572,1042,1043,1044,1047],{},"Canonical config object — works for ",[521,1045,1046],{},"initLogger"," and middleware options",[554,1049,1050,1055],{},[572,1051,1052],{},[521,1053,1054],{},"definePlugin(plugin)",[572,1056,1057,1058,662,1061,662,1063,662,1065,662,1067,662,1070,662,1073,662,1076],{},"Plugin contract — opt into any subset of ",[521,1059,1060],{},"setup",[521,1062,747],{},[521,1064,744],{},[521,1066,750],{},[521,1068,1069],{},"onRequestStart",[521,1071,1072],{},"onRequestFinish",[521,1074,1075],{},"onClientLog",[521,1077,1078],{},"extendLogger",[554,1080,1081,1086],{},[572,1082,1083],{},[521,1084,1085],{},"composeEnrichers \u002F composeDrains \u002F composeKeep \u002F composePlugins",[572,1087,1088],{},"Combine multiple extensions into one",[517,1090,1091,1092,662,1095,662,1098,662,1101,760,1104,1107,1108,1111],{},"Types like ",[521,1093,1094],{},"RequestLogger",[521,1096,1097],{},"DrainContext",[521,1099,1100],{},"EnrichContext",[521,1102,1103],{},"WideEvent",[521,1105,1106],{},"TailSamplingContext"," are exported from the main ",[521,1109,1110],{},"evlog"," package.",[794,1113,1115],{"id":1114},"manifest-mode-recommended","Manifest mode (recommended)",[517,1117,1118,1119,1121,1122,1124],{},"Most frameworks fit a ",[521,1120,589],{}," middleware shape. For those, write a manifest describing how to extract the request and attach the logger — ",[521,1123,650],{}," does the rest.",[1126,1127,1128],"code-collapse",{},[802,1129,1134],{"className":1130,"code":1131,"filename":1132,"language":1133,"meta":808,"style":808},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import type { IncomingMessage, ServerResponse } from 'node:http'\nimport {\n  createLoggerStorage,\n  defineFrameworkIntegration,\n  type BaseEvlogOptions,\n} from 'evlog\u002Ftoolkit'\n\u002F\u002F On Workers \u002F edge, prefer: import { createLoggerStorage } from 'evlog\u002Ftoolkit\u002Fstorage'\nimport type { RequestLogger } from 'evlog'\n\nexport type MyFrameworkEvlogOptions = BaseEvlogOptions\n\nconst { storage, useLogger } = createLoggerStorage(\n  'Cannot access logger outside of middleware context. Make sure evlog middleware is registered before your routes.',\n)\n\nexport { useLogger }\n\nconst integration = defineFrameworkIntegration\u003CIncomingMessage>({\n  name: 'my-framework',\n  extractRequest: (req) => ({\n    method: req.method || 'GET',\n    path: req.url || '\u002F',\n    headers: req.headers,\n    requestId: typeof req.headers['x-request-id'] === 'string'\n      ? req.headers['x-request-id']\n      : undefined,\n  }),\n  attachLogger: (req, logger) => {\n    (req as IncomingMessage & { log: RequestLogger }).log = logger\n  },\n  storage,\n})\n\nexport function evlog(options: MyFrameworkEvlogOptions = {}) {\n  return async (req: IncomingMessage, res: ServerResponse, next: () => Promise\u003Cvoid>) => {\n    const { skipped, finish, runWith } = integration.start(req, options)\n    if (skipped) {\n      await next()\n      return\n    }\n    try {\n      await runWith(() => next())\n      await finish({ status: res.statusCode })\n    } catch (error) {\n      await finish({ error: error as Error })\n      throw error\n    }\n  }\n}\n","my-framework-evlog.ts","typescript",[521,1135,1136,1174,1182,1191,1199,1210,1224,1231,1253,1260,1278,1283,1310,1324,1330,1335,1348,1353,1382,1401,1425,1454,1480,1497,1535,1556,1565,1575,1598,1637,1643,1651,1658,1663,1690,1743,1786,1801,1812,1818,1824,1832,1851,1879,1897,1924,1933,1938,1944],{"__ignoreMap":808},[812,1137,1138,1142,1145,1149,1153,1156,1159,1162,1165,1168,1171],{"class":814,"line":815},[812,1139,1141],{"class":1140},"s7zQu","import",[812,1143,1144],{"class":1140}," type",[812,1146,1148],{"class":1147},"sMK4o"," {",[812,1150,1152],{"class":1151},"sTEyZ"," IncomingMessage",[812,1154,1155],{"class":1147},",",[812,1157,1158],{"class":1151}," ServerResponse",[812,1160,1161],{"class":1147}," }",[812,1163,1164],{"class":1140}," from",[812,1166,1167],{"class":1147}," '",[812,1169,1170],{"class":821},"node:http",[812,1172,1173],{"class":1147},"'\n",[812,1175,1177,1179],{"class":814,"line":1176},2,[812,1178,1141],{"class":1140},[812,1180,1181],{"class":1147}," {\n",[812,1183,1185,1188],{"class":814,"line":1184},3,[812,1186,1187],{"class":1151},"  createLoggerStorage",[812,1189,1190],{"class":1147},",\n",[812,1192,1194,1197],{"class":814,"line":1193},4,[812,1195,1196],{"class":1151},"  defineFrameworkIntegration",[812,1198,1190],{"class":1147},[812,1200,1202,1205,1208],{"class":814,"line":1201},5,[812,1203,1204],{"class":1140},"  type",[812,1206,1207],{"class":1151}," BaseEvlogOptions",[812,1209,1190],{"class":1147},[812,1211,1213,1216,1218,1220,1222],{"class":814,"line":1212},6,[812,1214,1215],{"class":1147},"}",[812,1217,1164],{"class":1140},[812,1219,1167],{"class":1147},[812,1221,527],{"class":821},[812,1223,1173],{"class":1147},[812,1225,1227],{"class":814,"line":1226},7,[812,1228,1230],{"class":1229},"sHwdD","\u002F\u002F On Workers \u002F edge, prefer: import { createLoggerStorage } from 'evlog\u002Ftoolkit\u002Fstorage'\n",[812,1232,1234,1236,1238,1240,1243,1245,1247,1249,1251],{"class":814,"line":1233},8,[812,1235,1141],{"class":1140},[812,1237,1144],{"class":1140},[812,1239,1148],{"class":1147},[812,1241,1242],{"class":1151}," RequestLogger",[812,1244,1161],{"class":1147},[812,1246,1164],{"class":1140},[812,1248,1167],{"class":1147},[812,1250,1110],{"class":821},[812,1252,1173],{"class":1147},[812,1254,1256],{"class":814,"line":1255},9,[812,1257,1259],{"emptyLinePlaceholder":1258},true,"\n",[812,1261,1263,1266,1269,1272,1275],{"class":814,"line":1262},10,[812,1264,1265],{"class":1140},"export",[812,1267,1144],{"class":1268},"spNyl",[812,1270,1271],{"class":818}," MyFrameworkEvlogOptions",[812,1273,1274],{"class":1147}," =",[812,1276,1277],{"class":818}," BaseEvlogOptions\n",[812,1279,1281],{"class":814,"line":1280},11,[812,1282,1259],{"emptyLinePlaceholder":1258},[812,1284,1286,1289,1291,1294,1296,1299,1301,1303,1307],{"class":814,"line":1285},12,[812,1287,1288],{"class":1268},"const",[812,1290,1148],{"class":1147},[812,1292,1293],{"class":1151}," storage",[812,1295,1155],{"class":1147},[812,1297,1298],{"class":1151}," useLogger ",[812,1300,1215],{"class":1147},[812,1302,1274],{"class":1147},[812,1304,1306],{"class":1305},"s2Zo4"," createLoggerStorage",[812,1308,1309],{"class":1151},"(\n",[812,1311,1313,1316,1319,1322],{"class":814,"line":1312},13,[812,1314,1315],{"class":1147},"  '",[812,1317,1318],{"class":821},"Cannot access logger outside of middleware context. Make sure evlog middleware is registered before your routes.",[812,1320,1321],{"class":1147},"'",[812,1323,1190],{"class":1147},[812,1325,1327],{"class":814,"line":1326},14,[812,1328,1329],{"class":1151},")\n",[812,1331,1333],{"class":814,"line":1332},15,[812,1334,1259],{"emptyLinePlaceholder":1258},[812,1336,1338,1340,1342,1345],{"class":814,"line":1337},16,[812,1339,1265],{"class":1140},[812,1341,1148],{"class":1147},[812,1343,1344],{"class":1151}," useLogger",[812,1346,1347],{"class":1147}," }\n",[812,1349,1351],{"class":814,"line":1350},17,[812,1352,1259],{"emptyLinePlaceholder":1258},[812,1354,1356,1358,1361,1364,1367,1370,1373,1376,1379],{"class":814,"line":1355},18,[812,1357,1288],{"class":1268},[812,1359,1360],{"class":1151}," integration ",[812,1362,1363],{"class":1147},"=",[812,1365,1366],{"class":1305}," defineFrameworkIntegration",[812,1368,1369],{"class":1147},"\u003C",[812,1371,1372],{"class":818},"IncomingMessage",[812,1374,1375],{"class":1147},">",[812,1377,1378],{"class":1151},"(",[812,1380,1381],{"class":1147},"{\n",[812,1383,1385,1389,1392,1394,1397,1399],{"class":814,"line":1384},19,[812,1386,1388],{"class":1387},"swJcz","  name",[812,1390,1391],{"class":1147},":",[812,1393,1167],{"class":1147},[812,1395,1396],{"class":821},"my-framework",[812,1398,1321],{"class":1147},[812,1400,1190],{"class":1147},[812,1402,1404,1407,1409,1412,1416,1418,1421,1423],{"class":814,"line":1403},20,[812,1405,1406],{"class":1305},"  extractRequest",[812,1408,1391],{"class":1147},[812,1410,1411],{"class":1147}," (",[812,1413,1415],{"class":1414},"sHdIc","req",[812,1417,613],{"class":1147},[812,1419,1420],{"class":1268}," =>",[812,1422,1411],{"class":1151},[812,1424,1381],{"class":1147},[812,1426,1428,1431,1433,1436,1439,1442,1445,1447,1450,1452],{"class":814,"line":1427},21,[812,1429,1430],{"class":1387},"    method",[812,1432,1391],{"class":1147},[812,1434,1435],{"class":1151}," req",[812,1437,1438],{"class":1147},".",[812,1440,1441],{"class":1151},"method ",[812,1443,1444],{"class":1147},"||",[812,1446,1167],{"class":1147},[812,1448,1449],{"class":821},"GET",[812,1451,1321],{"class":1147},[812,1453,1190],{"class":1147},[812,1455,1457,1460,1462,1464,1466,1469,1471,1473,1476,1478],{"class":814,"line":1456},22,[812,1458,1459],{"class":1387},"    path",[812,1461,1391],{"class":1147},[812,1463,1435],{"class":1151},[812,1465,1438],{"class":1147},[812,1467,1468],{"class":1151},"url ",[812,1470,1444],{"class":1147},[812,1472,1167],{"class":1147},[812,1474,1475],{"class":821},"\u002F",[812,1477,1321],{"class":1147},[812,1479,1190],{"class":1147},[812,1481,1483,1486,1488,1490,1492,1495],{"class":814,"line":1482},23,[812,1484,1485],{"class":1387},"    headers",[812,1487,1391],{"class":1147},[812,1489,1435],{"class":1151},[812,1491,1438],{"class":1147},[812,1493,1494],{"class":1151},"headers",[812,1496,1190],{"class":1147},[812,1498,1500,1503,1505,1508,1510,1512,1515,1517,1520,1522,1525,1528,1530,1533],{"class":814,"line":1499},24,[812,1501,1502],{"class":1387},"    requestId",[812,1504,1391],{"class":1147},[812,1506,1507],{"class":1147}," typeof",[812,1509,1435],{"class":1151},[812,1511,1438],{"class":1147},[812,1513,1514],{"class":1151},"headers[",[812,1516,1321],{"class":1147},[812,1518,1519],{"class":821},"x-request-id",[812,1521,1321],{"class":1147},[812,1523,1524],{"class":1151},"] ",[812,1526,1527],{"class":1147},"===",[812,1529,1167],{"class":1147},[812,1531,1532],{"class":821},"string",[812,1534,1173],{"class":1147},[812,1536,1538,1541,1543,1545,1547,1549,1551,1553],{"class":814,"line":1537},25,[812,1539,1540],{"class":1147},"      ?",[812,1542,1435],{"class":1151},[812,1544,1438],{"class":1147},[812,1546,1514],{"class":1151},[812,1548,1321],{"class":1147},[812,1550,1519],{"class":821},[812,1552,1321],{"class":1147},[812,1554,1555],{"class":1151},"]\n",[812,1557,1559,1562],{"class":814,"line":1558},26,[812,1560,1561],{"class":1147},"      :",[812,1563,1564],{"class":1147}," undefined,\n",[812,1566,1568,1571,1573],{"class":814,"line":1567},27,[812,1569,1570],{"class":1147},"  }",[812,1572,613],{"class":1151},[812,1574,1190],{"class":1147},[812,1576,1578,1581,1583,1585,1587,1589,1592,1594,1596],{"class":814,"line":1577},28,[812,1579,1580],{"class":1305},"  attachLogger",[812,1582,1391],{"class":1147},[812,1584,1411],{"class":1147},[812,1586,1415],{"class":1414},[812,1588,1155],{"class":1147},[812,1590,1591],{"class":1414}," logger",[812,1593,613],{"class":1147},[812,1595,1420],{"class":1268},[812,1597,1181],{"class":1147},[812,1599,1601,1604,1606,1609,1611,1614,1616,1619,1621,1623,1625,1627,1629,1632,1634],{"class":814,"line":1600},29,[812,1602,1603],{"class":1387},"    (",[812,1605,1415],{"class":1151},[812,1607,1608],{"class":1140}," as",[812,1610,1152],{"class":818},[812,1612,1613],{"class":1147}," &",[812,1615,1148],{"class":1147},[812,1617,1618],{"class":1387}," log",[812,1620,1391],{"class":1147},[812,1622,1242],{"class":818},[812,1624,1161],{"class":1147},[812,1626,613],{"class":1387},[812,1628,1438],{"class":1147},[812,1630,1631],{"class":1151},"log",[812,1633,1274],{"class":1147},[812,1635,1636],{"class":1151}," logger\n",[812,1638,1640],{"class":814,"line":1639},30,[812,1641,1642],{"class":1147},"  },\n",[812,1644,1646,1649],{"class":814,"line":1645},31,[812,1647,1648],{"class":1151},"  storage",[812,1650,1190],{"class":1147},[812,1652,1654,1656],{"class":814,"line":1653},32,[812,1655,1215],{"class":1147},[812,1657,1329],{"class":1151},[812,1659,1661],{"class":814,"line":1660},33,[812,1662,1259],{"emptyLinePlaceholder":1258},[812,1664,1666,1668,1671,1674,1676,1679,1681,1683,1685,1688],{"class":814,"line":1665},34,[812,1667,1265],{"class":1140},[812,1669,1670],{"class":1268}," function",[812,1672,1673],{"class":1305}," evlog",[812,1675,1378],{"class":1147},[812,1677,1678],{"class":1414},"options",[812,1680,1391],{"class":1147},[812,1682,1271],{"class":818},[812,1684,1274],{"class":1147},[812,1686,1687],{"class":1147}," {})",[812,1689,1181],{"class":1147},[812,1691,1693,1696,1699,1701,1703,1705,1707,1709,1712,1714,1716,1718,1721,1723,1726,1728,1731,1733,1736,1739,1741],{"class":814,"line":1692},35,[812,1694,1695],{"class":1140},"  return",[812,1697,1698],{"class":1268}," async",[812,1700,1411],{"class":1147},[812,1702,1415],{"class":1414},[812,1704,1391],{"class":1147},[812,1706,1152],{"class":818},[812,1708,1155],{"class":1147},[812,1710,1711],{"class":1414}," res",[812,1713,1391],{"class":1147},[812,1715,1158],{"class":818},[812,1717,1155],{"class":1147},[812,1719,1720],{"class":1305}," next",[812,1722,1391],{"class":1147},[812,1724,1725],{"class":1147}," ()",[812,1727,1420],{"class":1268},[812,1729,1730],{"class":818}," Promise",[812,1732,1369],{"class":1147},[812,1734,1735],{"class":818},"void",[812,1737,1738],{"class":1147},">)",[812,1740,1420],{"class":1268},[812,1742,1181],{"class":1147},[812,1744,1746,1749,1751,1754,1756,1759,1761,1764,1766,1768,1771,1773,1776,1778,1780,1782,1784],{"class":814,"line":1745},36,[812,1747,1748],{"class":1268},"    const",[812,1750,1148],{"class":1147},[812,1752,1753],{"class":1151}," skipped",[812,1755,1155],{"class":1147},[812,1757,1758],{"class":1151}," finish",[812,1760,1155],{"class":1147},[812,1762,1763],{"class":1151}," runWith",[812,1765,1161],{"class":1147},[812,1767,1274],{"class":1147},[812,1769,1770],{"class":1151}," integration",[812,1772,1438],{"class":1147},[812,1774,1775],{"class":1305},"start",[812,1777,1378],{"class":1387},[812,1779,1415],{"class":1151},[812,1781,1155],{"class":1147},[812,1783,764],{"class":1151},[812,1785,1329],{"class":1387},[812,1787,1789,1792,1794,1796,1799],{"class":814,"line":1788},37,[812,1790,1791],{"class":1140},"    if",[812,1793,1411],{"class":1387},[812,1795,704],{"class":1151},[812,1797,1798],{"class":1387},") ",[812,1800,1381],{"class":1147},[812,1802,1804,1807,1809],{"class":814,"line":1803},38,[812,1805,1806],{"class":1140},"      await",[812,1808,1720],{"class":1305},[812,1810,1811],{"class":1387},"()\n",[812,1813,1815],{"class":814,"line":1814},39,[812,1816,1817],{"class":1140},"      return\n",[812,1819,1821],{"class":814,"line":1820},40,[812,1822,1823],{"class":1147},"    }\n",[812,1825,1827,1830],{"class":814,"line":1826},41,[812,1828,1829],{"class":1140},"    try",[812,1831,1181],{"class":1147},[812,1833,1835,1837,1839,1841,1844,1846,1848],{"class":814,"line":1834},42,[812,1836,1806],{"class":1140},[812,1838,1763],{"class":1305},[812,1840,1378],{"class":1387},[812,1842,1843],{"class":1147},"()",[812,1845,1420],{"class":1268},[812,1847,1720],{"class":1305},[812,1849,1850],{"class":1387},"())\n",[812,1852,1854,1856,1858,1860,1863,1866,1868,1870,1872,1875,1877],{"class":814,"line":1853},43,[812,1855,1806],{"class":1140},[812,1857,1758],{"class":1305},[812,1859,1378],{"class":1387},[812,1861,1862],{"class":1147},"{",[812,1864,1865],{"class":1387}," status",[812,1867,1391],{"class":1147},[812,1869,1711],{"class":1151},[812,1871,1438],{"class":1147},[812,1873,1874],{"class":1151},"statusCode",[812,1876,1161],{"class":1147},[812,1878,1329],{"class":1387},[812,1880,1882,1885,1888,1890,1893,1895],{"class":814,"line":1881},44,[812,1883,1884],{"class":1147},"    }",[812,1886,1887],{"class":1140}," catch",[812,1889,1411],{"class":1387},[812,1891,1892],{"class":1151},"error",[812,1894,1798],{"class":1387},[812,1896,1381],{"class":1147},[812,1898,1900,1902,1904,1906,1908,1911,1913,1915,1917,1920,1922],{"class":814,"line":1899},45,[812,1901,1806],{"class":1140},[812,1903,1758],{"class":1305},[812,1905,1378],{"class":1387},[812,1907,1862],{"class":1147},[812,1909,1910],{"class":1387}," error",[812,1912,1391],{"class":1147},[812,1914,1910],{"class":1151},[812,1916,1608],{"class":1140},[812,1918,1919],{"class":818}," Error",[812,1921,1161],{"class":1147},[812,1923,1329],{"class":1387},[812,1925,1927,1930],{"class":814,"line":1926},46,[812,1928,1929],{"class":1140},"      throw",[812,1931,1932],{"class":1151}," error\n",[812,1934,1936],{"class":814,"line":1935},47,[812,1937,1823],{"class":1147},[812,1939,1941],{"class":814,"line":1940},48,[812,1942,1943],{"class":1147},"  }\n",[812,1945,1947],{"class":814,"line":1946},49,[812,1948,1949],{"class":1147},"}\n",[517,1951,1952,1953,1955],{},"That's it. This middleware gets every feature for free: route filtering, drain adapters, enrichers, tail sampling, error capture, plugin lifecycle hooks, ",[521,1954,726],{},", and duration tracking.",[1957,1958,1960,1961,1963],"h3",{"id":1959},"what-defineframeworkintegration-does","What ",[521,1962,650],{}," does",[517,1965,1966],{},"Given the manifest above, the helper:",[1968,1969,1970,1979,1990,1996,2000,2010],"ol",{},[642,1971,1972,1973,1975,1976,1978],{},"Normalizes headers (auto-detects ",[521,1974,680],{}," vs ",[521,1977,684],{},").",[642,1980,1981,1982,1985,1986,1989],{},"Generates a ",[521,1983,1984],{},"requestId"," if ",[521,1987,1988],{},"extractRequest"," doesn't return one.",[642,1991,1992,1993,1995],{},"Calls ",[521,1994,1032],{}," with the merged options.",[642,1997,1992,1998,1438],{},[521,1999,665],{},[642,2001,2002,2003,2005,2006,2009],{},"Attaches ",[521,2004,726],{}," to the logger when ",[521,2007,2008],{},"storage"," is provided (so users can spawn correlated background work).",[642,2011,2012,2013,2016,2017,2020,2021,2024,2025,1438],{},"Exposes ",[521,2014,2015],{},"runWith(fn)"," — runs ",[521,2018,2019],{},"fn()"," inside ",[521,2022,2023],{},"storage.run(logger, …)"," if storage is configured, otherwise just calls ",[521,2026,2019],{},[517,2028,2029],{},"You're left with only the framework-specific glue: where to read the request from, where to attach the logger, and how to compute the response status.",[794,2031,2033],{"id":2032},"custom-mode","Custom mode",[517,2035,2036,2037,2039,2040,2042,2043,2045],{},"If your framework's lifecycle doesn't fit a clean ",[521,2038,589],{}," shape (NestJS interceptors, Next.js App Router, SvelteKit ",[521,2041,612],{},"), drop one level lower and call ",[521,2044,1032],{}," directly:",[802,2047,2049],{"className":1130,"code":2048,"language":1133,"meta":808,"style":808},"import { createMiddlewareLogger, extractSafeNodeHeaders } from 'evlog\u002Ftoolkit'\n\nconst { logger, finish, skipped } = createMiddlewareLogger({\n  method,\n  path,\n  requestId,\n  headers: extractSafeNodeHeaders(rawHeaders),\n  ...options,\n})\n",[521,2050,2051,2075,2079,2106,2113,2120,2127,2141,2150],{"__ignoreMap":808},[812,2052,2053,2055,2057,2060,2062,2065,2067,2069,2071,2073],{"class":814,"line":815},[812,2054,1141],{"class":1140},[812,2056,1148],{"class":1147},[812,2058,2059],{"class":1151}," createMiddlewareLogger",[812,2061,1155],{"class":1147},[812,2063,2064],{"class":1151}," extractSafeNodeHeaders",[812,2066,1161],{"class":1147},[812,2068,1164],{"class":1140},[812,2070,1167],{"class":1147},[812,2072,527],{"class":821},[812,2074,1173],{"class":1147},[812,2076,2077],{"class":814,"line":1176},[812,2078,1259],{"emptyLinePlaceholder":1258},[812,2080,2081,2083,2085,2087,2089,2091,2093,2096,2098,2100,2102,2104],{"class":814,"line":1184},[812,2082,1288],{"class":1268},[812,2084,1148],{"class":1147},[812,2086,1591],{"class":1151},[812,2088,1155],{"class":1147},[812,2090,1758],{"class":1151},[812,2092,1155],{"class":1147},[812,2094,2095],{"class":1151}," skipped ",[812,2097,1215],{"class":1147},[812,2099,1274],{"class":1147},[812,2101,2059],{"class":1305},[812,2103,1378],{"class":1151},[812,2105,1381],{"class":1147},[812,2107,2108,2111],{"class":814,"line":1193},[812,2109,2110],{"class":1151},"  method",[812,2112,1190],{"class":1147},[812,2114,2115,2118],{"class":814,"line":1201},[812,2116,2117],{"class":1151},"  path",[812,2119,1190],{"class":1147},[812,2121,2122,2125],{"class":814,"line":1212},[812,2123,2124],{"class":1151},"  requestId",[812,2126,1190],{"class":1147},[812,2128,2129,2132,2134,2136,2139],{"class":814,"line":1226},[812,2130,2131],{"class":1387},"  headers",[812,2133,1391],{"class":1147},[812,2135,2064],{"class":1305},[812,2137,2138],{"class":1151},"(rawHeaders)",[812,2140,1190],{"class":1147},[812,2142,2143,2146,2148],{"class":814,"line":1233},[812,2144,2145],{"class":1147},"  ...",[812,2147,1678],{"class":1151},[812,2149,1190],{"class":1147},[812,2151,2152,2154],{"class":814,"line":1255},[812,2153,1215],{"class":1147},[812,2155,1329],{"class":1151},[517,2157,2158,2159,2162,2163,2165,2166,2169],{},"You'll be responsible for ALS wrapping (",[521,2160,2161],{},"storage.run","), ",[521,2164,726],{}," attachment (via ",[521,2167,2168],{},"attachForkToLogger","), and finishing the lifecycle — but you keep the full pipeline (route filtering, sampling, emit, enrich, drain, plugins) for free.",[794,2171,2173],{"id":2172},"serverless-workers-edge","Serverless (Workers \u002F Edge)",[517,2175,2176,2177,2179,2180,2185],{},"On Cloudflare Workers and Vercel Edge, the runtime can terminate as soon as the response is returned. If your drain sends HTTP to an observability backend, pass ",[521,2178,770],{}," so enrich still runs inline but drain work survives after the response — the same behavior as ",[575,2181,2182],{"href":271},[521,2183,2184],{},"evlog\u002Fworkers"," and the Nitro plugin.",[517,2187,2188,2190,2191,2193],{},[533,2189,2033],{}," — pass ",[521,2192,770],{}," per request:",[802,2195,2197],{"className":1130,"code":2196,"language":1133,"meta":808,"style":808},"import { waitUntil } from '@vercel\u002Ffunctions'\n\u002F\u002F import { waitUntil } from 'cloudflare:workers' \u002F\u002F Vercel-style global on some runtimes\n\nconst { logger, finish, skipped } = createMiddlewareLogger({\n  method,\n  path,\n  requestId,\n  headers: extractSafeNodeHeaders(rawHeaders),\n  waitUntil, \u002F\u002F or ctx.waitUntil.bind(ctx) on Cloudflare\n  ...options,\n})\n",[521,2198,2199,2219,2227,2231,2257,2263,2269,2275,2287,2297,2305],{"__ignoreMap":808},[812,2200,2201,2203,2205,2208,2210,2212,2214,2217],{"class":814,"line":815},[812,2202,1141],{"class":1140},[812,2204,1148],{"class":1147},[812,2206,2207],{"class":1151}," waitUntil",[812,2209,1161],{"class":1147},[812,2211,1164],{"class":1140},[812,2213,1167],{"class":1147},[812,2215,2216],{"class":821},"@vercel\u002Ffunctions",[812,2218,1173],{"class":1147},[812,2220,2221,2224],{"class":814,"line":1176},[812,2222,2223],{"class":1229},"\u002F\u002F import { waitUntil } from 'cloudflare:workers'",[812,2225,2226],{"class":1229}," \u002F\u002F Vercel-style global on some runtimes\n",[812,2228,2229],{"class":814,"line":1184},[812,2230,1259],{"emptyLinePlaceholder":1258},[812,2232,2233,2235,2237,2239,2241,2243,2245,2247,2249,2251,2253,2255],{"class":814,"line":1193},[812,2234,1288],{"class":1268},[812,2236,1148],{"class":1147},[812,2238,1591],{"class":1151},[812,2240,1155],{"class":1147},[812,2242,1758],{"class":1151},[812,2244,1155],{"class":1147},[812,2246,2095],{"class":1151},[812,2248,1215],{"class":1147},[812,2250,1274],{"class":1147},[812,2252,2059],{"class":1305},[812,2254,1378],{"class":1151},[812,2256,1381],{"class":1147},[812,2258,2259,2261],{"class":814,"line":1201},[812,2260,2110],{"class":1151},[812,2262,1190],{"class":1147},[812,2264,2265,2267],{"class":814,"line":1212},[812,2266,2117],{"class":1151},[812,2268,1190],{"class":1147},[812,2270,2271,2273],{"class":814,"line":1226},[812,2272,2124],{"class":1151},[812,2274,1190],{"class":1147},[812,2276,2277,2279,2281,2283,2285],{"class":814,"line":1233},[812,2278,2131],{"class":1387},[812,2280,1391],{"class":1147},[812,2282,2064],{"class":1305},[812,2284,2138],{"class":1151},[812,2286,1190],{"class":1147},[812,2288,2289,2292,2294],{"class":814,"line":1255},[812,2290,2291],{"class":1151},"  waitUntil",[812,2293,1155],{"class":1147},[812,2295,2296],{"class":1229}," \u002F\u002F or ctx.waitUntil.bind(ctx) on Cloudflare\n",[812,2298,2299,2301,2303],{"class":814,"line":1262},[812,2300,2145],{"class":1147},[812,2302,1678],{"class":1151},[812,2304,1190],{"class":1147},[812,2306,2307,2309],{"class":814,"line":1280},[812,2308,1215],{"class":1147},[812,2310,1329],{"class":1151},[517,2312,2313,2316,2317,2319,2320,2322,2323,2325],{},[533,2314,2315],{},"Manifest mode"," — either pass ",[521,2318,770],{}," in ",[521,2321,694],{}," or declare ",[521,2324,774],{}," on the manifest when the hook lives on the framework context:",[802,2327,2329],{"className":1130,"code":2328,"language":1133,"meta":808,"style":808},"const integration = defineFrameworkIntegration\u003CWorkerContext>({\n  name: 'my-framework',\n  extractRequest: (ctx) => ({ \u002F* … *\u002F }),\n  attachLogger: (ctx, logger) => { \u002F* … *\u002F },\n  extractWaitUntil: ctx => ctx.executionCtx.waitUntil.bind(ctx.executionCtx),\n})\n\nexport function evlog(options: BaseEvlogOptions = {}) {\n  return async (ctx, next) => {\n    const { skipped, finish, runWith } = integration.start(ctx, options)\n    \u002F\u002F Per-request override still works:\n    \u002F\u002F integration.start(ctx, { ...options, waitUntil: ctx.executionCtx.waitUntil.bind(ctx.executionCtx) })\n    \u002F\u002F …\n  }\n}\n",[521,2330,2331,2352,2366,2394,2419,2457,2463,2467,2489,2509,2545,2550,2555,2560,2564],{"__ignoreMap":808},[812,2332,2333,2335,2337,2339,2341,2343,2346,2348,2350],{"class":814,"line":815},[812,2334,1288],{"class":1268},[812,2336,1360],{"class":1151},[812,2338,1363],{"class":1147},[812,2340,1366],{"class":1305},[812,2342,1369],{"class":1147},[812,2344,2345],{"class":818},"WorkerContext",[812,2347,1375],{"class":1147},[812,2349,1378],{"class":1151},[812,2351,1381],{"class":1147},[812,2353,2354,2356,2358,2360,2362,2364],{"class":814,"line":1176},[812,2355,1388],{"class":1387},[812,2357,1391],{"class":1147},[812,2359,1167],{"class":1147},[812,2361,1396],{"class":821},[812,2363,1321],{"class":1147},[812,2365,1190],{"class":1147},[812,2367,2368,2370,2372,2374,2377,2379,2381,2383,2385,2388,2390,2392],{"class":814,"line":1184},[812,2369,1406],{"class":1305},[812,2371,1391],{"class":1147},[812,2373,1411],{"class":1147},[812,2375,2376],{"class":1414},"ctx",[812,2378,613],{"class":1147},[812,2380,1420],{"class":1268},[812,2382,1411],{"class":1151},[812,2384,1862],{"class":1147},[812,2386,2387],{"class":1229}," \u002F* … *\u002F",[812,2389,1161],{"class":1147},[812,2391,613],{"class":1151},[812,2393,1190],{"class":1147},[812,2395,2396,2398,2400,2402,2404,2406,2408,2410,2412,2414,2416],{"class":814,"line":1193},[812,2397,1580],{"class":1305},[812,2399,1391],{"class":1147},[812,2401,1411],{"class":1147},[812,2403,2376],{"class":1414},[812,2405,1155],{"class":1147},[812,2407,1591],{"class":1414},[812,2409,613],{"class":1147},[812,2411,1420],{"class":1268},[812,2413,1148],{"class":1147},[812,2415,2387],{"class":1229},[812,2417,2418],{"class":1147}," },\n",[812,2420,2421,2424,2426,2429,2431,2433,2435,2438,2440,2442,2444,2447,2450,2452,2455],{"class":814,"line":1201},[812,2422,2423],{"class":1305},"  extractWaitUntil",[812,2425,1391],{"class":1147},[812,2427,2428],{"class":1414}," ctx",[812,2430,1420],{"class":1268},[812,2432,2428],{"class":1151},[812,2434,1438],{"class":1147},[812,2436,2437],{"class":1151},"executionCtx",[812,2439,1438],{"class":1147},[812,2441,770],{"class":1151},[812,2443,1438],{"class":1147},[812,2445,2446],{"class":1305},"bind",[812,2448,2449],{"class":1151},"(ctx",[812,2451,1438],{"class":1147},[812,2453,2454],{"class":1151},"executionCtx)",[812,2456,1190],{"class":1147},[812,2458,2459,2461],{"class":814,"line":1212},[812,2460,1215],{"class":1147},[812,2462,1329],{"class":1151},[812,2464,2465],{"class":814,"line":1226},[812,2466,1259],{"emptyLinePlaceholder":1258},[812,2468,2469,2471,2473,2475,2477,2479,2481,2483,2485,2487],{"class":814,"line":1233},[812,2470,1265],{"class":1140},[812,2472,1670],{"class":1268},[812,2474,1673],{"class":1305},[812,2476,1378],{"class":1147},[812,2478,1678],{"class":1414},[812,2480,1391],{"class":1147},[812,2482,1207],{"class":818},[812,2484,1274],{"class":1147},[812,2486,1687],{"class":1147},[812,2488,1181],{"class":1147},[812,2490,2491,2493,2495,2497,2499,2501,2503,2505,2507],{"class":814,"line":1255},[812,2492,1695],{"class":1140},[812,2494,1698],{"class":1268},[812,2496,1411],{"class":1147},[812,2498,2376],{"class":1414},[812,2500,1155],{"class":1147},[812,2502,1720],{"class":1414},[812,2504,613],{"class":1147},[812,2506,1420],{"class":1268},[812,2508,1181],{"class":1147},[812,2510,2511,2513,2515,2517,2519,2521,2523,2525,2527,2529,2531,2533,2535,2537,2539,2541,2543],{"class":814,"line":1262},[812,2512,1748],{"class":1268},[812,2514,1148],{"class":1147},[812,2516,1753],{"class":1151},[812,2518,1155],{"class":1147},[812,2520,1758],{"class":1151},[812,2522,1155],{"class":1147},[812,2524,1763],{"class":1151},[812,2526,1161],{"class":1147},[812,2528,1274],{"class":1147},[812,2530,1770],{"class":1151},[812,2532,1438],{"class":1147},[812,2534,1775],{"class":1305},[812,2536,1378],{"class":1387},[812,2538,2376],{"class":1151},[812,2540,1155],{"class":1147},[812,2542,764],{"class":1151},[812,2544,1329],{"class":1387},[812,2546,2547],{"class":814,"line":1280},[812,2548,2549],{"class":1229},"    \u002F\u002F Per-request override still works:\n",[812,2551,2552],{"class":814,"line":1285},[812,2553,2554],{"class":1229},"    \u002F\u002F integration.start(ctx, { ...options, waitUntil: ctx.executionCtx.waitUntil.bind(ctx.executionCtx) })\n",[812,2556,2557],{"class":814,"line":1312},[812,2558,2559],{"class":1229},"    \u002F\u002F …\n",[812,2561,2562],{"class":814,"line":1326},[812,2563,1943],{"class":1147},[812,2565,2566],{"class":814,"line":1332},[812,2567,1949],{"class":1147},[517,2569,2570,2571,2574,2575,2577],{},"Per-request ",[521,2572,2573],{},"options.waitUntil"," takes precedence over ",[521,2576,774],{},". Without either, drains are awaited (correct for traditional Node.js servers).",[794,2579,2581],{"id":2580},"non-http-runtimes","Non-HTTP runtimes",[517,2583,2584,2585,651,2587,2045],{},"For queue workers, CLI drivers, cron jobs, or durable execution engines, skip the HTTP-shaped helpers and use ",[521,2586,781],{},[521,2588,527],{},[802,2590,2594],{"className":2591,"code":2592,"language":2593,"meta":808,"style":808},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { createRequestLogger } from 'evlog\u002Ftoolkit'\n\nasync function processJob(job: Job) {\n  const logger = createRequestLogger({\n    service: 'jobs',\n    context: { jobId: job.id, queue: job.queue },\n  })\n\n  try {\n    await runJob(job)\n    logger.set({ status: 'success' })\n  } catch (err) {\n    logger.error(err)\n    throw err\n  } finally {\n    await logger.emit()\n  }\n}\n","ts",[521,2595,2596,2615,2619,2643,2658,2674,2712,2718,2722,2729,2743,2772,2787,2801,2809,2818,2831,2835],{"__ignoreMap":808},[812,2597,2598,2600,2602,2605,2607,2609,2611,2613],{"class":814,"line":815},[812,2599,1141],{"class":1140},[812,2601,1148],{"class":1147},[812,2603,2604],{"class":1151}," createRequestLogger",[812,2606,1161],{"class":1147},[812,2608,1164],{"class":1140},[812,2610,1167],{"class":1147},[812,2612,527],{"class":821},[812,2614,1173],{"class":1147},[812,2616,2617],{"class":814,"line":1176},[812,2618,1259],{"emptyLinePlaceholder":1258},[812,2620,2621,2624,2626,2629,2631,2634,2636,2639,2641],{"class":814,"line":1184},[812,2622,2623],{"class":1268},"async",[812,2625,1670],{"class":1268},[812,2627,2628],{"class":1305}," processJob",[812,2630,1378],{"class":1147},[812,2632,2633],{"class":1414},"job",[812,2635,1391],{"class":1147},[812,2637,2638],{"class":818}," Job",[812,2640,613],{"class":1147},[812,2642,1181],{"class":1147},[812,2644,2645,2648,2650,2652,2654,2656],{"class":814,"line":1193},[812,2646,2647],{"class":1268},"  const",[812,2649,1591],{"class":1151},[812,2651,1274],{"class":1147},[812,2653,2604],{"class":1305},[812,2655,1378],{"class":1387},[812,2657,1381],{"class":1147},[812,2659,2660,2663,2665,2667,2670,2672],{"class":814,"line":1201},[812,2661,2662],{"class":1387},"    service",[812,2664,1391],{"class":1147},[812,2666,1167],{"class":1147},[812,2668,2669],{"class":821},"jobs",[812,2671,1321],{"class":1147},[812,2673,1190],{"class":1147},[812,2675,2676,2679,2681,2683,2686,2688,2691,2693,2696,2698,2701,2703,2705,2707,2710],{"class":814,"line":1212},[812,2677,2678],{"class":1387},"    context",[812,2680,1391],{"class":1147},[812,2682,1148],{"class":1147},[812,2684,2685],{"class":1387}," jobId",[812,2687,1391],{"class":1147},[812,2689,2690],{"class":1151}," job",[812,2692,1438],{"class":1147},[812,2694,2695],{"class":1151},"id",[812,2697,1155],{"class":1147},[812,2699,2700],{"class":1387}," queue",[812,2702,1391],{"class":1147},[812,2704,2690],{"class":1151},[812,2706,1438],{"class":1147},[812,2708,2709],{"class":1151},"queue",[812,2711,2418],{"class":1147},[812,2713,2714,2716],{"class":814,"line":1226},[812,2715,1570],{"class":1147},[812,2717,1329],{"class":1387},[812,2719,2720],{"class":814,"line":1233},[812,2721,1259],{"emptyLinePlaceholder":1258},[812,2723,2724,2727],{"class":814,"line":1255},[812,2725,2726],{"class":1140},"  try",[812,2728,1181],{"class":1147},[812,2730,2731,2734,2737,2739,2741],{"class":814,"line":1262},[812,2732,2733],{"class":1140},"    await",[812,2735,2736],{"class":1305}," runJob",[812,2738,1378],{"class":1387},[812,2740,2633],{"class":1151},[812,2742,1329],{"class":1387},[812,2744,2745,2748,2750,2753,2755,2757,2759,2761,2763,2766,2768,2770],{"class":814,"line":1280},[812,2746,2747],{"class":1151},"    logger",[812,2749,1438],{"class":1147},[812,2751,2752],{"class":1305},"set",[812,2754,1378],{"class":1387},[812,2756,1862],{"class":1147},[812,2758,1865],{"class":1387},[812,2760,1391],{"class":1147},[812,2762,1167],{"class":1147},[812,2764,2765],{"class":821},"success",[812,2767,1321],{"class":1147},[812,2769,1161],{"class":1147},[812,2771,1329],{"class":1387},[812,2773,2774,2776,2778,2780,2783,2785],{"class":814,"line":1285},[812,2775,1570],{"class":1147},[812,2777,1887],{"class":1140},[812,2779,1411],{"class":1387},[812,2781,2782],{"class":1151},"err",[812,2784,1798],{"class":1387},[812,2786,1381],{"class":1147},[812,2788,2789,2791,2793,2795,2797,2799],{"class":814,"line":1312},[812,2790,2747],{"class":1151},[812,2792,1438],{"class":1147},[812,2794,1892],{"class":1305},[812,2796,1378],{"class":1387},[812,2798,2782],{"class":1151},[812,2800,1329],{"class":1387},[812,2802,2803,2806],{"class":814,"line":1326},[812,2804,2805],{"class":1140},"    throw",[812,2807,2808],{"class":1151}," err\n",[812,2810,2811,2813,2816],{"class":814,"line":1332},[812,2812,1570],{"class":1147},[812,2814,2815],{"class":1140}," finally",[812,2817,1181],{"class":1147},[812,2819,2820,2822,2824,2826,2829],{"class":814,"line":1337},[812,2821,2733],{"class":1140},[812,2823,1591],{"class":1151},[812,2825,1438],{"class":1147},[812,2827,2828],{"class":1305},"emit",[812,2830,1811],{"class":1387},[812,2832,2833],{"class":814,"line":1350},[812,2834,1943],{"class":1147},[812,2836,2837],{"class":814,"line":1355},[812,2838,1949],{"class":1147},[517,2840,2841,2842,2845],{},"Same enrichers, same drain hook, same ",[575,2843,2844],{"href":467},"identity headers"," on outbound HTTP drain requests — only the entry point shape changes.",[794,2847,2849],{"id":2848},"reference-implementations","Reference implementations",[517,2851,2852],{},"Study these built-in integrations for framework-specific patterns:",[548,2854,2855,2871],{},[551,2856,2857],{},[554,2858,2859,2862,2865,2868],{},[557,2860,2861],{},"Framework",[557,2863,2864],{},"Lines",[557,2866,2867],{},"Mode",[557,2869,2870],{},"Source",[567,2872,2873,2890,2906,2923,2940,2957],{},[554,2874,2875,2877,2880,2883],{},[572,2876,250],{},[572,2878,2879],{},"~50",[572,2881,2882],{},"manifest",[572,2884,2885],{},[575,2886,2889],{"href":2887,"rel":2888},"https:\u002F\u002Fgithub.com\u002Fhugorcd\u002Fevlog\u002Fblob\u002Fmain\u002Fpackages\u002Fevlog\u002Fsrc\u002Fhono\u002Findex.ts",[792],"hono\u002Findex.ts",[554,2891,2892,2894,2896,2899],{},[572,2893,245],{},[572,2895,2879],{},[572,2897,2898],{},"manifest + ALS",[572,2900,2901],{},[575,2902,2905],{"href":2903,"rel":2904},"https:\u002F\u002Fgithub.com\u002Fhugorcd\u002Fevlog\u002Fblob\u002Fmain\u002Fpackages\u002Fevlog\u002Fsrc\u002Fexpress\u002Findex.ts",[792],"express\u002Findex.ts",[554,2907,2908,2910,2913,2916],{},[572,2909,255],{},[572,2911,2912],{},"~70",[572,2914,2915],{},"manifest + Fastify hooks",[572,2917,2918],{},[575,2919,2922],{"href":2920,"rel":2921},"https:\u002F\u002Fgithub.com\u002Fhugorcd\u002Fevlog\u002Fblob\u002Fmain\u002Fpackages\u002Fevlog\u002Fsrc\u002Ffastify\u002Findex.ts",[792],"fastify\u002Findex.ts",[554,2924,2925,2927,2930,2933],{},[572,2926,260],{},[572,2928,2929],{},"~80",[572,2931,2932],{},"manifest + custom ALS scoping",[572,2934,2935],{},[575,2936,2939],{"href":2937,"rel":2938},"https:\u002F\u002Fgithub.com\u002Fhugorcd\u002Fevlog\u002Fblob\u002Fmain\u002Fpackages\u002Fevlog\u002Fsrc\u002Felysia\u002Findex.ts",[792],"elysia\u002Findex.ts",[554,2941,2942,2944,2947,2950],{},[572,2943,240],{},[572,2945,2946],{},"~120",[572,2948,2949],{},"custom (interceptor)",[572,2951,2952],{},[575,2953,2956],{"href":2954,"rel":2955},"https:\u002F\u002Fgithub.com\u002Fhugorcd\u002Fevlog\u002Fblob\u002Fmain\u002Fpackages\u002Fevlog\u002Fsrc\u002Fnestjs\u002F",[792],"nestjs\u002F",[554,2958,2959,2961,2964,2970],{},[572,2960,225],{},[572,2962,2963],{},"~90",[572,2965,2966,2967,2969],{},"custom (",[521,2968,612],{}," hook)",[572,2971,2972],{},[575,2973,2976],{"href":2974,"rel":2975},"https:\u002F\u002Fgithub.com\u002Fhugorcd\u002Fevlog\u002Fblob\u002Fmain\u002Fpackages\u002Fevlog\u002Fsrc\u002Fsveltekit\u002F",[792],"sveltekit\u002F",[538,2978,2981,2982,2987],{"color":2979,"icon":2980},"neutral","i-lucide-heart","Built an integration for a framework we don't support? ",[575,2983,2986],{"href":2984,"rel":2985},"https:\u002F\u002Fgithub.com\u002Fhugorcd\u002Fevlog\u002Fpulls",[792],"Open a PR"," — the community will thank you.",[794,2989,2991],{"id":2990},"next-steps","Next steps",[639,2993,2994,3000,3006,3011,3016,3021],{},[642,2995,2996,2999],{},[575,2997,2998],{"href":472},"Custom Drains"," — same toolkit shape for drain destinations",[642,3001,3002,3005],{},[575,3003,3004],{"href":459},"Custom Enrichers"," — same toolkit shape for derived event fields",[642,3007,3008,3010],{},[575,3009,454],{"href":455}," — multi-hook extensions (drain + enrich + keep in one object)",[642,3012,3013,3015],{},[575,3014,46],{"href":47}," — design comprehensive events with context layering",[642,3017,3018,3020],{},[575,3019,61],{"href":62}," — control log volume with head and tail sampling",[642,3022,3023,3025],{},[575,3024,133],{"href":138}," — send logs to Axiom, Sentry, PostHog, and more",[3027,3028,3029],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .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 .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}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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}",{"title":808,"searchDepth":1176,"depth":1176,"links":3031},[3032,3033,3034,3038,3039,3040,3041,3042],{"id":796,"depth":1176,"text":797},{"id":871,"depth":1176,"text":872},{"id":1114,"depth":1176,"text":1115,"children":3035},[3036],{"id":1959,"depth":1184,"text":3037},"What defineFrameworkIntegration does",{"id":2032,"depth":1176,"text":2033},{"id":2172,"depth":1176,"text":2173},{"id":2580,"depth":1176,"text":2581},{"id":2848,"depth":1176,"text":2849},{"id":2990,"depth":1176,"text":2991},"Build evlog support for an HTTP framework (or non-HTTP runtime) without a built-in integration. Use defineFrameworkIntegration for the (ctx, next) middleware shape, or createMiddlewareLogger \u002F createRequestLogger for everything else.","md",[3046,3048],{"label":2998,"icon":474,"to":472,"color":2979,"variant":3047},"subtle",{"label":3004,"icon":419,"to":459,"color":2979,"variant":3047},{},{"title":440,"icon":443},{"title":512,"description":3043},"tE0g7MuhC5DtwwxqiGtuCyY-5TQDWiziJyFf9R_bXaA",[3054,3056],{"title":435,"path":436,"stem":437,"description":3055,"icon":438,"children":-1},"Subscribe to wide events flowing through evlog — in-process with createStreamDrain, or over the network with the local SSE stream server.",{"title":445,"path":446,"stem":447,"description":3057,"icon":448,"children":-1},"Replay and tail the local NDJSON drain with readFsLogs and tailFsLogs — works in-process or from any external Node tool, survives restarts.",1785609202593]