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