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