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