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