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