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