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