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