[{"data":1,"prerenderedAt":2038},["ShallowReactive",2],{"navigation_docs":3,"-extend-plugins":538,"-extend-plugins-surround":2033},[4,30,80,128,308,440,499],{"title":5,"path":6,"stem":7,"children":8,"page":29},"Start","\u002Fstart","1.start",[9,14,19,24],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","\u002Fstart\u002Fintroduction","1.start\u002F1.introduction","i-lucide-info",{"title":15,"path":16,"stem":17,"icon":18},"Why start with evlog","\u002Fstart\u002Fwhy-evlog","1.start\u002F2.why-evlog","i-lucide-rocket",{"title":20,"path":21,"stem":22,"icon":23},"Installation","\u002Fstart\u002Finstallation","1.start\u002F3.installation","i-lucide-download",{"title":25,"path":26,"stem":27,"icon":28},"Quick Start","\u002Fstart\u002Fquick-start","1.start\u002F4.quick-start","i-lucide-zap",false,{"title":31,"path":32,"stem":33,"children":34,"page":29},"Learn","\u002Flearn","2.learn",[35,40,45,50,55,60,65,70,75],{"title":36,"path":37,"stem":38,"icon":39},"Overview","\u002Flearn\u002Foverview","2.learn\u002F0.overview","i-lucide-list",{"title":41,"path":42,"stem":43,"icon":44},"Simple Logging","\u002Flearn\u002Fsimple-logging","2.learn\u002F1.simple-logging","i-lucide-terminal",{"title":46,"path":47,"stem":48,"icon":49},"Wide Events","\u002Flearn\u002Fwide-events","2.learn\u002F2.wide-events","i-lucide-layers",{"title":51,"path":52,"stem":53,"icon":54},"Structured Errors","\u002Flearn\u002Fstructured-errors","2.learn\u002F3.structured-errors","i-lucide-shield-alert",{"title":56,"path":57,"stem":58,"icon":59},"Lifecycle","\u002Flearn\u002Flifecycle","2.learn\u002F4.lifecycle","i-lucide-arrow-right-left",{"title":61,"path":62,"stem":63,"icon":64},"Sampling","\u002Flearn\u002Fsampling","2.learn\u002F5.sampling","i-lucide-filter",{"title":66,"path":67,"stem":68,"icon":69},"Auto-Redaction","\u002Flearn\u002Fredaction","2.learn\u002F6.redaction","i-lucide-eye-off",{"title":71,"path":72,"stem":73,"icon":74},"Typed Fields","\u002Flearn\u002Ftyped-fields","2.learn\u002F7.typed-fields","i-simple-icons-typescript",{"title":76,"path":77,"stem":78,"icon":79},"Catalogs","\u002Flearn\u002Fcatalogs","2.learn\u002F8.catalogs","i-lucide-book-open",{"title":81,"path":82,"stem":83,"children":84,"page":29},"CLI","\u002Fcli","3.cli",[85,88,93,98,103,108,113,118,123],{"title":36,"path":86,"stem":87,"icon":44},"\u002Fcli\u002Foverview","3.cli\u002F0.overview",{"title":89,"path":90,"stem":91,"icon":92},"init","\u002Fcli\u002Finit","3.cli\u002F1.init","i-lucide-wand-sparkles",{"title":94,"path":95,"stem":96,"icon":97},"map","\u002Fcli\u002Fmap","3.cli\u002F2.map","i-lucide-radar",{"title":99,"path":100,"stem":101,"icon":102},"Rules","\u002Fcli\u002Frules","3.cli\u002F3.rules","i-lucide-list-checks",{"title":104,"path":105,"stem":106,"icon":107},"Scoring","\u002Fcli\u002Fscoring","3.cli\u002F4.scoring","i-lucide-gauge",{"title":109,"path":110,"stem":111,"icon":112},"CI","\u002Fcli\u002Fci","3.cli\u002F5.ci","i-lucide-git-pull-request",{"title":114,"path":115,"stem":116,"icon":117},"doctor","\u002Fcli\u002Fdoctor","3.cli\u002F6.doctor","i-lucide-stethoscope",{"title":119,"path":120,"stem":121,"icon":122},"telemetry","\u002Fcli\u002Ftelemetry","3.cli\u002F7.telemetry","i-lucide-bar-chart-3",{"title":124,"path":125,"stem":126,"icon":127},"agents","\u002Fcli\u002Fagents","3.cli\u002F8.agents","i-lucide-bot",{"title":129,"path":130,"stem":131,"children":132,"page":29},"Integrate","\u002Fintegrate","4.integrate",[133,137,220],{"title":36,"path":134,"stem":135,"icon":136},"\u002Fintegrate\u002Foverview","4.integrate\u002F0.overview","i-lucide-plug",{"title":138,"path":139,"stem":140,"children":141,"page":29},"Adapters","\u002Fintegrate\u002Fadapters","4.integrate\u002Fadapters",[142,145,175,200],{"title":36,"path":143,"stem":144,"icon":39},"\u002Fintegrate\u002Fadapters\u002Foverview","4.integrate\u002Fadapters\u002F01.overview",{"title":146,"path":147,"stem":148,"children":149,"page":29},"Cloud","\u002Fintegrate\u002Fadapters\u002Fcloud","4.integrate\u002Fadapters\u002Fcloud",[150,155,160,165,170],{"title":151,"path":152,"stem":153,"icon":154},"Axiom","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Faxiom","4.integrate\u002Fadapters\u002Fcloud\u002F01.axiom","i-custom-axiom",{"title":156,"path":157,"stem":158,"icon":159},"PostHog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fposthog","4.integrate\u002Fadapters\u002Fcloud\u002F02.posthog","i-simple-icons-posthog",{"title":161,"path":162,"stem":163,"icon":164},"Sentry","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fsentry","4.integrate\u002Fadapters\u002Fcloud\u002F03.sentry","i-simple-icons-sentry",{"title":166,"path":167,"stem":168,"icon":169},"Better Stack","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fbetter-stack","4.integrate\u002Fadapters\u002Fcloud\u002F04.better-stack","i-simple-icons-betterstack",{"title":171,"path":172,"stem":173,"icon":174},"Datadog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fdatadog","4.integrate\u002Fadapters\u002Fcloud\u002F05.datadog","i-simple-icons-datadog",{"title":176,"path":177,"stem":178,"children":179,"page":29},"Cloud or Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fhybrid","4.integrate\u002Fadapters\u002Fhybrid",[180,185,190,195],{"title":181,"path":182,"stem":183,"icon":184},"Grafana Loki","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Floki","4.integrate\u002Fadapters\u002Fhybrid\u002F01.loki","i-simple-icons-grafana",{"title":186,"path":187,"stem":188,"icon":189},"ClickHouse","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fclickhouse","4.integrate\u002Fadapters\u002Fhybrid\u002F02.clickhouse","i-simple-icons-clickhouse",{"title":191,"path":192,"stem":193,"icon":194},"OTLP","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fotlp","4.integrate\u002Fadapters\u002Fhybrid\u002F03.otlp","i-simple-icons-opentelemetry",{"title":196,"path":197,"stem":198,"icon":199},"HyperDX","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fhyperdx","4.integrate\u002Fadapters\u002Fhybrid\u002F04.hyperdx","i-custom-hyperdx",{"title":201,"path":202,"stem":203,"children":204,"page":29},"Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fself-hosted","4.integrate\u002Fadapters\u002Fself-hosted",[205,210,215],{"title":206,"path":207,"stem":208,"icon":209},"File System","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Ffs","4.integrate\u002Fadapters\u002Fself-hosted\u002F01.fs","i-lucide-hard-drive",{"title":211,"path":212,"stem":213,"icon":214},"NuxtHub","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fnuxthub","4.integrate\u002Fadapters\u002Fself-hosted\u002F02.nuxthub","i-simple-icons-nuxt",{"title":216,"path":217,"stem":218,"icon":219},"Memory","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fmemory","4.integrate\u002Fadapters\u002Fself-hosted\u002F03.memory","i-lucide-cpu",{"title":221,"path":222,"stem":223,"children":224,"page":29},"Frameworks","\u002Fintegrate\u002Fframeworks","4.integrate\u002Fframeworks",[225,229,234,239,244,249,254,259,264,269,274,279,284,289,293,298,303],{"title":36,"path":226,"stem":227,"icon":228},"\u002Fintegrate\u002Fframeworks\u002Foverview","4.integrate\u002Fframeworks\u002F00.overview","i-lucide-layout-grid",{"title":230,"path":231,"stem":232,"icon":233},"Nuxt","\u002Fintegrate\u002Fframeworks\u002Fnuxt","4.integrate\u002Fframeworks\u002F01.nuxt","i-simple-icons-nuxtdotjs",{"title":235,"path":236,"stem":237,"icon":238},"Next.js","\u002Fintegrate\u002Fframeworks\u002Fnextjs","4.integrate\u002Fframeworks\u002F02.nextjs","i-simple-icons-nextdotjs",{"title":240,"path":241,"stem":242,"icon":243},"SvelteKit","\u002Fintegrate\u002Fframeworks\u002Fsveltekit","4.integrate\u002Fframeworks\u002F03.sveltekit","i-simple-icons-svelte",{"title":245,"path":246,"stem":247,"icon":248},"Nitro","\u002Fintegrate\u002Fframeworks\u002Fnitro","4.integrate\u002Fframeworks\u002F04.nitro","i-custom-nitro",{"title":250,"path":251,"stem":252,"icon":253},"TanStack Start","\u002Fintegrate\u002Fframeworks\u002Ftanstack-start","4.integrate\u002Fframeworks\u002F05.tanstack-start","i-custom-tanstack",{"title":255,"path":256,"stem":257,"icon":258},"NestJS","\u002Fintegrate\u002Fframeworks\u002Fnestjs","4.integrate\u002Fframeworks\u002F06.nestjs","i-simple-icons-nestjs",{"title":260,"path":261,"stem":262,"icon":263},"Express","\u002Fintegrate\u002Fframeworks\u002Fexpress","4.integrate\u002Fframeworks\u002F07.express","i-simple-icons-express",{"title":265,"path":266,"stem":267,"icon":268},"Hono","\u002Fintegrate\u002Fframeworks\u002Fhono","4.integrate\u002Fframeworks\u002F08.hono","i-simple-icons-hono",{"title":270,"path":271,"stem":272,"icon":273},"Fastify","\u002Fintegrate\u002Fframeworks\u002Ffastify","4.integrate\u002Fframeworks\u002F09.fastify","i-simple-icons-fastify",{"title":275,"path":276,"stem":277,"icon":278},"Elysia","\u002Fintegrate\u002Fframeworks\u002Felysia","4.integrate\u002Fframeworks\u002F10.elysia","i-custom-elysia",{"title":280,"path":281,"stem":282,"icon":283},"React Router","\u002Fintegrate\u002Fframeworks\u002Freact-router","4.integrate\u002Fframeworks\u002F11.react-router","i-custom-reactrouter",{"title":285,"path":286,"stem":287,"icon":288},"Cloudflare Workers","\u002Fintegrate\u002Fframeworks\u002Fcloudflare-workers","4.integrate\u002Fframeworks\u002F12.cloudflare-workers","i-simple-icons-cloudflare",{"title":290,"path":291,"stem":292,"icon":74},"Standalone","\u002Fintegrate\u002Fframeworks\u002Fstandalone","4.integrate\u002Fframeworks\u002F13.standalone",{"title":294,"path":295,"stem":296,"icon":297},"Astro","\u002Fintegrate\u002Fframeworks\u002Fastro","4.integrate\u002Fframeworks\u002F14.astro","i-simple-icons-astro",{"title":299,"path":300,"stem":301,"icon":302},"oRPC","\u002Fintegrate\u002Fframeworks\u002Forpc","4.integrate\u002Fframeworks\u002F15.orpc","i-lucide-network",{"title":304,"path":305,"stem":306,"icon":307},"AWS Lambda","\u002Fintegrate\u002Fframeworks\u002Faws-lambda","4.integrate\u002Fframeworks\u002F16.aws-lambda","i-custom-lambda",{"title":309,"path":310,"stem":311,"children":312,"page":29},"Use Cases","\u002Fuse-cases","5.use-cases",[313,316,321,350,377,409,430,435],{"title":36,"path":314,"stem":315,"icon":102},"\u002Fuse-cases\u002Foverview","5.use-cases\u002F0.overview",{"title":317,"path":318,"stem":319,"icon":320},"Client Logging","\u002Fuse-cases\u002Fclient-logging","5.use-cases\u002F1.client-logging","i-lucide-monitor",{"title":322,"icon":323,"path":324,"stem":325,"children":326,"page":29},"AI SDK","i-simple-icons-vercel","\u002Fuse-cases\u002Fai-sdk","5.use-cases\u002F2.ai-sdk",[327,330,335,340,345],{"title":36,"path":328,"stem":329,"icon":39},"\u002Fuse-cases\u002Fai-sdk\u002Foverview","5.use-cases\u002F2.ai-sdk\u002F01.overview",{"title":331,"path":332,"stem":333,"icon":334},"Usage","\u002Fuse-cases\u002Fai-sdk\u002Fusage","5.use-cases\u002F2.ai-sdk\u002F02.usage","i-lucide-code",{"title":336,"path":337,"stem":338,"icon":339},"Options","\u002Fuse-cases\u002Fai-sdk\u002Foptions","5.use-cases\u002F2.ai-sdk\u002F03.options","i-lucide-sliders",{"title":341,"path":342,"stem":343,"icon":344},"Metadata","\u002Fuse-cases\u002Fai-sdk\u002Fmetadata","5.use-cases\u002F2.ai-sdk\u002F04.metadata","i-lucide-database",{"title":346,"path":347,"stem":348,"icon":349},"Telemetry","\u002Fuse-cases\u002Fai-sdk\u002Ftelemetry","5.use-cases\u002F2.ai-sdk\u002F05.telemetry","i-lucide-activity",{"title":351,"icon":352,"path":353,"stem":354,"children":355,"page":29},"Better Auth","i-simple-icons-betterauth","\u002Fuse-cases\u002Fbetter-auth","5.use-cases\u002F3.better-auth",[356,359,364,369,373],{"title":36,"path":357,"stem":358,"icon":39},"\u002Fuse-cases\u002Fbetter-auth\u002Foverview","5.use-cases\u002F3.better-auth\u002F01.overview",{"title":360,"path":361,"stem":362,"icon":363},"Identify User","\u002Fuse-cases\u002Fbetter-auth\u002Fidentify-user","5.use-cases\u002F3.better-auth\u002F02.identify-user","i-lucide-user-check",{"title":365,"path":366,"stem":367,"icon":368},"Middleware","\u002Fuse-cases\u002Fbetter-auth\u002Fmiddleware","5.use-cases\u002F3.better-auth\u002F03.middleware","i-lucide-shield",{"title":370,"path":371,"stem":372,"icon":320},"Client Sync","\u002Fuse-cases\u002Fbetter-auth\u002Fclient-sync","5.use-cases\u002F3.better-auth\u002F04.client-sync",{"title":374,"path":375,"stem":376,"icon":107},"Performance","\u002Fuse-cases\u002Fbetter-auth\u002Fperformance","5.use-cases\u002F3.better-auth\u002F05.performance",{"title":378,"icon":379,"path":380,"stem":381,"children":382,"page":29},"Audit Logs","i-lucide-shield-check","\u002Fuse-cases\u002Faudit","5.use-cases\u002F4.audit",[383,386,391,396,401,405],{"title":36,"path":384,"stem":385,"icon":39},"\u002Fuse-cases\u002Faudit\u002Foverview","5.use-cases\u002F4.audit\u002F01.overview",{"title":387,"path":388,"stem":389,"icon":390},"Schema","\u002Fuse-cases\u002Faudit\u002Fschema","5.use-cases\u002F4.audit\u002F02.schema","i-lucide-file-text",{"title":392,"path":393,"stem":394,"icon":395},"Recording","\u002Fuse-cases\u002Faudit\u002Frecording","5.use-cases\u002F4.audit\u002F03.recording","i-lucide-pen-line",{"title":397,"path":398,"stem":399,"icon":400},"Drains","\u002Fuse-cases\u002Faudit\u002Fpipeline","5.use-cases\u002F4.audit\u002F04.pipeline","i-lucide-link",{"title":402,"path":403,"stem":404,"icon":379},"Compliance","\u002Fuse-cases\u002Faudit\u002Fcompliance","5.use-cases\u002F4.audit\u002F05.compliance",{"title":406,"path":407,"stem":408,"icon":79},"Recipes","\u002Fuse-cases\u002Faudit\u002Frecipes","5.use-cases\u002F4.audit\u002F06.recipes",{"title":346,"icon":107,"path":410,"stem":411,"children":412,"page":29},"\u002Fuse-cases\u002Ftelemetry","5.use-cases\u002F4.telemetry",[413,416,421,426],{"title":36,"path":414,"stem":415,"icon":39},"\u002Fuse-cases\u002Ftelemetry\u002Foverview","5.use-cases\u002F4.telemetry\u002F01.overview",{"title":417,"path":418,"stem":419,"icon":420},"Setup","\u002Fuse-cases\u002Ftelemetry\u002Fsetup","5.use-cases\u002F4.telemetry\u002F02.setup","i-lucide-wrench",{"title":422,"path":423,"stem":424,"icon":425},"Ingest","\u002Fuse-cases\u002Ftelemetry\u002Fingest","5.use-cases\u002F4.telemetry\u002F03.ingest","i-lucide-server",{"title":427,"path":428,"stem":429,"icon":79},"Reference","\u002Fuse-cases\u002Ftelemetry\u002Freference","5.use-cases\u002F4.telemetry\u002F04.reference",{"title":431,"path":432,"stem":433,"icon":434},"Enrichers","\u002Fuse-cases\u002Fenrichers","5.use-cases\u002F5.enrichers","i-lucide-sparkles",{"title":436,"path":437,"stem":438,"icon":439},"eve","\u002Fuse-cases\u002Feve","5.use-cases\u002F5.eve","i-custom-eve",{"title":441,"path":442,"stem":443,"children":444,"page":29},"Extend","\u002Fextend","6.extend",[445,449,454,459,463,468,472,476,480,484,489,494],{"title":36,"path":446,"stem":447,"icon":448},"\u002Fextend\u002Foverview","6.extend\u002F0.overview","i-lucide-blocks",{"title":450,"path":451,"stem":452,"icon":453},"Stream","\u002Fextend\u002Fstream","6.extend\u002F1.stream","i-lucide-radio-tower",{"title":455,"path":456,"stem":457,"icon":458},"Custom framework","\u002Fextend\u002Fcustom-framework","6.extend\u002F10.custom-framework","i-lucide-puzzle",{"title":460,"path":461,"stem":462,"icon":453},"Diagnostics channel","\u002Fextend\u002Fdiagnostics-channel","6.extend\u002F11.diagnostics-channel",{"title":464,"path":465,"stem":466,"icon":467},"FS reader","\u002Fextend\u002Ffs-reader","6.extend\u002F2.fs-reader","i-lucide-folder-search",{"title":406,"path":469,"stem":470,"icon":471},"\u002Fextend\u002Fconsumer-recipes","6.extend\u002F3.consumer-recipes","i-lucide-chef-hat",{"title":473,"path":474,"stem":475,"icon":448},"Plugins","\u002Fextend\u002Fplugins","6.extend\u002F4.plugins",{"title":477,"path":478,"stem":479,"icon":434},"Custom enrichers","\u002Fextend\u002Fcustom-enrichers","6.extend\u002F5.custom-enrichers",{"title":481,"path":482,"stem":483,"icon":64},"Tail sampling","\u002Fextend\u002Ftail-sampling","6.extend\u002F6.tail-sampling",{"title":485,"path":486,"stem":487,"icon":488},"Identity headers","\u002Fextend\u002Fidentity-headers","6.extend\u002F7.identity-headers","i-lucide-fingerprint",{"title":490,"path":491,"stem":492,"icon":493},"Custom drains","\u002Fextend\u002Fcustom-drains","6.extend\u002F8.custom-drains","i-lucide-share-2",{"title":495,"path":496,"stem":497,"icon":498},"Drain pipeline","\u002Fextend\u002Fdrain-pipeline","6.extend\u002F9.drain-pipeline","i-lucide-workflow",{"title":427,"path":500,"stem":501,"children":502,"page":29},"\u002Freference","7.reference",[503,507,512,515,520,524,529,533],{"title":36,"path":504,"stem":505,"icon":506},"\u002Freference\u002Foverview","7.reference\u002F0.overview","i-lucide-book-marked",{"title":508,"path":509,"stem":510,"icon":511},"Configuration","\u002Freference\u002Fconfiguration","7.reference\u002F1.configuration","i-lucide-settings",{"title":374,"path":513,"stem":514,"icon":107},"\u002Freference\u002Fperformance","7.reference\u002F2.performance",{"title":516,"path":517,"stem":518,"icon":519},"Vite Plugin","\u002Freference\u002Fvite-plugin","7.reference\u002F3.vite-plugin","i-custom-vite",{"title":521,"path":522,"stem":523,"icon":379},"Best Practices","\u002Freference\u002Fbest-practices","7.reference\u002F4.best-practices",{"title":525,"path":526,"stem":527,"icon":528},"vs Other Loggers","\u002Freference\u002Fvs-other-loggers","7.reference\u002F5.vs-other-loggers","i-lucide-scale",{"title":530,"path":531,"stem":532,"icon":434},"Agent Skills","\u002Freference\u002Fagent-skills","7.reference\u002F6.agent-skills",{"title":534,"path":535,"stem":536,"icon":537},"Cost","\u002Freference\u002Fcost","7.reference\u002F7.cost","i-lucide-receipt",{"id":539,"title":473,"body":540,"description":2021,"extension":2022,"links":2023,"meta":2029,"navigation":2030,"path":474,"seo":2031,"stem":475,"__hash__":2032},"docs\u002F6.extend\u002F4.plugins.md",{"type":541,"value":542,"toc":2013},"minimark",[543,546,559,579,666,671,930,933,1165,1168,1310,1324,1328,1343,1807,1811,1820,1911,1918,1922,1979,1983,2009],[544,545],"lifecycle-flow",{},[547,548,549,553,554,558],"p",{},[550,551,552],"code",{},"definePlugin()"," is the ",[555,556,557],"strong",{},"canonical extension point"," for evlog. Drains and enrichers are special cases of plugins, but a single plugin can opt into multiple hooks at once, the right shape for any non-trivial extension that mixes several concerns (e.g. enrich on every event + side-effect on drain + keep decision on tail sampling, all reading the same shared state).",[547,560,561,562,568,569,574,575,578],{},"When the extension only does one thing, prefer the single-purpose ",[563,564,565],"a",{"href":478},[550,566,567],{},"enricherPlugin()"," \u002F ",[563,570,571],{"href":491},[550,572,573],{},"drainPlugin()"," wrappers. Reach for ",[550,576,577],{},"definePlugin"," when several hooks share state.",[580,581,584,587,658],"prompt",{":actions":582,"description":583,"icon":448},"[\"copy\",\"cursor\",\"claude\"]","Build a multi-hook evlog plugin",[547,585,586],{},"Build an evlog plugin that hooks into more than one lifecycle stage.",[588,589,590,624,630,633,647],"ul",{},[591,592,593,594,596,597,600,601,604,605,604,608,604,611,604,614,604,617,604,620,623],"li",{},"Import ",[550,595,577],{}," from ",[550,598,599],{},"evlog"," and pick the hooks I need (",[550,602,603],{},"onRequestStart",", ",[550,606,607],{},"enrich",[550,609,610],{},"drain",[550,612,613],{},"extendLogger",[550,615,616],{},"keep",[550,618,619],{},"onClientLog",[550,621,622],{},"onRequestFinish",")",[591,625,626,627,629],{},"Keep ",[550,628,607],{}," pure (no I\u002FO, no throwing, use try\u002Fcatch internally)",[591,631,632],{},"For drains, batch and ship to the destination; respect backpressure if the drain is slow",[591,634,635,636,639,640,643,644,623],{},"Register the plugin via the framework config: Next\u002Fstandalone ",[550,637,638],{},"initLogger({ plugins: [myPlugin] })",", Hono\u002FExpress\u002FFastify\u002FElysia middleware option ",[550,641,642],{},"{ plugins: [myPlugin] }",". For Nitro, register the individual hooks directly (",[550,645,646],{},"nitroApp.hooks.hook('evlog:enrich' | 'evlog:drain' | …)",[591,648,649,650,568,652,654,655,657],{},"Prefer single-purpose ",[550,651,567],{},[550,653,573],{}," wrappers for simple extensions; use ",[550,656,577],{}," only when several hooks are needed",[547,659,660,661],{},"Docs: ",[563,662,663],{"href":663,"rel":664},"https:\u002F\u002Fwww.evlog.dev\u002Fextend\u002Fplugins",[665],"nofollow",[667,668,670],"h2",{"id":669},"minimal-example","Minimal example",[672,673,678],"pre",{"className":674,"code":675,"language":676,"meta":677,"style":677},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { definePlugin } from 'evlog'\n\nexport const tenantPlugin = definePlugin({\n  name: 'tenant',\n  onRequestStart({ logger, headers }) {\n    const tenantId = headers?.['x-tenant-id']\n    if (tenantId) logger.set({ tenant: { id: tenantId } })\n  },\n  enrich({ event }) {\n    event.region = process.env.REGION\n  },\n})\n","ts","",[550,679,680,712,719,744,765,790,820,870,876,891,917,922],{"__ignoreMap":677},[681,682,685,689,693,697,700,703,706,709],"span",{"class":683,"line":684},"line",1,[681,686,688],{"class":687},"s7zQu","import",[681,690,692],{"class":691},"sMK4o"," {",[681,694,696],{"class":695},"sTEyZ"," definePlugin",[681,698,699],{"class":691}," }",[681,701,702],{"class":687}," from",[681,704,705],{"class":691}," '",[681,707,599],{"class":708},"sfazB",[681,710,711],{"class":691},"'\n",[681,713,715],{"class":683,"line":714},2,[681,716,718],{"emptyLinePlaceholder":717},true,"\n",[681,720,722,725,729,732,735,738,741],{"class":683,"line":721},3,[681,723,724],{"class":687},"export",[681,726,728],{"class":727},"spNyl"," const",[681,730,731],{"class":695}," tenantPlugin ",[681,733,734],{"class":691},"=",[681,736,696],{"class":737},"s2Zo4",[681,739,740],{"class":695},"(",[681,742,743],{"class":691},"{\n",[681,745,747,751,754,756,759,762],{"class":683,"line":746},4,[681,748,750],{"class":749},"swJcz","  name",[681,752,753],{"class":691},":",[681,755,705],{"class":691},[681,757,758],{"class":708},"tenant",[681,760,761],{"class":691},"'",[681,763,764],{"class":691},",\n",[681,766,768,771,774,778,781,784,787],{"class":683,"line":767},5,[681,769,770],{"class":749},"  onRequestStart",[681,772,773],{"class":691},"({",[681,775,777],{"class":776},"sHdIc"," logger",[681,779,780],{"class":691},",",[681,782,783],{"class":776}," headers",[681,785,786],{"class":691}," })",[681,788,789],{"class":691}," {\n",[681,791,793,796,799,802,804,807,810,812,815,817],{"class":683,"line":792},6,[681,794,795],{"class":727},"    const",[681,797,798],{"class":695}," tenantId",[681,800,801],{"class":691}," =",[681,803,783],{"class":695},[681,805,806],{"class":691},"?.",[681,808,809],{"class":749},"[",[681,811,761],{"class":691},[681,813,814],{"class":708},"x-tenant-id",[681,816,761],{"class":691},[681,818,819],{"class":749},"]\n",[681,821,823,826,829,832,835,838,841,844,846,849,852,854,856,859,861,863,865,867],{"class":683,"line":822},7,[681,824,825],{"class":687},"    if",[681,827,828],{"class":749}," (",[681,830,831],{"class":695},"tenantId",[681,833,834],{"class":749},") ",[681,836,837],{"class":695},"logger",[681,839,840],{"class":691},".",[681,842,843],{"class":737},"set",[681,845,740],{"class":749},[681,847,848],{"class":691},"{",[681,850,851],{"class":749}," tenant",[681,853,753],{"class":691},[681,855,692],{"class":691},[681,857,858],{"class":749}," id",[681,860,753],{"class":691},[681,862,798],{"class":695},[681,864,699],{"class":691},[681,866,699],{"class":691},[681,868,869],{"class":749},")\n",[681,871,873],{"class":683,"line":872},8,[681,874,875],{"class":691},"  },\n",[681,877,879,882,884,887,889],{"class":683,"line":878},9,[681,880,881],{"class":749},"  enrich",[681,883,773],{"class":691},[681,885,886],{"class":776}," event",[681,888,786],{"class":691},[681,890,789],{"class":691},[681,892,894,897,899,902,904,907,909,912,914],{"class":683,"line":893},10,[681,895,896],{"class":695},"    event",[681,898,840],{"class":691},[681,900,901],{"class":695},"region",[681,903,801],{"class":691},[681,905,906],{"class":695}," process",[681,908,840],{"class":691},[681,910,911],{"class":695},"env",[681,913,840],{"class":691},[681,915,916],{"class":695},"REGION\n",[681,918,920],{"class":683,"line":919},11,[681,921,875],{"class":691},[681,923,925,928],{"class":683,"line":924},12,[681,926,927],{"class":691},"}",[681,929,869],{"class":695},[547,931,932],{},"Register the plugin where you bootstrap evlog. The shape depends on your runtime:",[934,935,936,1006,1084],"code-group",{},[672,937,940],{"className":674,"code":938,"filename":939,"language":676,"meta":677,"style":677},"import { initLogger } from 'evlog'\nimport { tenantPlugin } from '.\u002Fplugins\u002Ftenant'\n\ninitLogger({ plugins: [tenantPlugin] })\n","Next.js \u002F standalone",[550,941,942,961,981,985],{"__ignoreMap":677},[681,943,944,946,948,951,953,955,957,959],{"class":683,"line":684},[681,945,688],{"class":687},[681,947,692],{"class":691},[681,949,950],{"class":695}," initLogger",[681,952,699],{"class":691},[681,954,702],{"class":687},[681,956,705],{"class":691},[681,958,599],{"class":708},[681,960,711],{"class":691},[681,962,963,965,967,970,972,974,976,979],{"class":683,"line":714},[681,964,688],{"class":687},[681,966,692],{"class":691},[681,968,969],{"class":695}," tenantPlugin",[681,971,699],{"class":691},[681,973,702],{"class":687},[681,975,705],{"class":691},[681,977,978],{"class":708},".\u002Fplugins\u002Ftenant",[681,980,711],{"class":691},[681,982,983],{"class":683,"line":721},[681,984,718],{"emptyLinePlaceholder":717},[681,986,987,990,992,994,997,999,1002,1004],{"class":683,"line":746},[681,988,989],{"class":737},"initLogger",[681,991,740],{"class":695},[681,993,848],{"class":691},[681,995,996],{"class":749}," plugins",[681,998,753],{"class":691},[681,1000,1001],{"class":695}," [tenantPlugin] ",[681,1003,927],{"class":691},[681,1005,869],{"class":695},[672,1007,1010],{"className":674,"code":1008,"filename":1009,"language":676,"meta":677,"style":677},"import { evlogMiddleware } from 'evlog\u002F\u003Cframework>'\nimport { tenantPlugin } from '.\u002Fplugins\u002Ftenant'\n\napp.use(evlogMiddleware({ plugins: [tenantPlugin] }))\n","Hono \u002F Express \u002F Fastify \u002F Elysia",[550,1011,1012,1032,1050,1054],{"__ignoreMap":677},[681,1013,1014,1016,1018,1021,1023,1025,1027,1030],{"class":683,"line":684},[681,1015,688],{"class":687},[681,1017,692],{"class":691},[681,1019,1020],{"class":695}," evlogMiddleware",[681,1022,699],{"class":691},[681,1024,702],{"class":687},[681,1026,705],{"class":691},[681,1028,1029],{"class":708},"evlog\u002F\u003Cframework>",[681,1031,711],{"class":691},[681,1033,1034,1036,1038,1040,1042,1044,1046,1048],{"class":683,"line":714},[681,1035,688],{"class":687},[681,1037,692],{"class":691},[681,1039,969],{"class":695},[681,1041,699],{"class":691},[681,1043,702],{"class":687},[681,1045,705],{"class":691},[681,1047,978],{"class":708},[681,1049,711],{"class":691},[681,1051,1052],{"class":683,"line":721},[681,1053,718],{"emptyLinePlaceholder":717},[681,1055,1056,1059,1061,1064,1066,1069,1071,1073,1075,1077,1079,1081],{"class":683,"line":746},[681,1057,1058],{"class":695},"app",[681,1060,840],{"class":691},[681,1062,1063],{"class":737},"use",[681,1065,740],{"class":695},[681,1067,1068],{"class":737},"evlogMiddleware",[681,1070,740],{"class":695},[681,1072,848],{"class":691},[681,1074,996],{"class":749},[681,1076,753],{"class":691},[681,1078,1001],{"class":695},[681,1080,927],{"class":691},[681,1082,1083],{"class":695},"))\n",[672,1085,1087],{"className":674,"code":1086,"filename":245,"language":676,"meta":677,"style":677},"\u002F\u002F Register the hooks you actually use directly:\nnitroApp.hooks.hook('evlog:enrich', tenantPlugin.enrich!)\nnitroApp.hooks.hook('evlog:request:start', tenantPlugin.onRequestStart!)\n",[550,1088,1089,1095,1132],{"__ignoreMap":677},[681,1090,1091],{"class":683,"line":684},[681,1092,1094],{"class":1093},"sHwdD","\u002F\u002F Register the hooks you actually use directly:\n",[681,1096,1097,1100,1102,1105,1107,1110,1112,1114,1117,1119,1121,1123,1125,1127,1130],{"class":683,"line":714},[681,1098,1099],{"class":695},"nitroApp",[681,1101,840],{"class":691},[681,1103,1104],{"class":695},"hooks",[681,1106,840],{"class":691},[681,1108,1109],{"class":737},"hook",[681,1111,740],{"class":695},[681,1113,761],{"class":691},[681,1115,1116],{"class":708},"evlog:enrich",[681,1118,761],{"class":691},[681,1120,780],{"class":691},[681,1122,969],{"class":695},[681,1124,840],{"class":691},[681,1126,607],{"class":695},[681,1128,1129],{"class":691},"!",[681,1131,869],{"class":695},[681,1133,1134,1136,1138,1140,1142,1144,1146,1148,1151,1153,1155,1157,1159,1161,1163],{"class":683,"line":721},[681,1135,1099],{"class":695},[681,1137,840],{"class":691},[681,1139,1104],{"class":695},[681,1141,840],{"class":691},[681,1143,1109],{"class":737},[681,1145,740],{"class":695},[681,1147,761],{"class":691},[681,1149,1150],{"class":708},"evlog:request:start",[681,1152,761],{"class":691},[681,1154,780],{"class":691},[681,1156,969],{"class":695},[681,1158,840],{"class":691},[681,1160,603],{"class":695},[681,1162,1129],{"class":691},[681,1164,869],{"class":695},[667,1166,1167],{"id":1104},"Hooks",[1169,1170,1171,1187],"table",{},[1172,1173,1174],"thead",{},[1175,1176,1177,1181,1184],"tr",{},[1178,1179,1180],"th",{},"Hook",[1178,1182,1183],{},"When",[1178,1185,1186],{},"Use it for",[1188,1189,1190,1207,1222,1235,1255,1268,1281,1294],"tbody",{},[1175,1191,1192,1198,1201],{},[1193,1194,1195],"td",{},[550,1196,1197],{},"setup(ctx)",[1193,1199,1200],{},"Once when registered",[1193,1202,1203,1204,1206],{},"Read ",[550,1205,911],{},", set up shared state",[1175,1208,1209,1214,1217],{},[1193,1210,1211],{},[550,1212,1213],{},"onRequestStart(ctx)",[1193,1215,1216],{},"Each request, before any handler runs",[1193,1218,1219,1220],{},"Pull values from headers into ",[550,1221,837],{},[1175,1223,1224,1229,1232],{},[1193,1225,1226],{},[550,1227,1228],{},"enrich(ctx)",[1193,1230,1231],{},"Every event, before drain",[1193,1233,1234],{},"Add derived fields (geo, deploy id…)",[1175,1236,1237,1242,1245],{},[1193,1238,1239],{},[550,1240,1241],{},"keep(ctx)",[1193,1243,1244],{},"Tail sampling decision",[1193,1246,1247,1248,604,1251,1254],{},"Force-keep based on outcome (",[550,1249,1250],{},"status >= 400",[550,1252,1253],{},"duration > 500",", …)",[1175,1256,1257,1262,1265],{},[1193,1258,1259],{},[550,1260,1261],{},"drain(ctx)",[1193,1263,1264],{},"Every emitted event",[1193,1266,1267],{},"Side-effect: alert, mirror to a queue, etc.",[1175,1269,1270,1275,1278],{},[1193,1271,1272],{},[550,1273,1274],{},"onRequestFinish(ctx)",[1193,1276,1277],{},"After response",[1193,1279,1280],{},"Per-request post-processing",[1175,1282,1283,1288,1291],{},[1193,1284,1285],{},[550,1286,1287],{},"onClientLog(ctx)",[1193,1289,1290],{},"Browser-submitted event hits the ingest endpoint",[1193,1292,1293],{},"Observe \u002F reject client traffic",[1175,1295,1296,1301,1304],{},[1193,1297,1298],{},[550,1299,1300],{},"extendLogger(logger)",[1193,1302,1303],{},"Each request",[1193,1305,1306,1307,623],{},"Add custom methods (e.g. ",[550,1308,1309],{},"logger.audit.refund()",[547,1311,1312,1313,1316,1317,840],{},"Every hook is ",[555,1314,1315],{},"optional",". A plugin can implement any subset. The full type lives in ",[563,1318,1321],{"href":1319,"rel":1320},"https:\u002F\u002Fgithub.com\u002FHugoRCD\u002Fevlog\u002Fblob\u002Fmain\u002Fpackages\u002Fevlog\u002Fsrc\u002Fshared\u002Fplugin.ts",[665],[550,1322,1323],{},"packages\u002Fevlog\u002Fsrc\u002Fshared\u002Fplugin.ts",[667,1325,1327],{"id":1326},"a-multi-hook-example","A multi-hook example",[547,1329,1330,1331,1334,1335,604,1338,1340,1341,753],{},"Plugins shine when several concerns share state. Here, a single ",[550,1332,1333],{},"request-metrics"," plugin tracks per-request timing through ",[550,1336,1337],{},"setup",[550,1339,603],{},", and ",[550,1342,610],{},[672,1344,1346],{"className":674,"code":1345,"language":676,"meta":677,"style":677},"import { definePlugin } from 'evlog\u002Ftoolkit'\n\nexport const requestMetricsPlugin = definePlugin({\n  name: 'request-metrics',\n\n  setup({ env }) {\n    statsd.init({ service: env.service })\n  },\n\n  enrich({ event }) {\n    if (event.durationMs !== undefined) event.tier = event.durationMs > 1000 ? 'slow' : 'fast'\n  },\n\n  drain({ event }) {\n    if (event.durationMs !== undefined) {\n      statsd.timing('http.request', event.durationMs, { path: event.path as string })\n    }\n  },\n\n  onRequestStart({ logger, request }) {\n    logger.set({ trace: { startedAt: Date.now() } })\n  },\n\n  onRequestFinish({ event, durationMs }) {\n    if (event && (event.level === 'error' || durationMs > 5000)) {\n      \u002F\u002F alert \u002F forward \u002F etc.\n    }\n  },\n})\n",[550,1347,1348,1367,1371,1388,1402,1406,1420,1449,1453,1457,1469,1533,1537,1542,1556,1577,1632,1638,1643,1648,1666,1709,1714,1719,1738,1784,1790,1795,1800],{"__ignoreMap":677},[681,1349,1350,1352,1354,1356,1358,1360,1362,1365],{"class":683,"line":684},[681,1351,688],{"class":687},[681,1353,692],{"class":691},[681,1355,696],{"class":695},[681,1357,699],{"class":691},[681,1359,702],{"class":687},[681,1361,705],{"class":691},[681,1363,1364],{"class":708},"evlog\u002Ftoolkit",[681,1366,711],{"class":691},[681,1368,1369],{"class":683,"line":714},[681,1370,718],{"emptyLinePlaceholder":717},[681,1372,1373,1375,1377,1380,1382,1384,1386],{"class":683,"line":721},[681,1374,724],{"class":687},[681,1376,728],{"class":727},[681,1378,1379],{"class":695}," requestMetricsPlugin ",[681,1381,734],{"class":691},[681,1383,696],{"class":737},[681,1385,740],{"class":695},[681,1387,743],{"class":691},[681,1389,1390,1392,1394,1396,1398,1400],{"class":683,"line":746},[681,1391,750],{"class":749},[681,1393,753],{"class":691},[681,1395,705],{"class":691},[681,1397,1333],{"class":708},[681,1399,761],{"class":691},[681,1401,764],{"class":691},[681,1403,1404],{"class":683,"line":767},[681,1405,718],{"emptyLinePlaceholder":717},[681,1407,1408,1411,1413,1416,1418],{"class":683,"line":792},[681,1409,1410],{"class":749},"  setup",[681,1412,773],{"class":691},[681,1414,1415],{"class":776}," env",[681,1417,786],{"class":691},[681,1419,789],{"class":691},[681,1421,1422,1425,1427,1429,1431,1433,1436,1438,1440,1442,1445,1447],{"class":683,"line":822},[681,1423,1424],{"class":695},"    statsd",[681,1426,840],{"class":691},[681,1428,89],{"class":737},[681,1430,740],{"class":749},[681,1432,848],{"class":691},[681,1434,1435],{"class":749}," service",[681,1437,753],{"class":691},[681,1439,1415],{"class":695},[681,1441,840],{"class":691},[681,1443,1444],{"class":695},"service",[681,1446,699],{"class":691},[681,1448,869],{"class":749},[681,1450,1451],{"class":683,"line":872},[681,1452,875],{"class":691},[681,1454,1455],{"class":683,"line":878},[681,1456,718],{"emptyLinePlaceholder":717},[681,1458,1459,1461,1463,1465,1467],{"class":683,"line":893},[681,1460,881],{"class":749},[681,1462,773],{"class":691},[681,1464,886],{"class":776},[681,1466,786],{"class":691},[681,1468,789],{"class":691},[681,1470,1471,1473,1475,1478,1480,1483,1486,1489,1491,1493,1495,1498,1500,1502,1504,1506,1509,1513,1516,1518,1521,1523,1526,1528,1531],{"class":683,"line":919},[681,1472,825],{"class":687},[681,1474,828],{"class":749},[681,1476,1477],{"class":695},"event",[681,1479,840],{"class":691},[681,1481,1482],{"class":695},"durationMs",[681,1484,1485],{"class":691}," !==",[681,1487,1488],{"class":691}," undefined",[681,1490,834],{"class":749},[681,1492,1477],{"class":695},[681,1494,840],{"class":691},[681,1496,1497],{"class":695},"tier",[681,1499,801],{"class":691},[681,1501,886],{"class":695},[681,1503,840],{"class":691},[681,1505,1482],{"class":695},[681,1507,1508],{"class":691}," >",[681,1510,1512],{"class":1511},"sbssI"," 1000",[681,1514,1515],{"class":691}," ?",[681,1517,705],{"class":691},[681,1519,1520],{"class":708},"slow",[681,1522,761],{"class":691},[681,1524,1525],{"class":691}," :",[681,1527,705],{"class":691},[681,1529,1530],{"class":708},"fast",[681,1532,711],{"class":691},[681,1534,1535],{"class":683,"line":924},[681,1536,875],{"class":691},[681,1538,1540],{"class":683,"line":1539},13,[681,1541,718],{"emptyLinePlaceholder":717},[681,1543,1545,1548,1550,1552,1554],{"class":683,"line":1544},14,[681,1546,1547],{"class":749},"  drain",[681,1549,773],{"class":691},[681,1551,886],{"class":776},[681,1553,786],{"class":691},[681,1555,789],{"class":691},[681,1557,1559,1561,1563,1565,1567,1569,1571,1573,1575],{"class":683,"line":1558},15,[681,1560,825],{"class":687},[681,1562,828],{"class":749},[681,1564,1477],{"class":695},[681,1566,840],{"class":691},[681,1568,1482],{"class":695},[681,1570,1485],{"class":691},[681,1572,1488],{"class":691},[681,1574,834],{"class":749},[681,1576,743],{"class":691},[681,1578,1580,1583,1585,1588,1590,1592,1595,1597,1599,1601,1603,1605,1607,1609,1612,1614,1616,1618,1621,1624,1628,1630],{"class":683,"line":1579},16,[681,1581,1582],{"class":695},"      statsd",[681,1584,840],{"class":691},[681,1586,1587],{"class":737},"timing",[681,1589,740],{"class":749},[681,1591,761],{"class":691},[681,1593,1594],{"class":708},"http.request",[681,1596,761],{"class":691},[681,1598,780],{"class":691},[681,1600,886],{"class":695},[681,1602,840],{"class":691},[681,1604,1482],{"class":695},[681,1606,780],{"class":691},[681,1608,692],{"class":691},[681,1610,1611],{"class":749}," path",[681,1613,753],{"class":691},[681,1615,886],{"class":695},[681,1617,840],{"class":691},[681,1619,1620],{"class":695},"path",[681,1622,1623],{"class":687}," as",[681,1625,1627],{"class":1626},"sBMFI"," string",[681,1629,699],{"class":691},[681,1631,869],{"class":749},[681,1633,1635],{"class":683,"line":1634},17,[681,1636,1637],{"class":691},"    }\n",[681,1639,1641],{"class":683,"line":1640},18,[681,1642,875],{"class":691},[681,1644,1646],{"class":683,"line":1645},19,[681,1647,718],{"emptyLinePlaceholder":717},[681,1649,1651,1653,1655,1657,1659,1662,1664],{"class":683,"line":1650},20,[681,1652,770],{"class":749},[681,1654,773],{"class":691},[681,1656,777],{"class":776},[681,1658,780],{"class":691},[681,1660,1661],{"class":776}," request",[681,1663,786],{"class":691},[681,1665,789],{"class":691},[681,1667,1669,1672,1674,1676,1678,1680,1683,1685,1687,1690,1692,1695,1697,1700,1703,1705,1707],{"class":683,"line":1668},21,[681,1670,1671],{"class":695},"    logger",[681,1673,840],{"class":691},[681,1675,843],{"class":737},[681,1677,740],{"class":749},[681,1679,848],{"class":691},[681,1681,1682],{"class":749}," trace",[681,1684,753],{"class":691},[681,1686,692],{"class":691},[681,1688,1689],{"class":749}," startedAt",[681,1691,753],{"class":691},[681,1693,1694],{"class":695}," Date",[681,1696,840],{"class":691},[681,1698,1699],{"class":737},"now",[681,1701,1702],{"class":749},"() ",[681,1704,927],{"class":691},[681,1706,699],{"class":691},[681,1708,869],{"class":749},[681,1710,1712],{"class":683,"line":1711},22,[681,1713,875],{"class":691},[681,1715,1717],{"class":683,"line":1716},23,[681,1718,718],{"emptyLinePlaceholder":717},[681,1720,1722,1725,1727,1729,1731,1734,1736],{"class":683,"line":1721},24,[681,1723,1724],{"class":749},"  onRequestFinish",[681,1726,773],{"class":691},[681,1728,886],{"class":776},[681,1730,780],{"class":691},[681,1732,1733],{"class":776}," durationMs",[681,1735,786],{"class":691},[681,1737,789],{"class":691},[681,1739,1741,1743,1745,1747,1750,1752,1754,1756,1759,1762,1764,1767,1769,1772,1774,1776,1779,1782],{"class":683,"line":1740},25,[681,1742,825],{"class":687},[681,1744,828],{"class":749},[681,1746,1477],{"class":695},[681,1748,1749],{"class":691}," &&",[681,1751,828],{"class":749},[681,1753,1477],{"class":695},[681,1755,840],{"class":691},[681,1757,1758],{"class":695},"level",[681,1760,1761],{"class":691}," ===",[681,1763,705],{"class":691},[681,1765,1766],{"class":708},"error",[681,1768,761],{"class":691},[681,1770,1771],{"class":691}," ||",[681,1773,1733],{"class":695},[681,1775,1508],{"class":691},[681,1777,1778],{"class":1511}," 5000",[681,1780,1781],{"class":749},")) ",[681,1783,743],{"class":691},[681,1785,1787],{"class":683,"line":1786},26,[681,1788,1789],{"class":1093},"      \u002F\u002F alert \u002F forward \u002F etc.\n",[681,1791,1793],{"class":683,"line":1792},27,[681,1794,1637],{"class":691},[681,1796,1798],{"class":683,"line":1797},28,[681,1799,875],{"class":691},[681,1801,1803,1805],{"class":683,"line":1802},29,[681,1804,927],{"class":691},[681,1806,869],{"class":695},[667,1808,1810],{"id":1809},"sugar-plugins","Sugar plugins",[547,1812,1813,1814,1816,1817,1819],{},"For single-hook extensions, the toolkit offers ",[550,1815,573],{}," and ",[550,1818,567],{}," wrappers:",[672,1821,1825],{"className":1822,"code":1823,"language":1824,"meta":677,"style":677},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { drainPlugin, enricherPlugin } from 'evlog\u002Ftoolkit'\n\nconst drainOnly = drainPlugin('axiom', createAxiomDrain())\nconst enricherOnly = enricherPlugin('user-agent', createUserAgentEnricher())\n","typescript",[550,1826,1827,1851,1855,1884],{"__ignoreMap":677},[681,1828,1829,1831,1833,1836,1838,1841,1843,1845,1847,1849],{"class":683,"line":684},[681,1830,688],{"class":687},[681,1832,692],{"class":691},[681,1834,1835],{"class":695}," drainPlugin",[681,1837,780],{"class":691},[681,1839,1840],{"class":695}," enricherPlugin",[681,1842,699],{"class":691},[681,1844,702],{"class":687},[681,1846,705],{"class":691},[681,1848,1364],{"class":708},[681,1850,711],{"class":691},[681,1852,1853],{"class":683,"line":714},[681,1854,718],{"emptyLinePlaceholder":717},[681,1856,1857,1860,1863,1865,1867,1869,1871,1874,1876,1878,1881],{"class":683,"line":721},[681,1858,1859],{"class":727},"const",[681,1861,1862],{"class":695}," drainOnly ",[681,1864,734],{"class":691},[681,1866,1835],{"class":737},[681,1868,740],{"class":695},[681,1870,761],{"class":691},[681,1872,1873],{"class":708},"axiom",[681,1875,761],{"class":691},[681,1877,780],{"class":691},[681,1879,1880],{"class":737}," createAxiomDrain",[681,1882,1883],{"class":695},"())\n",[681,1885,1886,1888,1891,1893,1895,1897,1899,1902,1904,1906,1909],{"class":683,"line":746},[681,1887,1859],{"class":727},[681,1889,1890],{"class":695}," enricherOnly ",[681,1892,734],{"class":691},[681,1894,1840],{"class":737},[681,1896,740],{"class":695},[681,1898,761],{"class":691},[681,1900,1901],{"class":708},"user-agent",[681,1903,761],{"class":691},[681,1905,780],{"class":691},[681,1907,1908],{"class":737}," createUserAgentEnricher",[681,1910,1883],{"class":695},[547,1912,1913,1914,1917],{},"These are equivalent to a ",[550,1915,1916],{},"definePlugin({ name, drain | enrich })"," shape but read more clearly when intent is obvious.",[667,1919,1921],{"id":1920},"common-pitfalls","Common pitfalls",[588,1923,1924,1933,1944,1967],{},[591,1925,1926,1929,1930,1932],{},[555,1927,1928],{},"Don't throw from a hook."," The plugin runner catches and logs errors with the plugin name, but a thrown error from ",[550,1931,607],{}," won't propagate the event downstream. Keep hooks defensive.",[591,1934,1935,1940,1941,1943],{},[555,1936,1937,1939],{},[550,1938,610],{}," runs for every event",": not just per-request. If you only care about per-request lifecycle, use ",[550,1942,622],{}," instead.",[591,1945,1946,1951,1952,1955,1956,1959,1960,1963,1964,840],{},[555,1947,1948,1950],{},[550,1949,613],{}," mutates the logger object",": augment ",[550,1953,1954],{},"RequestLogger"," in a ",[550,1957,1958],{},".d.ts"," so ",[550,1961,1962],{},"useLogger(event)"," exposes the new methods to TypeScript. See ",[563,1965,1966],{"href":72},"typed fields",[591,1968,1969,1975,1976,1978],{},[555,1970,1971,1972],{},"Plugins are de-duplicated by ",[550,1973,1974],{},"name",". Re-registering with the same ",[550,1977,1974],{}," replaces the previous version (last registration wins).",[667,1980,1982],{"id":1981},"next-steps","Next steps",[588,1984,1985,1991,1997,2003],{},[591,1986,1987,1990],{},[563,1988,1989],{"href":478},"Custom Enrichers",": single-hook enrichment",[591,1992,1993,1996],{},[563,1994,1995],{"href":491},"Custom Drains",": single-destination output",[591,1998,1999,2002],{},[563,2000,2001],{"href":482},"Tail Sampling",": outcome-aware keep decisions",[591,2004,2005,2008],{},[563,2006,2007],{"href":486},"Identity Headers",": tag every drain request",[2010,2011,2012],"style",{},"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 .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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}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 .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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"title":677,"searchDepth":714,"depth":714,"links":2014},[2015,2016,2017,2018,2019,2020],{"id":669,"depth":714,"text":670},{"id":1104,"depth":714,"text":1167},{"id":1326,"depth":714,"text":1327},{"id":1809,"depth":714,"text":1810},{"id":1920,"depth":714,"text":1921},{"id":1981,"depth":714,"text":1982},"definePlugin is evlog's canonical extension point: opt into any subset of the lifecycle hooks from one cohesive object.","md",[2024,2027,2028],{"label":1989,"icon":434,"to":478,"color":2025,"variant":2026},"neutral","subtle",{"label":1995,"icon":493,"to":491,"color":2025,"variant":2026},{"label":2001,"icon":64,"to":482,"color":2025,"variant":2026},{},{"title":473,"icon":448},{"title":473,"description":2021},"MKg-wOwX5kmQhW1QlCOyX30OJn6aIeGoPG1ePT5ku_0",[2034,2036],{"title":406,"path":469,"stem":470,"description":2035,"icon":471,"children":-1},"Concrete copy-paste recipes — build your own minimal devtool, pipe to curl + jq, replay history then go live, and aggregate on the consumer side.",{"title":477,"path":478,"stem":479,"description":2037,"icon":434,"children":-1},"Write an enricher that adds deployment metadata, tenant ids, feature flags, or anything computed. Error isolation and merging are handled.",1786817428146]