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