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