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