[{"data":1,"prerenderedAt":1393},["ShallowReactive",2],{"navigation_docs":3,"-use-cases-audit-pipeline":505,"-use-cases-audit-pipeline-surround":1388},[4,30,80,123,288,420,475],{"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,200],{"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,180],{"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,170,175],{"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},"OTLP","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fotlp","4.integrate\u002Fadapters\u002Fcloud\u002F02.otlp","i-simple-icons-opentelemetry",{"title":156,"path":157,"stem":158,"icon":159},"PostHog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fposthog","4.integrate\u002Fadapters\u002Fcloud\u002F03.posthog","i-simple-icons-posthog",{"title":161,"path":162,"stem":163,"icon":164},"Sentry","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fsentry","4.integrate\u002Fadapters\u002Fcloud\u002F04.sentry","i-simple-icons-sentry",{"title":166,"path":167,"stem":168,"icon":169},"Better Stack","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fbetter-stack","4.integrate\u002Fadapters\u002Fcloud\u002F05.better-stack","i-simple-icons-betterstack",{"title":171,"path":172,"stem":173,"icon":174},"Datadog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fdatadog","4.integrate\u002Fadapters\u002Fcloud\u002F06.datadog","i-simple-icons-datadog",{"title":176,"path":177,"stem":178,"icon":179},"HyperDX","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fhyperdx","4.integrate\u002Fadapters\u002Fcloud\u002F07.hyperdx","i-custom-hyperdx",{"title":181,"path":182,"stem":183,"children":184,"page":29},"Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fself-hosted","4.integrate\u002Fadapters\u002Fself-hosted",[185,190,195],{"title":186,"path":187,"stem":188,"icon":189},"File System","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Ffs","4.integrate\u002Fadapters\u002Fself-hosted\u002F01.fs","i-lucide-hard-drive",{"title":191,"path":192,"stem":193,"icon":194},"NuxtHub","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fnuxthub","4.integrate\u002Fadapters\u002Fself-hosted\u002F02.nuxthub","i-simple-icons-nuxt",{"title":196,"path":197,"stem":198,"icon":199},"Memory","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fmemory","4.integrate\u002Fadapters\u002Fself-hosted\u002F03.memory","i-lucide-cpu",{"title":201,"path":202,"stem":203,"children":204,"page":29},"Frameworks","\u002Fintegrate\u002Fframeworks","4.integrate\u002Fframeworks",[205,209,214,219,224,229,234,239,244,249,254,259,264,269,273,278,283],{"title":36,"path":206,"stem":207,"icon":208},"\u002Fintegrate\u002Fframeworks\u002Foverview","4.integrate\u002Fframeworks\u002F00.overview","i-lucide-layout-grid",{"title":210,"path":211,"stem":212,"icon":213},"Nuxt","\u002Fintegrate\u002Fframeworks\u002Fnuxt","4.integrate\u002Fframeworks\u002F01.nuxt","i-simple-icons-nuxtdotjs",{"title":215,"path":216,"stem":217,"icon":218},"Next.js","\u002Fintegrate\u002Fframeworks\u002Fnextjs","4.integrate\u002Fframeworks\u002F02.nextjs","i-simple-icons-nextdotjs",{"title":220,"path":221,"stem":222,"icon":223},"SvelteKit","\u002Fintegrate\u002Fframeworks\u002Fsveltekit","4.integrate\u002Fframeworks\u002F03.sveltekit","i-simple-icons-svelte",{"title":225,"path":226,"stem":227,"icon":228},"Nitro","\u002Fintegrate\u002Fframeworks\u002Fnitro","4.integrate\u002Fframeworks\u002F04.nitro","i-custom-nitro",{"title":230,"path":231,"stem":232,"icon":233},"TanStack Start","\u002Fintegrate\u002Fframeworks\u002Ftanstack-start","4.integrate\u002Fframeworks\u002F05.tanstack-start","i-custom-tanstack",{"title":235,"path":236,"stem":237,"icon":238},"NestJS","\u002Fintegrate\u002Fframeworks\u002Fnestjs","4.integrate\u002Fframeworks\u002F06.nestjs","i-simple-icons-nestjs",{"title":240,"path":241,"stem":242,"icon":243},"Express","\u002Fintegrate\u002Fframeworks\u002Fexpress","4.integrate\u002Fframeworks\u002F07.express","i-simple-icons-express",{"title":245,"path":246,"stem":247,"icon":248},"Hono","\u002Fintegrate\u002Fframeworks\u002Fhono","4.integrate\u002Fframeworks\u002F08.hono","i-simple-icons-hono",{"title":250,"path":251,"stem":252,"icon":253},"Fastify","\u002Fintegrate\u002Fframeworks\u002Ffastify","4.integrate\u002Fframeworks\u002F09.fastify","i-simple-icons-fastify",{"title":255,"path":256,"stem":257,"icon":258},"Elysia","\u002Fintegrate\u002Fframeworks\u002Felysia","4.integrate\u002Fframeworks\u002F10.elysia","i-custom-elysia",{"title":260,"path":261,"stem":262,"icon":263},"React Router","\u002Fintegrate\u002Fframeworks\u002Freact-router","4.integrate\u002Fframeworks\u002F11.react-router","i-custom-reactrouter",{"title":265,"path":266,"stem":267,"icon":268},"Cloudflare Workers","\u002Fintegrate\u002Fframeworks\u002Fcloudflare-workers","4.integrate\u002Fframeworks\u002F12.cloudflare-workers","i-simple-icons-cloudflare",{"title":270,"path":271,"stem":272,"icon":74},"Standalone","\u002Fintegrate\u002Fframeworks\u002Fstandalone","4.integrate\u002Fframeworks\u002F13.standalone",{"title":274,"path":275,"stem":276,"icon":277},"Astro","\u002Fintegrate\u002Fframeworks\u002Fastro","4.integrate\u002Fframeworks\u002F14.astro","i-simple-icons-astro",{"title":279,"path":280,"stem":281,"icon":282},"oRPC","\u002Fintegrate\u002Fframeworks\u002Forpc","4.integrate\u002Fframeworks\u002F15.orpc","i-lucide-network",{"title":284,"path":285,"stem":286,"icon":287},"AWS Lambda","\u002Fintegrate\u002Fframeworks\u002Faws-lambda","4.integrate\u002Fframeworks\u002F16.aws-lambda","i-custom-lambda",{"title":289,"path":290,"stem":291,"children":292,"page":29},"Use Cases","\u002Fuse-cases","5.use-cases",[293,296,301,330,357,389,410,415],{"title":36,"path":294,"stem":295,"icon":102},"\u002Fuse-cases\u002Foverview","5.use-cases\u002F0.overview",{"title":297,"path":298,"stem":299,"icon":300},"Client Logging","\u002Fuse-cases\u002Fclient-logging","5.use-cases\u002F1.client-logging","i-lucide-monitor",{"title":302,"icon":303,"path":304,"stem":305,"children":306,"page":29},"AI SDK","i-simple-icons-vercel","\u002Fuse-cases\u002Fai-sdk","5.use-cases\u002F2.ai-sdk",[307,310,315,320,325],{"title":36,"path":308,"stem":309,"icon":39},"\u002Fuse-cases\u002Fai-sdk\u002Foverview","5.use-cases\u002F2.ai-sdk\u002F01.overview",{"title":311,"path":312,"stem":313,"icon":314},"Usage","\u002Fuse-cases\u002Fai-sdk\u002Fusage","5.use-cases\u002F2.ai-sdk\u002F02.usage","i-lucide-code",{"title":316,"path":317,"stem":318,"icon":319},"Options","\u002Fuse-cases\u002Fai-sdk\u002Foptions","5.use-cases\u002F2.ai-sdk\u002F03.options","i-lucide-sliders",{"title":321,"path":322,"stem":323,"icon":324},"Metadata","\u002Fuse-cases\u002Fai-sdk\u002Fmetadata","5.use-cases\u002F2.ai-sdk\u002F04.metadata","i-lucide-database",{"title":326,"path":327,"stem":328,"icon":329},"Telemetry","\u002Fuse-cases\u002Fai-sdk\u002Ftelemetry","5.use-cases\u002F2.ai-sdk\u002F05.telemetry","i-lucide-activity",{"title":331,"icon":332,"path":333,"stem":334,"children":335,"page":29},"Better Auth","i-simple-icons-betterauth","\u002Fuse-cases\u002Fbetter-auth","5.use-cases\u002F3.better-auth",[336,339,344,349,353],{"title":36,"path":337,"stem":338,"icon":39},"\u002Fuse-cases\u002Fbetter-auth\u002Foverview","5.use-cases\u002F3.better-auth\u002F01.overview",{"title":340,"path":341,"stem":342,"icon":343},"Identify User","\u002Fuse-cases\u002Fbetter-auth\u002Fidentify-user","5.use-cases\u002F3.better-auth\u002F02.identify-user","i-lucide-user-check",{"title":345,"path":346,"stem":347,"icon":348},"Middleware","\u002Fuse-cases\u002Fbetter-auth\u002Fmiddleware","5.use-cases\u002F3.better-auth\u002F03.middleware","i-lucide-shield",{"title":350,"path":351,"stem":352,"icon":300},"Client Sync","\u002Fuse-cases\u002Fbetter-auth\u002Fclient-sync","5.use-cases\u002F3.better-auth\u002F04.client-sync",{"title":354,"path":355,"stem":356,"icon":107},"Performance","\u002Fuse-cases\u002Fbetter-auth\u002Fperformance","5.use-cases\u002F3.better-auth\u002F05.performance",{"title":358,"icon":359,"path":360,"stem":361,"children":362,"page":29},"Audit Logs","i-lucide-shield-check","\u002Fuse-cases\u002Faudit","5.use-cases\u002F4.audit",[363,366,371,376,381,385],{"title":36,"path":364,"stem":365,"icon":39},"\u002Fuse-cases\u002Faudit\u002Foverview","5.use-cases\u002F4.audit\u002F01.overview",{"title":367,"path":368,"stem":369,"icon":370},"Schema","\u002Fuse-cases\u002Faudit\u002Fschema","5.use-cases\u002F4.audit\u002F02.schema","i-lucide-file-text",{"title":372,"path":373,"stem":374,"icon":375},"Recording","\u002Fuse-cases\u002Faudit\u002Frecording","5.use-cases\u002F4.audit\u002F03.recording","i-lucide-pen-line",{"title":377,"path":378,"stem":379,"icon":380},"Drains","\u002Fuse-cases\u002Faudit\u002Fpipeline","5.use-cases\u002F4.audit\u002F04.pipeline","i-lucide-link",{"title":382,"path":383,"stem":384,"icon":359},"Compliance","\u002Fuse-cases\u002Faudit\u002Fcompliance","5.use-cases\u002F4.audit\u002F05.compliance",{"title":386,"path":387,"stem":388,"icon":79},"Recipes","\u002Fuse-cases\u002Faudit\u002Frecipes","5.use-cases\u002F4.audit\u002F06.recipes",{"title":326,"icon":107,"path":390,"stem":391,"children":392,"page":29},"\u002Fuse-cases\u002Ftelemetry","5.use-cases\u002F4.telemetry",[393,396,401,406],{"title":36,"path":394,"stem":395,"icon":39},"\u002Fuse-cases\u002Ftelemetry\u002Foverview","5.use-cases\u002F4.telemetry\u002F01.overview",{"title":397,"path":398,"stem":399,"icon":400},"Setup","\u002Fuse-cases\u002Ftelemetry\u002Fsetup","5.use-cases\u002F4.telemetry\u002F02.setup","i-lucide-wrench",{"title":402,"path":403,"stem":404,"icon":405},"Ingest","\u002Fuse-cases\u002Ftelemetry\u002Fingest","5.use-cases\u002F4.telemetry\u002F03.ingest","i-lucide-server",{"title":407,"path":408,"stem":409,"icon":79},"Reference","\u002Fuse-cases\u002Ftelemetry\u002Freference","5.use-cases\u002F4.telemetry\u002F04.reference",{"title":411,"path":412,"stem":413,"icon":414},"Enrichers","\u002Fuse-cases\u002Fenrichers","5.use-cases\u002F5.enrichers","i-lucide-sparkles",{"title":416,"path":417,"stem":418,"icon":419},"eve","\u002Fuse-cases\u002Feve","5.use-cases\u002F5.eve","i-custom-eve",{"title":421,"path":422,"stem":423,"children":424,"page":29},"Extend","\u002Fextend","6.extend",[425,429,434,439,444,448,452,456,460,465,470],{"title":36,"path":426,"stem":427,"icon":428},"\u002Fextend\u002Foverview","6.extend\u002F0.overview","i-lucide-blocks",{"title":430,"path":431,"stem":432,"icon":433},"Stream","\u002Fextend\u002Fstream","6.extend\u002F1.stream","i-lucide-radio-tower",{"title":435,"path":436,"stem":437,"icon":438},"Custom framework","\u002Fextend\u002Fcustom-framework","6.extend\u002F10.custom-framework","i-lucide-puzzle",{"title":440,"path":441,"stem":442,"icon":443},"FS reader","\u002Fextend\u002Ffs-reader","6.extend\u002F2.fs-reader","i-lucide-folder-search",{"title":386,"path":445,"stem":446,"icon":447},"\u002Fextend\u002Fconsumer-recipes","6.extend\u002F3.consumer-recipes","i-lucide-chef-hat",{"title":449,"path":450,"stem":451,"icon":428},"Plugins","\u002Fextend\u002Fplugins","6.extend\u002F4.plugins",{"title":453,"path":454,"stem":455,"icon":414},"Custom enrichers","\u002Fextend\u002Fcustom-enrichers","6.extend\u002F5.custom-enrichers",{"title":457,"path":458,"stem":459,"icon":64},"Tail sampling","\u002Fextend\u002Ftail-sampling","6.extend\u002F6.tail-sampling",{"title":461,"path":462,"stem":463,"icon":464},"Identity headers","\u002Fextend\u002Fidentity-headers","6.extend\u002F7.identity-headers","i-lucide-fingerprint",{"title":466,"path":467,"stem":468,"icon":469},"Custom drains","\u002Fextend\u002Fcustom-drains","6.extend\u002F8.custom-drains","i-lucide-share-2",{"title":471,"path":472,"stem":473,"icon":474},"Drain pipeline","\u002Fextend\u002Fdrain-pipeline","6.extend\u002F9.drain-pipeline","i-lucide-workflow",{"title":407,"path":476,"stem":477,"children":478,"page":29},"\u002Freference","7.reference",[479,484,487,492,496,501],{"title":480,"path":481,"stem":482,"icon":483},"Configuration","\u002Freference\u002Fconfiguration","7.reference\u002F1.configuration","i-lucide-settings",{"title":354,"path":485,"stem":486,"icon":107},"\u002Freference\u002Fperformance","7.reference\u002F2.performance",{"title":488,"path":489,"stem":490,"icon":491},"Vite Plugin","\u002Freference\u002Fvite-plugin","7.reference\u002F3.vite-plugin","i-custom-vite",{"title":493,"path":494,"stem":495,"icon":359},"Best Practices","\u002Freference\u002Fbest-practices","7.reference\u002F4.best-practices",{"title":497,"path":498,"stem":499,"icon":500},"vs Other Loggers","\u002Freference\u002Fvs-other-loggers","7.reference\u002F5.vs-other-loggers","i-lucide-scale",{"title":502,"path":503,"stem":504,"icon":414},"Agent Skills","\u002Freference\u002Fagent-skills","7.reference\u002F6.agent-skills",{"id":506,"title":507,"body":508,"description":1377,"extension":1378,"links":1379,"meta":1384,"navigation":1385,"path":378,"seo":1386,"stem":379,"__hash__":1387},"docs\u002F5.use-cases\u002F4.audit\u002F04.pipeline.md","Drains & Integrity",{"type":509,"value":510,"toc":1369},"minimark",[511,528,535,544,631,634,757,775,781,801,815,952,959,1011,1017,1022,1028,1085,1102,1107,1110,1185,1189,1192,1341,1347,1350,1365],[512,513,514,515,519,520,523,524,527],"p",{},"Three building blocks: ",[516,517,518],"code",{},"auditEnricher"," fills context, ",[516,521,522],{},"auditOnly"," routes audits to a dedicated drain, and ",[516,525,526],{},"signed"," adds tamper-evident integrity. Each is opt-in and replaceable.",[529,530,532],"h2",{"id":531},"auditenricher",[516,533,534],{},"auditEnricher()",[512,536,537,539,540,543],{},[516,538,534],{}," populates ",[516,541,542],{},"event.audit.context.{requestId, traceId, ip, userAgent, tenantId}",". Skip it and ship a custom enricher if your strategy differs.",[545,546,552],"pre",{"className":547,"code":548,"filename":549,"language":550,"meta":551,"style":551},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { auditEnricher } from 'evlog'\n\nnitro.hooks.hook('evlog:enrich', auditEnricher())\n","server\u002Fplugins\u002Fevlog.ts","typescript","",[516,553,554,587,594],{"__ignoreMap":551},[555,556,559,563,567,571,574,577,580,584],"span",{"class":557,"line":558},"line",1,[555,560,562],{"class":561},"s7zQu","import",[555,564,566],{"class":565},"sMK4o"," {",[555,568,570],{"class":569},"sTEyZ"," auditEnricher",[555,572,573],{"class":565}," }",[555,575,576],{"class":561}," from",[555,578,579],{"class":565}," '",[555,581,583],{"class":582},"sfazB","evlog",[555,585,586],{"class":565},"'\n",[555,588,590],{"class":557,"line":589},2,[555,591,593],{"emptyLinePlaceholder":592},true,"\n",[555,595,597,600,603,606,608,612,615,618,621,623,626,628],{"class":557,"line":596},3,[555,598,599],{"class":569},"nitro",[555,601,602],{"class":565},".",[555,604,605],{"class":569},"hooks",[555,607,602],{"class":565},[555,609,611],{"class":610},"s2Zo4","hook",[555,613,614],{"class":569},"(",[555,616,617],{"class":565},"'",[555,619,620],{"class":582},"evlog:enrich",[555,622,617],{"class":565},[555,624,625],{"class":565},",",[555,627,570],{"class":610},[555,629,630],{"class":569},"())\n",[512,632,633],{},"For multi-tenant apps and custom session bridges, pass options:",[545,635,637],{"className":547,"code":636,"language":550,"meta":551,"style":551},"nitro.hooks.hook('evlog:enrich', auditEnricher({\n  tenantId: ctx => ctx.event.tenant as string | undefined,\n  bridge: { getSession: async ctx => readSessionActor(ctx.headers) },\n}))\n",[516,638,639,668,712,748],{"__ignoreMap":551},[555,640,641,643,645,647,649,651,653,655,657,659,661,663,665],{"class":557,"line":558},[555,642,599],{"class":569},[555,644,602],{"class":565},[555,646,605],{"class":569},[555,648,602],{"class":565},[555,650,611],{"class":610},[555,652,614],{"class":569},[555,654,617],{"class":565},[555,656,620],{"class":582},[555,658,617],{"class":565},[555,660,625],{"class":565},[555,662,570],{"class":610},[555,664,614],{"class":569},[555,666,667],{"class":565},"{\n",[555,669,670,673,676,680,684,686,688,691,693,696,699,703,706,709],{"class":557,"line":589},[555,671,672],{"class":610},"  tenantId",[555,674,675],{"class":565},":",[555,677,679],{"class":678},"sHdIc"," ctx",[555,681,683],{"class":682},"spNyl"," =>",[555,685,679],{"class":569},[555,687,602],{"class":565},[555,689,690],{"class":569},"event",[555,692,602],{"class":565},[555,694,695],{"class":569},"tenant ",[555,697,698],{"class":561},"as",[555,700,702],{"class":701},"sBMFI"," string",[555,704,705],{"class":565}," |",[555,707,708],{"class":701}," undefined",[555,710,711],{"class":565},",\n",[555,713,714,718,720,722,725,727,730,732,734,737,740,742,745],{"class":557,"line":596},[555,715,717],{"class":716},"swJcz","  bridge",[555,719,675],{"class":565},[555,721,566],{"class":565},[555,723,724],{"class":610}," getSession",[555,726,675],{"class":565},[555,728,729],{"class":682}," async",[555,731,679],{"class":678},[555,733,683],{"class":682},[555,735,736],{"class":610}," readSessionActor",[555,738,739],{"class":569},"(ctx",[555,741,602],{"class":565},[555,743,744],{"class":569},"headers) ",[555,746,747],{"class":565},"},\n",[555,749,751,754],{"class":557,"line":750},4,[555,752,753],{"class":565},"}",[555,755,756],{"class":569},"))\n",[512,758,759,760,762,763,766,767,770,771,774],{},"Without ",[516,761,518],{},", ",[516,764,765],{},"audit.context"," stays empty — auditors and incident responders need at least ",[516,768,769],{},"requestId"," and ",[516,772,773],{},"ip"," to triangulate a recorded action.",[529,776,778],{"id":777},"auditonly",[516,779,780],{},"auditOnly()",[782,783,784,788,789,792,793,796,797,800],"tip",{},[785,786,787],"strong",{},"Why filter audits to a separate sink?"," Three reasons: ",[785,790,791],{},"cost"," (audit volume is tiny next to product telemetry — keep them separate so retention costs don't explode), ",[785,794,795],{},"permissions"," (the audit dataset should be read-only for engineers and write-only for the app), and ",[785,798,799],{},"retention"," (audits often live 7+ years; product logs rarely live more than 90 days).",[512,802,803,806,807,810,811,814],{},[516,804,805],{},"auditOnly(drain)"," only forwards events with an ",[516,808,809],{},"audit"," field. Compose with ",[785,812,813],{},"any"," drain:",[545,816,818],{"className":547,"code":817,"language":550,"meta":551,"style":551},"import { auditOnly } from 'evlog'\nimport { createAxiomDrain } from 'evlog\u002Faxiom'\n\n\u002F\u002F Send audits to a dedicated Axiom dataset:\nnitro.hooks.hook('evlog:drain', auditOnly(\n  createAxiomDrain({ dataset: 'audit', apiKey: process.env.AXIOM_AUDIT_API_KEY }),\n))\n",[516,819,820,839,859,863,869,898,947],{"__ignoreMap":551},[555,821,822,824,826,829,831,833,835,837],{"class":557,"line":558},[555,823,562],{"class":561},[555,825,566],{"class":565},[555,827,828],{"class":569}," auditOnly",[555,830,573],{"class":565},[555,832,576],{"class":561},[555,834,579],{"class":565},[555,836,583],{"class":582},[555,838,586],{"class":565},[555,840,841,843,845,848,850,852,854,857],{"class":557,"line":589},[555,842,562],{"class":561},[555,844,566],{"class":565},[555,846,847],{"class":569}," createAxiomDrain",[555,849,573],{"class":565},[555,851,576],{"class":561},[555,853,579],{"class":565},[555,855,856],{"class":582},"evlog\u002Faxiom",[555,858,586],{"class":565},[555,860,861],{"class":557,"line":596},[555,862,593],{"emptyLinePlaceholder":592},[555,864,865],{"class":557,"line":750},[555,866,868],{"class":867},"sHwdD","\u002F\u002F Send audits to a dedicated Axiom dataset:\n",[555,870,872,874,876,878,880,882,884,886,889,891,893,895],{"class":557,"line":871},5,[555,873,599],{"class":569},[555,875,602],{"class":565},[555,877,605],{"class":569},[555,879,602],{"class":565},[555,881,611],{"class":610},[555,883,614],{"class":569},[555,885,617],{"class":565},[555,887,888],{"class":582},"evlog:drain",[555,890,617],{"class":565},[555,892,625],{"class":565},[555,894,828],{"class":610},[555,896,897],{"class":569},"(\n",[555,899,901,904,906,909,912,914,916,918,920,922,925,927,930,932,935,937,940,942,945],{"class":557,"line":900},6,[555,902,903],{"class":610},"  createAxiomDrain",[555,905,614],{"class":569},[555,907,908],{"class":565},"{",[555,910,911],{"class":716}," dataset",[555,913,675],{"class":565},[555,915,579],{"class":565},[555,917,809],{"class":582},[555,919,617],{"class":565},[555,921,625],{"class":565},[555,923,924],{"class":716}," apiKey",[555,926,675],{"class":565},[555,928,929],{"class":569}," process",[555,931,602],{"class":565},[555,933,934],{"class":569},"env",[555,936,602],{"class":565},[555,938,939],{"class":569},"AXIOM_AUDIT_API_KEY ",[555,941,753],{"class":565},[555,943,944],{"class":569},")",[555,946,711],{"class":565},[555,948,950],{"class":557,"line":949},7,[555,951,756],{"class":569},[512,953,954,955,958],{},"Set ",[516,956,957],{},"await: true"," to make audit writes synchronous (no fire-and-forget for audits — crash-safe by default):",[545,960,962],{"className":547,"code":961,"language":550,"meta":551,"style":551},"auditOnly(createFsDrain({ dir: '.audit' }), { await: true })\n",[516,963,964],{"__ignoreMap":551},[555,965,966,968,970,973,975,977,980,982,984,987,989,991,993,995,997,1000,1002,1006,1008],{"class":557,"line":558},[555,967,522],{"class":610},[555,969,614],{"class":569},[555,971,972],{"class":610},"createFsDrain",[555,974,614],{"class":569},[555,976,908],{"class":565},[555,978,979],{"class":716}," dir",[555,981,675],{"class":565},[555,983,579],{"class":565},[555,985,986],{"class":582},".audit",[555,988,617],{"class":565},[555,990,573],{"class":565},[555,992,944],{"class":569},[555,994,625],{"class":565},[555,996,566],{"class":565},[555,998,999],{"class":716}," await",[555,1001,675],{"class":565},[555,1003,1005],{"class":1004},"sfNiH"," true",[555,1007,573],{"class":565},[555,1009,1010],{"class":569},")\n",[512,1012,1013,1014,1016],{},"The ",[516,1015,957],{}," flag costs you a small bit of latency per request that records an audit (one synchronous drain call), but guarantees the audit hits disk before the response is sent. For compliance-grade audits, the trade-off is always worth it.",[529,1018,1019],{"id":526},[516,1020,1021],{},"signed()",[512,1023,1024,1027],{},[516,1025,1026],{},"signed(drain, opts)"," adds tamper-evident integrity. Two strategies:",[1029,1030,1031,1047],"table",{},[1032,1033,1034],"thead",{},[1035,1036,1037,1041,1044],"tr",{},[1038,1039,1040],"th",{},"Strategy",[1038,1042,1043],{},"What it adds",[1038,1045,1046],{},"Use case",[1048,1049,1050,1067],"tbody",{},[1035,1051,1052,1058,1064],{},[1053,1054,1055],"td",{},[516,1056,1057],{},"'hmac'",[1053,1059,1060,1063],{},[516,1061,1062],{},"event.audit.signature"," (HMAC of the canonical event)",[1053,1065,1066],{},"Single-event integrity check (any later mutation fails verification).",[1035,1068,1069,1074,1082],{},[1053,1070,1071],{},[516,1072,1073],{},"'hash-chain'",[1053,1075,1076,770,1079],{},[516,1077,1078],{},"event.audit.prevHash",[516,1080,1081],{},"event.audit.hash",[1053,1083,1084],{},"A verifiable chain — deletions and reordering also become detectable.",[782,1086,1087,1093,1094,1098,1099,1101],{},[785,1088,1089,1090,1092],{},"What ",[516,1091,1021],{}," actually buys you."," Detection, not prevention. Anyone with write access to the underlying sink can still nuke the file or table — but the chain proves ",[1095,1096,1097],"em",{},"which"," events were dropped or modified after the fact. Skip ",[516,1100,1021],{}," if you already write to an append-only \u002F WORM store (S3 Object Lock, Postgres with row-level immutability, BigQuery append-only tables); doubling integrity layers just adds latency without raising the bar.",[1103,1104,1106],"h3",{"id":1105},"hmac","HMAC",[512,1108,1109],{},"Each event gets a signature. Tampering with one row breaks that row's verification, but doesn't break later rows.",[545,1111,1113],{"className":547,"code":1112,"language":550,"meta":551,"style":551},"import { signed } from 'evlog'\n\nsigned(drain, { strategy: 'hmac', secret: process.env.AUDIT_SECRET! })\n",[516,1114,1115,1134,1138],{"__ignoreMap":551},[555,1116,1117,1119,1121,1124,1126,1128,1130,1132],{"class":557,"line":558},[555,1118,562],{"class":561},[555,1120,566],{"class":565},[555,1122,1123],{"class":569}," signed",[555,1125,573],{"class":565},[555,1127,576],{"class":561},[555,1129,579],{"class":565},[555,1131,583],{"class":582},[555,1133,586],{"class":565},[555,1135,1136],{"class":557,"line":589},[555,1137,593],{"emptyLinePlaceholder":592},[555,1139,1140,1142,1145,1147,1149,1152,1154,1156,1158,1160,1162,1165,1167,1169,1171,1173,1175,1178,1181,1183],{"class":557,"line":596},[555,1141,526],{"class":610},[555,1143,1144],{"class":569},"(drain",[555,1146,625],{"class":565},[555,1148,566],{"class":565},[555,1150,1151],{"class":716}," strategy",[555,1153,675],{"class":565},[555,1155,579],{"class":565},[555,1157,1105],{"class":582},[555,1159,617],{"class":565},[555,1161,625],{"class":565},[555,1163,1164],{"class":716}," secret",[555,1166,675],{"class":565},[555,1168,929],{"class":569},[555,1170,602],{"class":565},[555,1172,934],{"class":569},[555,1174,602],{"class":565},[555,1176,1177],{"class":569},"AUDIT_SECRET",[555,1179,1180],{"class":565},"!",[555,1182,573],{"class":565},[555,1184,1010],{"class":569},[1103,1186,1188],{"id":1187},"hash-chain","Hash-chain",[512,1190,1191],{},"Each event references the previous event's hash. Deleting any row breaks the chain forward of that point, so the verifier can pinpoint the exact row that was tampered with.",[545,1193,1195],{"className":547,"code":1194,"language":550,"meta":551,"style":551},"signed(drain, {\n  strategy: 'hash-chain',\n  state: {\n    load: () => fs.readFile('.audit\u002Fhead', 'utf8').catch(() => null),\n    save: (h) => fs.writeFile('.audit\u002Fhead', h),\n  },\n})\n",[516,1196,1197,1208,1223,1232,1291,1330,1335],{"__ignoreMap":551},[555,1198,1199,1201,1203,1205],{"class":557,"line":558},[555,1200,526],{"class":610},[555,1202,1144],{"class":569},[555,1204,625],{"class":565},[555,1206,1207],{"class":565}," {\n",[555,1209,1210,1213,1215,1217,1219,1221],{"class":557,"line":589},[555,1211,1212],{"class":716},"  strategy",[555,1214,675],{"class":565},[555,1216,579],{"class":565},[555,1218,1187],{"class":582},[555,1220,617],{"class":565},[555,1222,711],{"class":565},[555,1224,1225,1228,1230],{"class":557,"line":596},[555,1226,1227],{"class":716},"  state",[555,1229,675],{"class":565},[555,1231,1207],{"class":565},[555,1233,1234,1237,1239,1242,1244,1247,1249,1252,1254,1256,1259,1261,1263,1265,1268,1270,1272,1274,1277,1279,1282,1284,1287,1289],{"class":557,"line":750},[555,1235,1236],{"class":610},"    load",[555,1238,675],{"class":565},[555,1240,1241],{"class":565}," ()",[555,1243,683],{"class":682},[555,1245,1246],{"class":569}," fs",[555,1248,602],{"class":565},[555,1250,1251],{"class":610},"readFile",[555,1253,614],{"class":569},[555,1255,617],{"class":565},[555,1257,1258],{"class":582},".audit\u002Fhead",[555,1260,617],{"class":565},[555,1262,625],{"class":565},[555,1264,579],{"class":565},[555,1266,1267],{"class":582},"utf8",[555,1269,617],{"class":565},[555,1271,944],{"class":569},[555,1273,602],{"class":565},[555,1275,1276],{"class":610},"catch",[555,1278,614],{"class":569},[555,1280,1281],{"class":565},"()",[555,1283,683],{"class":682},[555,1285,1286],{"class":565}," null",[555,1288,944],{"class":569},[555,1290,711],{"class":565},[555,1292,1293,1296,1298,1301,1304,1306,1308,1310,1312,1315,1317,1319,1321,1323,1325,1328],{"class":557,"line":871},[555,1294,1295],{"class":610},"    save",[555,1297,675],{"class":565},[555,1299,1300],{"class":565}," (",[555,1302,1303],{"class":678},"h",[555,1305,944],{"class":565},[555,1307,683],{"class":682},[555,1309,1246],{"class":569},[555,1311,602],{"class":565},[555,1313,1314],{"class":610},"writeFile",[555,1316,614],{"class":569},[555,1318,617],{"class":565},[555,1320,1258],{"class":582},[555,1322,617],{"class":565},[555,1324,625],{"class":565},[555,1326,1327],{"class":569}," h)",[555,1329,711],{"class":565},[555,1331,1332],{"class":557,"line":900},[555,1333,1334],{"class":565},"  },\n",[555,1336,1337,1339],{"class":557,"line":949},[555,1338,753],{"class":565},[555,1340,1010],{"class":569},[512,1342,1013,1343,1346],{},[516,1344,1345],{},"state"," config is required for cross-process or durable chains: load the previous head hash from your own store (Redis, Postgres, file) before each event, save the new head after.",[1348,1349],"hash-chain-tamper",{},[1351,1352,1353,1354,1357,1358,1361,1362,602],"note",{},"A CLI to walk and verify the chain (",[516,1355,1356],{},"evlog audit verify",") is on the roadmap. Until then, validate by recomputing the hashes of stored events and comparing each ",[516,1359,1360],{},"prevHash"," against the previous event's ",[516,1363,1364],{},"hash",[1366,1367,1368],"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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 .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 pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}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 .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":551,"searchDepth":589,"depth":589,"links":1370},[1371,1372,1373],{"id":531,"depth":589,"text":534},{"id":777,"depth":589,"text":780},{"id":526,"depth":589,"text":1021,"children":1374},[1375,1376],{"id":1105,"depth":596,"text":1106},{"id":1187,"depth":596,"text":1188},"auditEnricher to auto-fill request context, auditOnly to route audits to a dedicated sink, and signed for tamper-evident HMAC or hash-chain integrity.","md",[1380,1383],{"label":372,"icon":375,"to":373,"color":1381,"variant":1382},"neutral","subtle",{"label":382,"icon":359,"to":383,"color":1381,"variant":1382},{},{"title":377,"icon":380},{"title":507,"description":1377},"3WNlOjtJ5lfdHjYt6yZU7XwwlUIN95fS3mx0giockts",[1389,1391],{"title":372,"path":373,"stem":374,"description":1390,"icon":375,"children":-1},"log.audit, log.audit.deny, standalone audit(), withAudit auto-instrumentation, defineAuditAction and defineAuditCatalog registries, and auditDiff change patches.",{"title":382,"path":383,"stem":384,"description":1392,"icon":359,"children":-1},"Integrity, redact presets, GDPR vs append-only, retention windows, and the most common pitfalls when shipping audit logs to production.",1785229774265]