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