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