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