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