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