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