[{"data":1,"prerenderedAt":2991},["ShallowReactive",2],{"navigation_docs":3,"-extend-custom-framework":464,"-extend-custom-framework-surround":2986},[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":2976,"extension":2977,"links":2978,"meta":2982,"navigation":2983,"path":395,"seo":2984,"stem":396,"__hash__":2985},"docs\u002F5.extend\u002F10.custom-framework.md","Custom Framework Integration",{"type":468,"value":469,"toc":2963},"minimark",[470,483,491,501,584,742,747,818,822,1031,1054,1058,1067,1882,1888,1896,1899,1959,1962,1966,1978,2088,2102,2106,2118,2126,2244,2259,2501,2511,2515,2522,2772,2779,2783,2786,2910,2921,2925,2959],[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,734],"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,624,638,648,662,677,688,714,725],"ul",{},[596,597,598,599,601,602,605,606,608,609,612,613,616,617,620,621],"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()",[596,625,626,627,630,631,634,635,637],{},"Headers may be either Web ",[475,628,629],{},"Headers"," or Node ",[475,632,633],{},"IncomingHttpHeaders"," — ",[475,636,604],{}," normalizes both",[596,639,640,641,644,645],{},"In your middleware, call ",[475,642,643],{},"integration.start(ctx, options)"," which returns ",[475,646,647],{},"{ skipped, finish, runWith, logger, middlewareOptions }",[596,649,650,651,654,655,658,659],{},"If ",[475,652,653],{},"skipped"," is ",[475,656,657],{},"true",", skip directly to ",[475,660,661],{},"next",[596,663,664,665,668,669,672,673,676],{},"Run downstream handlers inside ",[475,666,667],{},"runWith(() => next())"," so ",[475,670,671],{},"AsyncLocalStorage"," and ",[475,674,675],{},"log.fork()"," work",[596,678,679,680,683,684,687],{},"On success: ",[475,681,682],{},"await finish({ status })","; on error: ",[475,685,686],{},"await finish({ error })"," then re-throw",[596,689,690,691,616,694,616,697,616,700,616,703,616,706,709,710,713],{},"Expose ",[475,692,693],{},"drain",[475,695,696],{},"enrich",[475,698,699],{},"keep",[475,701,702],{},"include",[475,704,705],{},"exclude",[475,707,708],{},"routes",", and ",[475,711,712],{},"plugins"," options",[596,715,716,717,720,721,724],{},"On Cloudflare Workers \u002F Vercel Edge, pass ",[475,718,719],{},"waitUntil"," (or ",[475,722,723],{},"extractWaitUntil"," on the manifest) so async drains complete after the response",[596,726,727,728,605,731,733],{},"For non-HTTP runtimes (queue workers, CLI, cron), use ",[475,729,730],{},"createRequestLogger",[475,732,481],{}," directly — wrap each unit of work in a logger lifecycle",[471,735,736,737],{},"Docs: ",[529,738,739],{"href":739,"rel":740},"https:\u002F\u002Fwww.evlog.dev\u002Fextend\u002Fcustom-framework",[741],"nofollow",[743,744,746],"h2",{"id":745},"install","Install",[748,749,750,775,789,803],"code-group",{},[751,752,758],"pre",{"className":753,"code":754,"filename":755,"language":756,"meta":757,"style":757},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm add evlog\n","pnpm","bash","",[475,759,760],{"__ignoreMap":757},[761,762,765,768,772],"span",{"class":763,"line":764},"line",1,[761,766,755],{"class":767},"sBMFI",[761,769,771],{"class":770},"sfazB"," add",[761,773,774],{"class":770}," evlog\n",[751,776,779],{"className":753,"code":777,"filename":778,"language":756,"meta":757,"style":757},"bun add evlog\n","bun",[475,780,781],{"__ignoreMap":757},[761,782,783,785,787],{"class":763,"line":764},[761,784,778],{"class":767},[761,786,771],{"class":770},[761,788,774],{"class":770},[751,790,793],{"className":753,"code":791,"filename":792,"language":756,"meta":757,"style":757},"yarn add evlog\n","yarn",[475,794,795],{"__ignoreMap":757},[761,796,797,799,801],{"class":763,"line":764},[761,798,792],{"class":767},[761,800,771],{"class":770},[761,802,774],{"class":770},[751,804,807],{"className":753,"code":805,"filename":806,"language":756,"meta":757,"style":757},"npm install evlog\n","npm",[475,808,809],{"__ignoreMap":757},[761,810,811,813,816],{"class":763,"line":764},[761,812,806],{"class":767},[761,814,815],{"class":770}," install",[761,817,774],{"class":770},[743,819,821],{"id":820},"whats-in-the-toolkit","What's in the toolkit",[502,823,824,834],{},[505,825,826],{},[508,827,828,831],{},[511,829,830],{},"Export",[511,832,833],{},"Purpose",[521,835,836,846,856,870,880,904,917,930,942,958,976,990,1021],{},[508,837,838,843],{},[526,839,840],{},[475,841,842],{},"defineFrameworkIntegration(spec)",[526,844,845],{},"Manifest factory — extract request, create logger, attach, run with ALS",[508,847,848,853],{},[526,849,850],{},[475,851,852],{},"createMiddlewareLogger(opts)",[526,854,855],{},"Lower-level lifecycle (custom mode)",[508,857,858,863],{},[526,859,860,862],{},[475,861,719],{}," on middleware options",[526,864,865,866,567],{},"Defer drain on Cloudflare Workers \u002F Vercel Edge (see ",[529,867,869],{"href":868},"#serverless-workers-edge","Serverless",[508,871,872,877],{},[526,873,874],{},[475,875,876],{},"createRequestLogger(opts)",[526,878,879],{},"Wrap a non-HTTP unit of work in a logger lifecycle",[508,881,882,887],{},[526,883,884],{},[475,885,886],{},"BaseEvlogOptions",[526,888,889,890,616,892,616,894,616,896,616,898,616,900,616,902],{},"Base user-facing options — ",[475,891,693],{},[475,893,696],{},[475,895,699],{},[475,897,702],{},[475,899,705],{},[475,901,708],{},[475,903,712],{},[508,905,906,911],{},[526,907,908],{},[475,909,910],{},"MiddlewareLoggerResult",[526,912,913,914],{},"Return type: ",[475,915,916],{},"{ logger, finish, skipped }",[508,918,919,924],{},[526,920,921],{},[475,922,923],{},"extractSafeHeaders(headers)",[526,925,926,927,929],{},"Filter sensitive headers from a Web API ",[475,928,629],{}," object",[508,931,932,937],{},[526,933,934],{},[475,935,936],{},"extractSafeNodeHeaders(headers)",[526,938,939,940],{},"Filter sensitive headers from Node.js ",[475,941,633],{},[508,943,944,949],{},[526,945,946],{},[475,947,948],{},"createLoggerStorage(hint)",[526,950,951,952,955,956],{},"Factory returning ",[475,953,954],{},"{ storage, useLogger }"," backed by ",[475,957,671],{},[508,959,960,965],{},[526,961,962],{},[475,963,964],{},"attachForkToLogger(storage, parent, opts)",[526,966,967,968,971,972,975],{},"Wires ",[475,969,970],{},"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,973,974],{},"createMiddlewareLogger"," returns the logger and before the lifecycle finishes",[508,977,978,983],{},[526,979,980],{},[475,981,982],{},"defineEvlog(config)",[526,984,985,986,989],{},"Canonical config object — works for ",[475,987,988],{},"initLogger"," and middleware options",[508,991,992,997],{},[526,993,994],{},[475,995,996],{},"definePlugin(plugin)",[526,998,999,1000,616,1003,616,1005,616,1007,616,1009,616,1012,616,1015,616,1018],{},"Plugin contract — opt into any subset of ",[475,1001,1002],{},"setup",[475,1004,696],{},[475,1006,693],{},[475,1008,699],{},[475,1010,1011],{},"onRequestStart",[475,1013,1014],{},"onRequestFinish",[475,1016,1017],{},"onClientLog",[475,1019,1020],{},"extendLogger",[508,1022,1023,1028],{},[526,1024,1025],{},[475,1026,1027],{},"composeEnrichers \u002F composeDrains \u002F composeKeep \u002F composePlugins",[526,1029,1030],{},"Combine multiple extensions into one",[471,1032,1033,1034,616,1037,616,1040,616,1043,709,1046,1049,1050,1053],{},"Types like ",[475,1035,1036],{},"RequestLogger",[475,1038,1039],{},"DrainContext",[475,1041,1042],{},"EnrichContext",[475,1044,1045],{},"WideEvent",[475,1047,1048],{},"TailSamplingContext"," are exported from the main ",[475,1051,1052],{},"evlog"," package.",[743,1055,1057],{"id":1056},"manifest-mode-recommended","Manifest mode (recommended)",[471,1059,1060,1061,1063,1064,1066],{},"Most frameworks fit a ",[475,1062,543],{}," middleware shape. For those, write a manifest describing how to extract the request and attach the logger — ",[475,1065,604],{}," does the rest.",[751,1068,1073],{"className":1069,"code":1070,"filename":1071,"language":1072,"meta":757,"style":757},"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'\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,1074,1075,1113,1121,1130,1138,1149,1163,1185,1192,1210,1215,1242,1256,1262,1267,1280,1285,1314,1333,1357,1386,1412,1429,1467,1488,1497,1507,1530,1569,1575,1583,1590,1595,1622,1675,1718,1733,1744,1750,1756,1764,1783,1811,1829,1856,1865,1870,1876],{"__ignoreMap":757},[761,1076,1077,1081,1084,1088,1092,1095,1098,1101,1104,1107,1110],{"class":763,"line":764},[761,1078,1080],{"class":1079},"s7zQu","import",[761,1082,1083],{"class":1079}," type",[761,1085,1087],{"class":1086},"sMK4o"," {",[761,1089,1091],{"class":1090},"sTEyZ"," IncomingMessage",[761,1093,1094],{"class":1086},",",[761,1096,1097],{"class":1090}," ServerResponse",[761,1099,1100],{"class":1086}," }",[761,1102,1103],{"class":1079}," from",[761,1105,1106],{"class":1086}," '",[761,1108,1109],{"class":770},"node:http",[761,1111,1112],{"class":1086},"'\n",[761,1114,1116,1118],{"class":763,"line":1115},2,[761,1117,1080],{"class":1079},[761,1119,1120],{"class":1086}," {\n",[761,1122,1124,1127],{"class":763,"line":1123},3,[761,1125,1126],{"class":1090},"  createLoggerStorage",[761,1128,1129],{"class":1086},",\n",[761,1131,1133,1136],{"class":763,"line":1132},4,[761,1134,1135],{"class":1090},"  defineFrameworkIntegration",[761,1137,1129],{"class":1086},[761,1139,1141,1144,1147],{"class":763,"line":1140},5,[761,1142,1143],{"class":1079},"  type",[761,1145,1146],{"class":1090}," BaseEvlogOptions",[761,1148,1129],{"class":1086},[761,1150,1152,1155,1157,1159,1161],{"class":763,"line":1151},6,[761,1153,1154],{"class":1086},"}",[761,1156,1103],{"class":1079},[761,1158,1106],{"class":1086},[761,1160,481],{"class":770},[761,1162,1112],{"class":1086},[761,1164,1166,1168,1170,1172,1175,1177,1179,1181,1183],{"class":763,"line":1165},7,[761,1167,1080],{"class":1079},[761,1169,1083],{"class":1079},[761,1171,1087],{"class":1086},[761,1173,1174],{"class":1090}," RequestLogger",[761,1176,1100],{"class":1086},[761,1178,1103],{"class":1079},[761,1180,1106],{"class":1086},[761,1182,1052],{"class":770},[761,1184,1112],{"class":1086},[761,1186,1188],{"class":763,"line":1187},8,[761,1189,1191],{"emptyLinePlaceholder":1190},true,"\n",[761,1193,1195,1198,1201,1204,1207],{"class":763,"line":1194},9,[761,1196,1197],{"class":1079},"export",[761,1199,1083],{"class":1200},"spNyl",[761,1202,1203],{"class":767}," MyFrameworkEvlogOptions",[761,1205,1206],{"class":1086}," =",[761,1208,1209],{"class":767}," BaseEvlogOptions\n",[761,1211,1213],{"class":763,"line":1212},10,[761,1214,1191],{"emptyLinePlaceholder":1190},[761,1216,1218,1221,1223,1226,1228,1231,1233,1235,1239],{"class":763,"line":1217},11,[761,1219,1220],{"class":1200},"const",[761,1222,1087],{"class":1086},[761,1224,1225],{"class":1090}," storage",[761,1227,1094],{"class":1086},[761,1229,1230],{"class":1090}," useLogger ",[761,1232,1154],{"class":1086},[761,1234,1206],{"class":1086},[761,1236,1238],{"class":1237},"s2Zo4"," createLoggerStorage",[761,1240,1241],{"class":1090},"(\n",[761,1243,1245,1248,1251,1254],{"class":763,"line":1244},12,[761,1246,1247],{"class":1086},"  '",[761,1249,1250],{"class":770},"Cannot access logger outside of middleware context. Make sure evlog middleware is registered before your routes.",[761,1252,1253],{"class":1086},"'",[761,1255,1129],{"class":1086},[761,1257,1259],{"class":763,"line":1258},13,[761,1260,1261],{"class":1090},")\n",[761,1263,1265],{"class":763,"line":1264},14,[761,1266,1191],{"emptyLinePlaceholder":1190},[761,1268,1270,1272,1274,1277],{"class":763,"line":1269},15,[761,1271,1197],{"class":1079},[761,1273,1087],{"class":1086},[761,1275,1276],{"class":1090}," useLogger",[761,1278,1279],{"class":1086}," }\n",[761,1281,1283],{"class":763,"line":1282},16,[761,1284,1191],{"emptyLinePlaceholder":1190},[761,1286,1288,1290,1293,1296,1299,1302,1305,1308,1311],{"class":763,"line":1287},17,[761,1289,1220],{"class":1200},[761,1291,1292],{"class":1090}," integration ",[761,1294,1295],{"class":1086},"=",[761,1297,1298],{"class":1237}," defineFrameworkIntegration",[761,1300,1301],{"class":1086},"\u003C",[761,1303,1304],{"class":767},"IncomingMessage",[761,1306,1307],{"class":1086},">",[761,1309,1310],{"class":1090},"(",[761,1312,1313],{"class":1086},"{\n",[761,1315,1317,1321,1324,1326,1329,1331],{"class":763,"line":1316},18,[761,1318,1320],{"class":1319},"swJcz","  name",[761,1322,1323],{"class":1086},":",[761,1325,1106],{"class":1086},[761,1327,1328],{"class":770},"my-framework",[761,1330,1253],{"class":1086},[761,1332,1129],{"class":1086},[761,1334,1336,1339,1341,1344,1348,1350,1353,1355],{"class":763,"line":1335},19,[761,1337,1338],{"class":1237},"  extractRequest",[761,1340,1323],{"class":1086},[761,1342,1343],{"class":1086}," (",[761,1345,1347],{"class":1346},"sHdIc","req",[761,1349,567],{"class":1086},[761,1351,1352],{"class":1200}," =>",[761,1354,1343],{"class":1090},[761,1356,1313],{"class":1086},[761,1358,1360,1363,1365,1368,1371,1374,1377,1379,1382,1384],{"class":763,"line":1359},20,[761,1361,1362],{"class":1319},"    method",[761,1364,1323],{"class":1086},[761,1366,1367],{"class":1090}," req",[761,1369,1370],{"class":1086},".",[761,1372,1373],{"class":1090},"method ",[761,1375,1376],{"class":1086},"||",[761,1378,1106],{"class":1086},[761,1380,1381],{"class":770},"GET",[761,1383,1253],{"class":1086},[761,1385,1129],{"class":1086},[761,1387,1389,1392,1394,1396,1398,1401,1403,1405,1408,1410],{"class":763,"line":1388},21,[761,1390,1391],{"class":1319},"    path",[761,1393,1323],{"class":1086},[761,1395,1367],{"class":1090},[761,1397,1370],{"class":1086},[761,1399,1400],{"class":1090},"url ",[761,1402,1376],{"class":1086},[761,1404,1106],{"class":1086},[761,1406,1407],{"class":770},"\u002F",[761,1409,1253],{"class":1086},[761,1411,1129],{"class":1086},[761,1413,1415,1418,1420,1422,1424,1427],{"class":763,"line":1414},22,[761,1416,1417],{"class":1319},"    headers",[761,1419,1323],{"class":1086},[761,1421,1367],{"class":1090},[761,1423,1370],{"class":1086},[761,1425,1426],{"class":1090},"headers",[761,1428,1129],{"class":1086},[761,1430,1432,1435,1437,1440,1442,1444,1447,1449,1452,1454,1457,1460,1462,1465],{"class":763,"line":1431},23,[761,1433,1434],{"class":1319},"    requestId",[761,1436,1323],{"class":1086},[761,1438,1439],{"class":1086}," typeof",[761,1441,1367],{"class":1090},[761,1443,1370],{"class":1086},[761,1445,1446],{"class":1090},"headers[",[761,1448,1253],{"class":1086},[761,1450,1451],{"class":770},"x-request-id",[761,1453,1253],{"class":1086},[761,1455,1456],{"class":1090},"] ",[761,1458,1459],{"class":1086},"===",[761,1461,1106],{"class":1086},[761,1463,1464],{"class":770},"string",[761,1466,1112],{"class":1086},[761,1468,1470,1473,1475,1477,1479,1481,1483,1485],{"class":763,"line":1469},24,[761,1471,1472],{"class":1086},"      ?",[761,1474,1367],{"class":1090},[761,1476,1370],{"class":1086},[761,1478,1446],{"class":1090},[761,1480,1253],{"class":1086},[761,1482,1451],{"class":770},[761,1484,1253],{"class":1086},[761,1486,1487],{"class":1090},"]\n",[761,1489,1491,1494],{"class":763,"line":1490},25,[761,1492,1493],{"class":1086},"      :",[761,1495,1496],{"class":1086}," undefined,\n",[761,1498,1500,1503,1505],{"class":763,"line":1499},26,[761,1501,1502],{"class":1086},"  }",[761,1504,567],{"class":1090},[761,1506,1129],{"class":1086},[761,1508,1510,1513,1515,1517,1519,1521,1524,1526,1528],{"class":763,"line":1509},27,[761,1511,1512],{"class":1237},"  attachLogger",[761,1514,1323],{"class":1086},[761,1516,1343],{"class":1086},[761,1518,1347],{"class":1346},[761,1520,1094],{"class":1086},[761,1522,1523],{"class":1346}," logger",[761,1525,567],{"class":1086},[761,1527,1352],{"class":1200},[761,1529,1120],{"class":1086},[761,1531,1533,1536,1538,1541,1543,1546,1548,1551,1553,1555,1557,1559,1561,1564,1566],{"class":763,"line":1532},28,[761,1534,1535],{"class":1319},"    (",[761,1537,1347],{"class":1090},[761,1539,1540],{"class":1079}," as",[761,1542,1091],{"class":767},[761,1544,1545],{"class":1086}," &",[761,1547,1087],{"class":1086},[761,1549,1550],{"class":1319}," log",[761,1552,1323],{"class":1086},[761,1554,1174],{"class":767},[761,1556,1100],{"class":1086},[761,1558,567],{"class":1319},[761,1560,1370],{"class":1086},[761,1562,1563],{"class":1090},"log",[761,1565,1206],{"class":1086},[761,1567,1568],{"class":1090}," logger\n",[761,1570,1572],{"class":763,"line":1571},29,[761,1573,1574],{"class":1086},"  },\n",[761,1576,1578,1581],{"class":763,"line":1577},30,[761,1579,1580],{"class":1090},"  storage",[761,1582,1129],{"class":1086},[761,1584,1586,1588],{"class":763,"line":1585},31,[761,1587,1154],{"class":1086},[761,1589,1261],{"class":1090},[761,1591,1593],{"class":763,"line":1592},32,[761,1594,1191],{"emptyLinePlaceholder":1190},[761,1596,1598,1600,1603,1606,1608,1611,1613,1615,1617,1620],{"class":763,"line":1597},33,[761,1599,1197],{"class":1079},[761,1601,1602],{"class":1200}," function",[761,1604,1605],{"class":1237}," evlog",[761,1607,1310],{"class":1086},[761,1609,1610],{"class":1346},"options",[761,1612,1323],{"class":1086},[761,1614,1203],{"class":767},[761,1616,1206],{"class":1086},[761,1618,1619],{"class":1086}," {})",[761,1621,1120],{"class":1086},[761,1623,1625,1628,1631,1633,1635,1637,1639,1641,1644,1646,1648,1650,1653,1655,1658,1660,1663,1665,1668,1671,1673],{"class":763,"line":1624},34,[761,1626,1627],{"class":1079},"  return",[761,1629,1630],{"class":1200}," async",[761,1632,1343],{"class":1086},[761,1634,1347],{"class":1346},[761,1636,1323],{"class":1086},[761,1638,1091],{"class":767},[761,1640,1094],{"class":1086},[761,1642,1643],{"class":1346}," res",[761,1645,1323],{"class":1086},[761,1647,1097],{"class":767},[761,1649,1094],{"class":1086},[761,1651,1652],{"class":1237}," next",[761,1654,1323],{"class":1086},[761,1656,1657],{"class":1086}," ()",[761,1659,1352],{"class":1200},[761,1661,1662],{"class":767}," Promise",[761,1664,1301],{"class":1086},[761,1666,1667],{"class":767},"void",[761,1669,1670],{"class":1086},">)",[761,1672,1352],{"class":1200},[761,1674,1120],{"class":1086},[761,1676,1678,1681,1683,1686,1688,1691,1693,1696,1698,1700,1703,1705,1708,1710,1712,1714,1716],{"class":763,"line":1677},35,[761,1679,1680],{"class":1200},"    const",[761,1682,1087],{"class":1086},[761,1684,1685],{"class":1090}," skipped",[761,1687,1094],{"class":1086},[761,1689,1690],{"class":1090}," finish",[761,1692,1094],{"class":1086},[761,1694,1695],{"class":1090}," runWith",[761,1697,1100],{"class":1086},[761,1699,1206],{"class":1086},[761,1701,1702],{"class":1090}," integration",[761,1704,1370],{"class":1086},[761,1706,1707],{"class":1237},"start",[761,1709,1310],{"class":1319},[761,1711,1347],{"class":1090},[761,1713,1094],{"class":1086},[761,1715,713],{"class":1090},[761,1717,1261],{"class":1319},[761,1719,1721,1724,1726,1728,1731],{"class":763,"line":1720},36,[761,1722,1723],{"class":1079},"    if",[761,1725,1343],{"class":1319},[761,1727,653],{"class":1090},[761,1729,1730],{"class":1319},") ",[761,1732,1313],{"class":1086},[761,1734,1736,1739,1741],{"class":763,"line":1735},37,[761,1737,1738],{"class":1079},"      await",[761,1740,1652],{"class":1237},[761,1742,1743],{"class":1319},"()\n",[761,1745,1747],{"class":763,"line":1746},38,[761,1748,1749],{"class":1079},"      return\n",[761,1751,1753],{"class":763,"line":1752},39,[761,1754,1755],{"class":1086},"    }\n",[761,1757,1759,1762],{"class":763,"line":1758},40,[761,1760,1761],{"class":1079},"    try",[761,1763,1120],{"class":1086},[761,1765,1767,1769,1771,1773,1776,1778,1780],{"class":763,"line":1766},41,[761,1768,1738],{"class":1079},[761,1770,1695],{"class":1237},[761,1772,1310],{"class":1319},[761,1774,1775],{"class":1086},"()",[761,1777,1352],{"class":1200},[761,1779,1652],{"class":1237},[761,1781,1782],{"class":1319},"())\n",[761,1784,1786,1788,1790,1792,1795,1798,1800,1802,1804,1807,1809],{"class":763,"line":1785},42,[761,1787,1738],{"class":1079},[761,1789,1690],{"class":1237},[761,1791,1310],{"class":1319},[761,1793,1794],{"class":1086},"{",[761,1796,1797],{"class":1319}," status",[761,1799,1323],{"class":1086},[761,1801,1643],{"class":1090},[761,1803,1370],{"class":1086},[761,1805,1806],{"class":1090},"statusCode",[761,1808,1100],{"class":1086},[761,1810,1261],{"class":1319},[761,1812,1814,1817,1820,1822,1825,1827],{"class":763,"line":1813},43,[761,1815,1816],{"class":1086},"    }",[761,1818,1819],{"class":1079}," catch",[761,1821,1343],{"class":1319},[761,1823,1824],{"class":1090},"error",[761,1826,1730],{"class":1319},[761,1828,1313],{"class":1086},[761,1830,1832,1834,1836,1838,1840,1843,1845,1847,1849,1852,1854],{"class":763,"line":1831},44,[761,1833,1738],{"class":1079},[761,1835,1690],{"class":1237},[761,1837,1310],{"class":1319},[761,1839,1794],{"class":1086},[761,1841,1842],{"class":1319}," error",[761,1844,1323],{"class":1086},[761,1846,1842],{"class":1090},[761,1848,1540],{"class":1079},[761,1850,1851],{"class":767}," Error",[761,1853,1100],{"class":1086},[761,1855,1261],{"class":1319},[761,1857,1859,1862],{"class":763,"line":1858},45,[761,1860,1861],{"class":1079},"      throw",[761,1863,1864],{"class":1090}," error\n",[761,1866,1868],{"class":763,"line":1867},46,[761,1869,1755],{"class":1086},[761,1871,1873],{"class":763,"line":1872},47,[761,1874,1875],{"class":1086},"  }\n",[761,1877,1879],{"class":763,"line":1878},48,[761,1880,1881],{"class":1086},"}\n",[471,1883,1884,1885,1887],{},"That's it. This middleware gets every feature for free: route filtering, drain adapters, enrichers, tail sampling, error capture, plugin lifecycle hooks, ",[475,1886,675],{},", and duration tracking.",[1889,1890,1892,1893,1895],"h3",{"id":1891},"what-defineframeworkintegration-does","What ",[475,1894,604],{}," does",[471,1897,1898],{},"Given the manifest above, the helper:",[1900,1901,1902,1911,1922,1928,1932,1942],"ol",{},[596,1903,1904,1905,1907,1908,1910],{},"Normalizes headers (auto-detects ",[475,1906,629],{}," vs ",[475,1909,633],{},").",[596,1912,1913,1914,1917,1918,1921],{},"Generates a ",[475,1915,1916],{},"requestId"," if ",[475,1919,1920],{},"extractRequest"," doesn't return one.",[596,1923,1924,1925,1927],{},"Calls ",[475,1926,974],{}," with the merged options.",[596,1929,1924,1930,1370],{},[475,1931,619],{},[596,1933,1934,1935,1937,1938,1941],{},"Attaches ",[475,1936,675],{}," to the logger when ",[475,1939,1940],{},"storage"," is provided (so users can spawn correlated background work).",[596,1943,1944,1945,1948,1949,1952,1953,1956,1957,1370],{},"Exposes ",[475,1946,1947],{},"runWith(fn)"," — runs ",[475,1950,1951],{},"fn()"," inside ",[475,1954,1955],{},"storage.run(logger, …)"," if storage is configured, otherwise just calls ",[475,1958,1951],{},[471,1960,1961],{},"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.",[743,1963,1965],{"id":1964},"custom-mode","Custom mode",[471,1967,1968,1969,1971,1972,1974,1975,1977],{},"If your framework's lifecycle doesn't fit a clean ",[475,1970,543],{}," shape (NestJS interceptors, Next.js App Router, SvelteKit ",[475,1973,566],{},"), drop one level lower and call ",[475,1976,974],{}," directly:",[751,1979,1981],{"className":1069,"code":1980,"language":1072,"meta":757,"style":757},"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,1982,1983,2007,2011,2038,2045,2052,2059,2073,2082],{"__ignoreMap":757},[761,1984,1985,1987,1989,1992,1994,1997,1999,2001,2003,2005],{"class":763,"line":764},[761,1986,1080],{"class":1079},[761,1988,1087],{"class":1086},[761,1990,1991],{"class":1090}," createMiddlewareLogger",[761,1993,1094],{"class":1086},[761,1995,1996],{"class":1090}," extractSafeNodeHeaders",[761,1998,1100],{"class":1086},[761,2000,1103],{"class":1079},[761,2002,1106],{"class":1086},[761,2004,481],{"class":770},[761,2006,1112],{"class":1086},[761,2008,2009],{"class":763,"line":1115},[761,2010,1191],{"emptyLinePlaceholder":1190},[761,2012,2013,2015,2017,2019,2021,2023,2025,2028,2030,2032,2034,2036],{"class":763,"line":1123},[761,2014,1220],{"class":1200},[761,2016,1087],{"class":1086},[761,2018,1523],{"class":1090},[761,2020,1094],{"class":1086},[761,2022,1690],{"class":1090},[761,2024,1094],{"class":1086},[761,2026,2027],{"class":1090}," skipped ",[761,2029,1154],{"class":1086},[761,2031,1206],{"class":1086},[761,2033,1991],{"class":1237},[761,2035,1310],{"class":1090},[761,2037,1313],{"class":1086},[761,2039,2040,2043],{"class":763,"line":1132},[761,2041,2042],{"class":1090},"  method",[761,2044,1129],{"class":1086},[761,2046,2047,2050],{"class":763,"line":1140},[761,2048,2049],{"class":1090},"  path",[761,2051,1129],{"class":1086},[761,2053,2054,2057],{"class":763,"line":1151},[761,2055,2056],{"class":1090},"  requestId",[761,2058,1129],{"class":1086},[761,2060,2061,2064,2066,2068,2071],{"class":763,"line":1165},[761,2062,2063],{"class":1319},"  headers",[761,2065,1323],{"class":1086},[761,2067,1996],{"class":1237},[761,2069,2070],{"class":1090},"(rawHeaders)",[761,2072,1129],{"class":1086},[761,2074,2075,2078,2080],{"class":763,"line":1187},[761,2076,2077],{"class":1086},"  ...",[761,2079,1610],{"class":1090},[761,2081,1129],{"class":1086},[761,2083,2084,2086],{"class":763,"line":1194},[761,2085,1154],{"class":1086},[761,2087,1261],{"class":1090},[471,2089,2090,2091,2094,2095,2097,2098,2101],{},"You'll be responsible for ALS wrapping (",[475,2092,2093],{},"storage.run","), ",[475,2096,675],{}," attachment (via ",[475,2099,2100],{},"attachForkToLogger","), and finishing the lifecycle — but you keep the full pipeline (route filtering, sampling, emit, enrich, drain, plugins) for free.",[743,2103,2105],{"id":2104},"serverless-workers-edge","Serverless (Workers \u002F Edge)",[471,2107,2108,2109,2111,2112,2117],{},"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,2110,719],{}," so enrich still runs inline but drain work survives after the response — the same behavior as ",[529,2113,2114],{"href":223},[475,2115,2116],{},"evlog\u002Fworkers"," and the Nitro plugin.",[471,2119,2120,2122,2123,2125],{},[487,2121,1965],{}," — pass ",[475,2124,719],{}," per request:",[751,2127,2129],{"className":1069,"code":2128,"language":1072,"meta":757,"style":757},"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,2130,2131,2151,2160,2164,2190,2196,2202,2208,2220,2230,2238],{"__ignoreMap":757},[761,2132,2133,2135,2137,2140,2142,2144,2146,2149],{"class":763,"line":764},[761,2134,1080],{"class":1079},[761,2136,1087],{"class":1086},[761,2138,2139],{"class":1090}," waitUntil",[761,2141,1100],{"class":1086},[761,2143,1103],{"class":1079},[761,2145,1106],{"class":1086},[761,2147,2148],{"class":770},"@vercel\u002Ffunctions",[761,2150,1112],{"class":1086},[761,2152,2153,2157],{"class":763,"line":1115},[761,2154,2156],{"class":2155},"sHwdD","\u002F\u002F import { waitUntil } from 'cloudflare:workers'",[761,2158,2159],{"class":2155}," \u002F\u002F Vercel-style global on some runtimes\n",[761,2161,2162],{"class":763,"line":1123},[761,2163,1191],{"emptyLinePlaceholder":1190},[761,2165,2166,2168,2170,2172,2174,2176,2178,2180,2182,2184,2186,2188],{"class":763,"line":1132},[761,2167,1220],{"class":1200},[761,2169,1087],{"class":1086},[761,2171,1523],{"class":1090},[761,2173,1094],{"class":1086},[761,2175,1690],{"class":1090},[761,2177,1094],{"class":1086},[761,2179,2027],{"class":1090},[761,2181,1154],{"class":1086},[761,2183,1206],{"class":1086},[761,2185,1991],{"class":1237},[761,2187,1310],{"class":1090},[761,2189,1313],{"class":1086},[761,2191,2192,2194],{"class":763,"line":1140},[761,2193,2042],{"class":1090},[761,2195,1129],{"class":1086},[761,2197,2198,2200],{"class":763,"line":1151},[761,2199,2049],{"class":1090},[761,2201,1129],{"class":1086},[761,2203,2204,2206],{"class":763,"line":1165},[761,2205,2056],{"class":1090},[761,2207,1129],{"class":1086},[761,2209,2210,2212,2214,2216,2218],{"class":763,"line":1187},[761,2211,2063],{"class":1319},[761,2213,1323],{"class":1086},[761,2215,1996],{"class":1237},[761,2217,2070],{"class":1090},[761,2219,1129],{"class":1086},[761,2221,2222,2225,2227],{"class":763,"line":1194},[761,2223,2224],{"class":1090},"  waitUntil",[761,2226,1094],{"class":1086},[761,2228,2229],{"class":2155}," \u002F\u002F or ctx.waitUntil.bind(ctx) on Cloudflare\n",[761,2231,2232,2234,2236],{"class":763,"line":1212},[761,2233,2077],{"class":1086},[761,2235,1610],{"class":1090},[761,2237,1129],{"class":1086},[761,2239,2240,2242],{"class":763,"line":1217},[761,2241,1154],{"class":1086},[761,2243,1261],{"class":1090},[471,2245,2246,2249,2250,2252,2253,2255,2256,2258],{},[487,2247,2248],{},"Manifest mode"," — either pass ",[475,2251,719],{}," in ",[475,2254,643],{}," or declare ",[475,2257,723],{}," on the manifest when the hook lives on the framework context:",[751,2260,2262],{"className":1069,"code":2261,"language":1072,"meta":757,"style":757},"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,2263,2264,2285,2299,2327,2352,2390,2396,2400,2422,2442,2478,2483,2488,2493,2497],{"__ignoreMap":757},[761,2265,2266,2268,2270,2272,2274,2276,2279,2281,2283],{"class":763,"line":764},[761,2267,1220],{"class":1200},[761,2269,1292],{"class":1090},[761,2271,1295],{"class":1086},[761,2273,1298],{"class":1237},[761,2275,1301],{"class":1086},[761,2277,2278],{"class":767},"WorkerContext",[761,2280,1307],{"class":1086},[761,2282,1310],{"class":1090},[761,2284,1313],{"class":1086},[761,2286,2287,2289,2291,2293,2295,2297],{"class":763,"line":1115},[761,2288,1320],{"class":1319},[761,2290,1323],{"class":1086},[761,2292,1106],{"class":1086},[761,2294,1328],{"class":770},[761,2296,1253],{"class":1086},[761,2298,1129],{"class":1086},[761,2300,2301,2303,2305,2307,2310,2312,2314,2316,2318,2321,2323,2325],{"class":763,"line":1123},[761,2302,1338],{"class":1237},[761,2304,1323],{"class":1086},[761,2306,1343],{"class":1086},[761,2308,2309],{"class":1346},"ctx",[761,2311,567],{"class":1086},[761,2313,1352],{"class":1200},[761,2315,1343],{"class":1090},[761,2317,1794],{"class":1086},[761,2319,2320],{"class":2155}," \u002F* … *\u002F",[761,2322,1100],{"class":1086},[761,2324,567],{"class":1090},[761,2326,1129],{"class":1086},[761,2328,2329,2331,2333,2335,2337,2339,2341,2343,2345,2347,2349],{"class":763,"line":1132},[761,2330,1512],{"class":1237},[761,2332,1323],{"class":1086},[761,2334,1343],{"class":1086},[761,2336,2309],{"class":1346},[761,2338,1094],{"class":1086},[761,2340,1523],{"class":1346},[761,2342,567],{"class":1086},[761,2344,1352],{"class":1200},[761,2346,1087],{"class":1086},[761,2348,2320],{"class":2155},[761,2350,2351],{"class":1086}," },\n",[761,2353,2354,2357,2359,2362,2364,2366,2368,2371,2373,2375,2377,2380,2383,2385,2388],{"class":763,"line":1140},[761,2355,2356],{"class":1237},"  extractWaitUntil",[761,2358,1323],{"class":1086},[761,2360,2361],{"class":1346}," ctx",[761,2363,1352],{"class":1200},[761,2365,2361],{"class":1090},[761,2367,1370],{"class":1086},[761,2369,2370],{"class":1090},"executionCtx",[761,2372,1370],{"class":1086},[761,2374,719],{"class":1090},[761,2376,1370],{"class":1086},[761,2378,2379],{"class":1237},"bind",[761,2381,2382],{"class":1090},"(ctx",[761,2384,1370],{"class":1086},[761,2386,2387],{"class":1090},"executionCtx)",[761,2389,1129],{"class":1086},[761,2391,2392,2394],{"class":763,"line":1151},[761,2393,1154],{"class":1086},[761,2395,1261],{"class":1090},[761,2397,2398],{"class":763,"line":1165},[761,2399,1191],{"emptyLinePlaceholder":1190},[761,2401,2402,2404,2406,2408,2410,2412,2414,2416,2418,2420],{"class":763,"line":1187},[761,2403,1197],{"class":1079},[761,2405,1602],{"class":1200},[761,2407,1605],{"class":1237},[761,2409,1310],{"class":1086},[761,2411,1610],{"class":1346},[761,2413,1323],{"class":1086},[761,2415,1146],{"class":767},[761,2417,1206],{"class":1086},[761,2419,1619],{"class":1086},[761,2421,1120],{"class":1086},[761,2423,2424,2426,2428,2430,2432,2434,2436,2438,2440],{"class":763,"line":1194},[761,2425,1627],{"class":1079},[761,2427,1630],{"class":1200},[761,2429,1343],{"class":1086},[761,2431,2309],{"class":1346},[761,2433,1094],{"class":1086},[761,2435,1652],{"class":1346},[761,2437,567],{"class":1086},[761,2439,1352],{"class":1200},[761,2441,1120],{"class":1086},[761,2443,2444,2446,2448,2450,2452,2454,2456,2458,2460,2462,2464,2466,2468,2470,2472,2474,2476],{"class":763,"line":1212},[761,2445,1680],{"class":1200},[761,2447,1087],{"class":1086},[761,2449,1685],{"class":1090},[761,2451,1094],{"class":1086},[761,2453,1690],{"class":1090},[761,2455,1094],{"class":1086},[761,2457,1695],{"class":1090},[761,2459,1100],{"class":1086},[761,2461,1206],{"class":1086},[761,2463,1702],{"class":1090},[761,2465,1370],{"class":1086},[761,2467,1707],{"class":1237},[761,2469,1310],{"class":1319},[761,2471,2309],{"class":1090},[761,2473,1094],{"class":1086},[761,2475,713],{"class":1090},[761,2477,1261],{"class":1319},[761,2479,2480],{"class":763,"line":1217},[761,2481,2482],{"class":2155},"    \u002F\u002F Per-request override still works:\n",[761,2484,2485],{"class":763,"line":1244},[761,2486,2487],{"class":2155},"    \u002F\u002F integration.start(ctx, { ...options, waitUntil: ctx.executionCtx.waitUntil.bind(ctx.executionCtx) })\n",[761,2489,2490],{"class":763,"line":1258},[761,2491,2492],{"class":2155},"    \u002F\u002F …\n",[761,2494,2495],{"class":763,"line":1264},[761,2496,1875],{"class":1086},[761,2498,2499],{"class":763,"line":1269},[761,2500,1881],{"class":1086},[471,2502,2503,2504,2507,2508,2510],{},"Per-request ",[475,2505,2506],{},"options.waitUntil"," takes precedence over ",[475,2509,723],{},". Without either, drains are awaited (correct for traditional Node.js servers).",[743,2512,2514],{"id":2513},"non-http-runtimes","Non-HTTP runtimes",[471,2516,2517,2518,605,2520,1977],{},"For queue workers, CLI drivers, cron jobs, or durable execution engines, skip the HTTP-shaped helpers and use ",[475,2519,730],{},[475,2521,481],{},[751,2523,2527],{"className":2524,"code":2525,"language":2526,"meta":757,"style":757},"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,2528,2529,2548,2552,2576,2591,2607,2645,2651,2655,2662,2676,2705,2720,2734,2742,2751,2764,2768],{"__ignoreMap":757},[761,2530,2531,2533,2535,2538,2540,2542,2544,2546],{"class":763,"line":764},[761,2532,1080],{"class":1079},[761,2534,1087],{"class":1086},[761,2536,2537],{"class":1090}," createRequestLogger",[761,2539,1100],{"class":1086},[761,2541,1103],{"class":1079},[761,2543,1106],{"class":1086},[761,2545,481],{"class":770},[761,2547,1112],{"class":1086},[761,2549,2550],{"class":763,"line":1115},[761,2551,1191],{"emptyLinePlaceholder":1190},[761,2553,2554,2557,2559,2562,2564,2567,2569,2572,2574],{"class":763,"line":1123},[761,2555,2556],{"class":1200},"async",[761,2558,1602],{"class":1200},[761,2560,2561],{"class":1237}," processJob",[761,2563,1310],{"class":1086},[761,2565,2566],{"class":1346},"job",[761,2568,1323],{"class":1086},[761,2570,2571],{"class":767}," Job",[761,2573,567],{"class":1086},[761,2575,1120],{"class":1086},[761,2577,2578,2581,2583,2585,2587,2589],{"class":763,"line":1132},[761,2579,2580],{"class":1200},"  const",[761,2582,1523],{"class":1090},[761,2584,1206],{"class":1086},[761,2586,2537],{"class":1237},[761,2588,1310],{"class":1319},[761,2590,1313],{"class":1086},[761,2592,2593,2596,2598,2600,2603,2605],{"class":763,"line":1140},[761,2594,2595],{"class":1319},"    service",[761,2597,1323],{"class":1086},[761,2599,1106],{"class":1086},[761,2601,2602],{"class":770},"jobs",[761,2604,1253],{"class":1086},[761,2606,1129],{"class":1086},[761,2608,2609,2612,2614,2616,2619,2621,2624,2626,2629,2631,2634,2636,2638,2640,2643],{"class":763,"line":1151},[761,2610,2611],{"class":1319},"    context",[761,2613,1323],{"class":1086},[761,2615,1087],{"class":1086},[761,2617,2618],{"class":1319}," jobId",[761,2620,1323],{"class":1086},[761,2622,2623],{"class":1090}," job",[761,2625,1370],{"class":1086},[761,2627,2628],{"class":1090},"id",[761,2630,1094],{"class":1086},[761,2632,2633],{"class":1319}," queue",[761,2635,1323],{"class":1086},[761,2637,2623],{"class":1090},[761,2639,1370],{"class":1086},[761,2641,2642],{"class":1090},"queue",[761,2644,2351],{"class":1086},[761,2646,2647,2649],{"class":763,"line":1165},[761,2648,1502],{"class":1086},[761,2650,1261],{"class":1319},[761,2652,2653],{"class":763,"line":1187},[761,2654,1191],{"emptyLinePlaceholder":1190},[761,2656,2657,2660],{"class":763,"line":1194},[761,2658,2659],{"class":1079},"  try",[761,2661,1120],{"class":1086},[761,2663,2664,2667,2670,2672,2674],{"class":763,"line":1212},[761,2665,2666],{"class":1079},"    await",[761,2668,2669],{"class":1237}," runJob",[761,2671,1310],{"class":1319},[761,2673,2566],{"class":1090},[761,2675,1261],{"class":1319},[761,2677,2678,2681,2683,2686,2688,2690,2692,2694,2696,2699,2701,2703],{"class":763,"line":1217},[761,2679,2680],{"class":1090},"    logger",[761,2682,1370],{"class":1086},[761,2684,2685],{"class":1237},"set",[761,2687,1310],{"class":1319},[761,2689,1794],{"class":1086},[761,2691,1797],{"class":1319},[761,2693,1323],{"class":1086},[761,2695,1106],{"class":1086},[761,2697,2698],{"class":770},"success",[761,2700,1253],{"class":1086},[761,2702,1100],{"class":1086},[761,2704,1261],{"class":1319},[761,2706,2707,2709,2711,2713,2716,2718],{"class":763,"line":1244},[761,2708,1502],{"class":1086},[761,2710,1819],{"class":1079},[761,2712,1343],{"class":1319},[761,2714,2715],{"class":1090},"err",[761,2717,1730],{"class":1319},[761,2719,1313],{"class":1086},[761,2721,2722,2724,2726,2728,2730,2732],{"class":763,"line":1258},[761,2723,2680],{"class":1090},[761,2725,1370],{"class":1086},[761,2727,1824],{"class":1237},[761,2729,1310],{"class":1319},[761,2731,2715],{"class":1090},[761,2733,1261],{"class":1319},[761,2735,2736,2739],{"class":763,"line":1264},[761,2737,2738],{"class":1079},"    throw",[761,2740,2741],{"class":1090}," err\n",[761,2743,2744,2746,2749],{"class":763,"line":1269},[761,2745,1502],{"class":1086},[761,2747,2748],{"class":1079}," finally",[761,2750,1120],{"class":1086},[761,2752,2753,2755,2757,2759,2762],{"class":763,"line":1282},[761,2754,2666],{"class":1079},[761,2756,1523],{"class":1090},[761,2758,1370],{"class":1086},[761,2760,2761],{"class":1237},"emit",[761,2763,1743],{"class":1319},[761,2765,2766],{"class":763,"line":1287},[761,2767,1875],{"class":1086},[761,2769,2770],{"class":763,"line":1316},[761,2771,1881],{"class":1086},[471,2773,2774,2775,2778],{},"Same enrichers, same drain hook, same ",[529,2776,2777],{"href":421},"identity headers"," on outbound HTTP drain requests — only the entry point shape changes.",[743,2780,2782],{"id":2781},"reference-implementations","Reference implementations",[471,2784,2785],{},"Study these built-in integrations for framework-specific patterns:",[502,2787,2788,2804],{},[505,2789,2790],{},[508,2791,2792,2795,2798,2801],{},[511,2793,2794],{},"Framework",[511,2796,2797],{},"Lines",[511,2799,2800],{},"Mode",[511,2802,2803],{},"Source",[521,2805,2806,2823,2839,2856,2873,2890],{},[508,2807,2808,2810,2813,2816],{},[526,2809,202],{},[526,2811,2812],{},"~50",[526,2814,2815],{},"manifest",[526,2817,2818],{},[529,2819,2822],{"href":2820,"rel":2821},"https:\u002F\u002Fgithub.com\u002Fhugorcd\u002Fevlog\u002Fblob\u002Fmain\u002Fpackages\u002Fevlog\u002Fsrc\u002Fhono\u002Findex.ts",[741],"hono\u002Findex.ts",[508,2824,2825,2827,2829,2832],{},[526,2826,197],{},[526,2828,2812],{},[526,2830,2831],{},"manifest + ALS",[526,2833,2834],{},[529,2835,2838],{"href":2836,"rel":2837},"https:\u002F\u002Fgithub.com\u002Fhugorcd\u002Fevlog\u002Fblob\u002Fmain\u002Fpackages\u002Fevlog\u002Fsrc\u002Fexpress\u002Findex.ts",[741],"express\u002Findex.ts",[508,2840,2841,2843,2846,2849],{},[526,2842,207],{},[526,2844,2845],{},"~70",[526,2847,2848],{},"manifest + Fastify hooks",[526,2850,2851],{},[529,2852,2855],{"href":2853,"rel":2854},"https:\u002F\u002Fgithub.com\u002Fhugorcd\u002Fevlog\u002Fblob\u002Fmain\u002Fpackages\u002Fevlog\u002Fsrc\u002Ffastify\u002Findex.ts",[741],"fastify\u002Findex.ts",[508,2857,2858,2860,2863,2866],{},[526,2859,212],{},[526,2861,2862],{},"~80",[526,2864,2865],{},"manifest + custom ALS scoping",[526,2867,2868],{},[529,2869,2872],{"href":2870,"rel":2871},"https:\u002F\u002Fgithub.com\u002Fhugorcd\u002Fevlog\u002Fblob\u002Fmain\u002Fpackages\u002Fevlog\u002Fsrc\u002Felysia\u002Findex.ts",[741],"elysia\u002Findex.ts",[508,2874,2875,2877,2880,2883],{},[526,2876,192],{},[526,2878,2879],{},"~120",[526,2881,2882],{},"custom (interceptor)",[526,2884,2885],{},[529,2886,2889],{"href":2887,"rel":2888},"https:\u002F\u002Fgithub.com\u002Fhugorcd\u002Fevlog\u002Fblob\u002Fmain\u002Fpackages\u002Fevlog\u002Fsrc\u002Fnestjs\u002F",[741],"nestjs\u002F",[508,2891,2892,2894,2897,2903],{},[526,2893,177],{},[526,2895,2896],{},"~90",[526,2898,2899,2900,2902],{},"custom (",[475,2901,566],{}," hook)",[526,2904,2905],{},[529,2906,2909],{"href":2907,"rel":2908},"https:\u002F\u002Fgithub.com\u002Fhugorcd\u002Fevlog\u002Fblob\u002Fmain\u002Fpackages\u002Fevlog\u002Fsrc\u002Fsveltekit\u002F",[741],"sveltekit\u002F",[492,2911,2914,2915,2920],{"color":2912,"icon":2913},"neutral","i-lucide-heart","Built an integration for a framework we don't support? ",[529,2916,2919],{"href":2917,"rel":2918},"https:\u002F\u002Fgithub.com\u002Fhugorcd\u002Fevlog\u002Fpulls",[741],"Open a PR"," — the community will thank you.",[743,2922,2924],{"id":2923},"next-steps","Next steps",[593,2926,2927,2933,2939,2944,2949,2954],{},[596,2928,2929,2932],{},[529,2930,2931],{"href":426},"Custom Drains"," — same toolkit shape for drain destinations",[596,2934,2935,2938],{},[529,2936,2937],{"href":413},"Custom Enrichers"," — same toolkit shape for derived event fields",[596,2940,2941,2943],{},[529,2942,408],{"href":409}," — multi-hook extensions (drain + enrich + keep in one object)",[596,2945,2946,2948],{},[529,2947,46],{"href":47}," — design comprehensive events with context layering",[596,2950,2951,2953],{},[529,2952,61],{"href":62}," — control log volume with head and tail sampling",[596,2955,2956,2958],{},[529,2957,90],{"href":95}," — send logs to Axiom, Sentry, PostHog, and more",[2960,2961,2962],"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 .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}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}",{"title":757,"searchDepth":1115,"depth":1115,"links":2964},[2965,2966,2967,2971,2972,2973,2974,2975],{"id":745,"depth":1115,"text":746},{"id":820,"depth":1115,"text":821},{"id":1056,"depth":1115,"text":1057,"children":2968},[2969],{"id":1891,"depth":1123,"text":2970},"What defineFrameworkIntegration does",{"id":1964,"depth":1115,"text":1965},{"id":2104,"depth":1115,"text":2105},{"id":2513,"depth":1115,"text":2514},{"id":2781,"depth":1115,"text":2782},{"id":2923,"depth":1115,"text":2924},"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",[2979,2981],{"label":2931,"icon":428,"to":426,"color":2912,"variant":2980},"subtle",{"label":2937,"icon":373,"to":413,"color":2912,"variant":2980},{},{"title":394,"icon":397},{"title":466,"description":2976},"n5YeMrPt-2_Kdq3rbW4NKlzFNeZyBEVYkcK-dHN7ZlQ",[2987,2989],{"title":389,"path":390,"stem":391,"description":2988,"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":2990,"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.",1784213444062]