[{"data":1,"prerenderedAt":1449},["ShallowReactive",2],{"navigation_docs":3,"-start-why-evlog":429,"-start-why-evlog-surround":1444},[4,30,80,235,343,398],{"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},"Integrate","\u002Fintegrate","3.integrate",[85,89,152],{"title":36,"path":86,"stem":87,"icon":88},"\u002Fintegrate\u002Foverview","3.integrate\u002F0.overview","i-lucide-plug",{"title":90,"path":91,"stem":92,"children":93,"page":29},"Adapters","\u002Fintegrate\u002Fadapters","3.integrate\u002Fadapters",[94,97,137],{"title":36,"path":95,"stem":96,"icon":39},"\u002Fintegrate\u002Fadapters\u002Foverview","3.integrate\u002Fadapters\u002F01.overview",{"title":98,"path":99,"stem":100,"children":101,"page":29},"Cloud","\u002Fintegrate\u002Fadapters\u002Fcloud","3.integrate\u002Fadapters\u002Fcloud",[102,107,112,117,122,127,132],{"title":103,"path":104,"stem":105,"icon":106},"Axiom","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Faxiom","3.integrate\u002Fadapters\u002Fcloud\u002F01.axiom","i-custom-axiom",{"title":108,"path":109,"stem":110,"icon":111},"OTLP","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fotlp","3.integrate\u002Fadapters\u002Fcloud\u002F02.otlp","i-simple-icons-opentelemetry",{"title":113,"path":114,"stem":115,"icon":116},"PostHog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fposthog","3.integrate\u002Fadapters\u002Fcloud\u002F03.posthog","i-simple-icons-posthog",{"title":118,"path":119,"stem":120,"icon":121},"Sentry","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fsentry","3.integrate\u002Fadapters\u002Fcloud\u002F04.sentry","i-simple-icons-sentry",{"title":123,"path":124,"stem":125,"icon":126},"Better Stack","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fbetter-stack","3.integrate\u002Fadapters\u002Fcloud\u002F05.better-stack","i-simple-icons-betterstack",{"title":128,"path":129,"stem":130,"icon":131},"Datadog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fdatadog","3.integrate\u002Fadapters\u002Fcloud\u002F06.datadog","i-simple-icons-datadog",{"title":133,"path":134,"stem":135,"icon":136},"HyperDX","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fhyperdx","3.integrate\u002Fadapters\u002Fcloud\u002F07.hyperdx","i-custom-hyperdx",{"title":138,"path":139,"stem":140,"children":141,"page":29},"Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fself-hosted","3.integrate\u002Fadapters\u002Fself-hosted",[142,147],{"title":143,"path":144,"stem":145,"icon":146},"File System","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Ffs","3.integrate\u002Fadapters\u002Fself-hosted\u002F01.fs","i-lucide-hard-drive",{"title":148,"path":149,"stem":150,"icon":151},"NuxtHub","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fnuxthub","3.integrate\u002Fadapters\u002Fself-hosted\u002F02.nuxthub","i-simple-icons-nuxt",{"title":153,"path":154,"stem":155,"children":156,"page":29},"Frameworks","\u002Fintegrate\u002Fframeworks","3.integrate\u002Fframeworks",[157,161,166,171,176,181,186,191,196,201,206,211,216,221,225,230],{"title":36,"path":158,"stem":159,"icon":160},"\u002Fintegrate\u002Fframeworks\u002Foverview","3.integrate\u002Fframeworks\u002F00.overview","i-lucide-layout-grid",{"title":162,"path":163,"stem":164,"icon":165},"Nuxt","\u002Fintegrate\u002Fframeworks\u002Fnuxt","3.integrate\u002Fframeworks\u002F01.nuxt","i-simple-icons-nuxtdotjs",{"title":167,"path":168,"stem":169,"icon":170},"Next.js","\u002Fintegrate\u002Fframeworks\u002Fnextjs","3.integrate\u002Fframeworks\u002F02.nextjs","i-simple-icons-nextdotjs",{"title":172,"path":173,"stem":174,"icon":175},"SvelteKit","\u002Fintegrate\u002Fframeworks\u002Fsveltekit","3.integrate\u002Fframeworks\u002F03.sveltekit","i-simple-icons-svelte",{"title":177,"path":178,"stem":179,"icon":180},"Nitro","\u002Fintegrate\u002Fframeworks\u002Fnitro","3.integrate\u002Fframeworks\u002F04.nitro","i-custom-nitro",{"title":182,"path":183,"stem":184,"icon":185},"TanStack Start","\u002Fintegrate\u002Fframeworks\u002Ftanstack-start","3.integrate\u002Fframeworks\u002F05.tanstack-start","i-custom-tanstack",{"title":187,"path":188,"stem":189,"icon":190},"NestJS","\u002Fintegrate\u002Fframeworks\u002Fnestjs","3.integrate\u002Fframeworks\u002F06.nestjs","i-simple-icons-nestjs",{"title":192,"path":193,"stem":194,"icon":195},"Express","\u002Fintegrate\u002Fframeworks\u002Fexpress","3.integrate\u002Fframeworks\u002F07.express","i-simple-icons-express",{"title":197,"path":198,"stem":199,"icon":200},"Hono","\u002Fintegrate\u002Fframeworks\u002Fhono","3.integrate\u002Fframeworks\u002F08.hono","i-simple-icons-hono",{"title":202,"path":203,"stem":204,"icon":205},"Fastify","\u002Fintegrate\u002Fframeworks\u002Ffastify","3.integrate\u002Fframeworks\u002F09.fastify","i-simple-icons-fastify",{"title":207,"path":208,"stem":209,"icon":210},"Elysia","\u002Fintegrate\u002Fframeworks\u002Felysia","3.integrate\u002Fframeworks\u002F10.elysia","i-custom-elysia",{"title":212,"path":213,"stem":214,"icon":215},"React Router","\u002Fintegrate\u002Fframeworks\u002Freact-router","3.integrate\u002Fframeworks\u002F11.react-router","i-custom-reactrouter",{"title":217,"path":218,"stem":219,"icon":220},"Cloudflare Workers","\u002Fintegrate\u002Fframeworks\u002Fcloudflare-workers","3.integrate\u002Fframeworks\u002F12.cloudflare-workers","i-simple-icons-cloudflare",{"title":222,"path":223,"stem":224,"icon":74},"Standalone","\u002Fintegrate\u002Fframeworks\u002Fstandalone","3.integrate\u002Fframeworks\u002F13.standalone",{"title":226,"path":227,"stem":228,"icon":229},"Astro","\u002Fintegrate\u002Fframeworks\u002Fastro","3.integrate\u002Fframeworks\u002F14.astro","i-simple-icons-astro",{"title":231,"path":232,"stem":233,"icon":234},"AWS Lambda","\u002Fintegrate\u002Fframeworks\u002Faws-lambda","3.integrate\u002Fframeworks\u002F16.aws-lambda","i-custom-lambda",{"title":236,"path":237,"stem":238,"children":239,"page":29},"Use Cases","\u002Fuse-cases","4.use-cases",[240,244,249,278,306,338],{"title":36,"path":241,"stem":242,"icon":243},"\u002Fuse-cases\u002Foverview","4.use-cases\u002F0.overview","i-lucide-list-checks",{"title":245,"path":246,"stem":247,"icon":248},"Client Logging","\u002Fuse-cases\u002Fclient-logging","4.use-cases\u002F1.client-logging","i-lucide-monitor",{"title":250,"icon":251,"path":252,"stem":253,"children":254,"page":29},"AI SDK","i-simple-icons-vercel","\u002Fuse-cases\u002Fai-sdk","4.use-cases\u002F2.ai-sdk",[255,258,263,268,273],{"title":36,"path":256,"stem":257,"icon":39},"\u002Fuse-cases\u002Fai-sdk\u002Foverview","4.use-cases\u002F2.ai-sdk\u002F01.overview",{"title":259,"path":260,"stem":261,"icon":262},"Usage","\u002Fuse-cases\u002Fai-sdk\u002Fusage","4.use-cases\u002F2.ai-sdk\u002F02.usage","i-lucide-code",{"title":264,"path":265,"stem":266,"icon":267},"Options","\u002Fuse-cases\u002Fai-sdk\u002Foptions","4.use-cases\u002F2.ai-sdk\u002F03.options","i-lucide-sliders",{"title":269,"path":270,"stem":271,"icon":272},"Metadata","\u002Fuse-cases\u002Fai-sdk\u002Fmetadata","4.use-cases\u002F2.ai-sdk\u002F04.metadata","i-lucide-database",{"title":274,"path":275,"stem":276,"icon":277},"Telemetry","\u002Fuse-cases\u002Fai-sdk\u002Ftelemetry","4.use-cases\u002F2.ai-sdk\u002F05.telemetry","i-lucide-activity",{"title":279,"icon":280,"path":281,"stem":282,"children":283,"page":29},"Better Auth","i-simple-icons-betterauth","\u002Fuse-cases\u002Fbetter-auth","4.use-cases\u002F3.better-auth",[284,287,292,297,301],{"title":36,"path":285,"stem":286,"icon":39},"\u002Fuse-cases\u002Fbetter-auth\u002Foverview","4.use-cases\u002F3.better-auth\u002F01.overview",{"title":288,"path":289,"stem":290,"icon":291},"Identify User","\u002Fuse-cases\u002Fbetter-auth\u002Fidentify-user","4.use-cases\u002F3.better-auth\u002F02.identify-user","i-lucide-user-check",{"title":293,"path":294,"stem":295,"icon":296},"Middleware","\u002Fuse-cases\u002Fbetter-auth\u002Fmiddleware","4.use-cases\u002F3.better-auth\u002F03.middleware","i-lucide-shield",{"title":298,"path":299,"stem":300,"icon":248},"Client Sync","\u002Fuse-cases\u002Fbetter-auth\u002Fclient-sync","4.use-cases\u002F3.better-auth\u002F04.client-sync",{"title":302,"path":303,"stem":304,"icon":305},"Performance","\u002Fuse-cases\u002Fbetter-auth\u002Fperformance","4.use-cases\u002F3.better-auth\u002F05.performance","i-lucide-gauge",{"title":307,"icon":308,"path":309,"stem":310,"children":311,"page":29},"Audit Logs","i-lucide-shield-check","\u002Fuse-cases\u002Faudit","4.use-cases\u002F4.audit",[312,315,320,325,330,334],{"title":36,"path":313,"stem":314,"icon":39},"\u002Fuse-cases\u002Faudit\u002Foverview","4.use-cases\u002F4.audit\u002F01.overview",{"title":316,"path":317,"stem":318,"icon":319},"Schema","\u002Fuse-cases\u002Faudit\u002Fschema","4.use-cases\u002F4.audit\u002F02.schema","i-lucide-file-text",{"title":321,"path":322,"stem":323,"icon":324},"Recording","\u002Fuse-cases\u002Faudit\u002Frecording","4.use-cases\u002F4.audit\u002F03.recording","i-lucide-pen-line",{"title":326,"path":327,"stem":328,"icon":329},"Drains","\u002Fuse-cases\u002Faudit\u002Fpipeline","4.use-cases\u002F4.audit\u002F04.pipeline","i-lucide-link",{"title":331,"path":332,"stem":333,"icon":308},"Compliance","\u002Fuse-cases\u002Faudit\u002Fcompliance","4.use-cases\u002F4.audit\u002F05.compliance",{"title":335,"path":336,"stem":337,"icon":79},"Recipes","\u002Fuse-cases\u002Faudit\u002Frecipes","4.use-cases\u002F4.audit\u002F06.recipes",{"title":339,"path":340,"stem":341,"icon":342},"Enrichers","\u002Fuse-cases\u002Fenrichers","4.use-cases\u002F5.enrichers","i-lucide-sparkles",{"title":344,"path":345,"stem":346,"children":347,"page":29},"Extend","\u002Fextend","5.extend",[348,352,357,362,367,371,375,379,383,388,393],{"title":36,"path":349,"stem":350,"icon":351},"\u002Fextend\u002Foverview","5.extend\u002F0.overview","i-lucide-blocks",{"title":353,"path":354,"stem":355,"icon":356},"Stream","\u002Fextend\u002Fstream","5.extend\u002F1.stream","i-lucide-radio-tower",{"title":358,"path":359,"stem":360,"icon":361},"Custom framework","\u002Fextend\u002Fcustom-framework","5.extend\u002F10.custom-framework","i-lucide-puzzle",{"title":363,"path":364,"stem":365,"icon":366},"FS reader","\u002Fextend\u002Ffs-reader","5.extend\u002F2.fs-reader","i-lucide-folder-search",{"title":335,"path":368,"stem":369,"icon":370},"\u002Fextend\u002Fconsumer-recipes","5.extend\u002F3.consumer-recipes","i-lucide-chef-hat",{"title":372,"path":373,"stem":374,"icon":351},"Plugins","\u002Fextend\u002Fplugins","5.extend\u002F4.plugins",{"title":376,"path":377,"stem":378,"icon":342},"Custom enrichers","\u002Fextend\u002Fcustom-enrichers","5.extend\u002F5.custom-enrichers",{"title":380,"path":381,"stem":382,"icon":64},"Tail sampling","\u002Fextend\u002Ftail-sampling","5.extend\u002F6.tail-sampling",{"title":384,"path":385,"stem":386,"icon":387},"Identity headers","\u002Fextend\u002Fidentity-headers","5.extend\u002F7.identity-headers","i-lucide-fingerprint",{"title":389,"path":390,"stem":391,"icon":392},"Custom drains","\u002Fextend\u002Fcustom-drains","5.extend\u002F8.custom-drains","i-lucide-share-2",{"title":394,"path":395,"stem":396,"icon":397},"Drain pipeline","\u002Fextend\u002Fdrain-pipeline","5.extend\u002F9.drain-pipeline","i-lucide-workflow",{"title":399,"path":400,"stem":401,"children":402,"page":29},"Reference","\u002Freference","6.reference",[403,408,411,416,420,425],{"title":404,"path":405,"stem":406,"icon":407},"Configuration","\u002Freference\u002Fconfiguration","6.reference\u002F1.configuration","i-lucide-settings",{"title":302,"path":409,"stem":410,"icon":305},"\u002Freference\u002Fperformance","6.reference\u002F2.performance",{"title":412,"path":413,"stem":414,"icon":415},"Vite Plugin","\u002Freference\u002Fvite-plugin","6.reference\u002F3.vite-plugin","i-custom-vite",{"title":417,"path":418,"stem":419,"icon":308},"Best Practices","\u002Freference\u002Fbest-practices","6.reference\u002F4.best-practices",{"title":421,"path":422,"stem":423,"icon":424},"vs Other Loggers","\u002Freference\u002Fvs-other-loggers","6.reference\u002F5.vs-other-loggers","i-lucide-scale",{"title":426,"path":427,"stem":428,"icon":342},"Agent Skills","\u002Freference\u002Fagent-skills","6.reference\u002F6.agent-skills",{"id":430,"title":15,"body":431,"description":1431,"extension":1432,"links":1433,"meta":1440,"navigation":1441,"path":16,"seo":1442,"stem":17,"__hash__":1443},"docs\u002F1.start\u002F2.why-evlog.md",{"type":432,"value":433,"toc":1418},"minimark",[434,448,462,467,470,475,533,537,540,553,573,591,605,622,629,633,636,801,811,819,823,829,889,899,903,910,933,949,953,957,964,1157,1179,1183,1189,1238,1241,1285,1291,1295,1360,1364,1414],[435,436,437,438,442,443,447],"p",{},"The cheapest moment to add structured logging is ",[439,440,441],"strong",{},"before the first request",". By the time you have 200 routes, 40 background jobs, and a ",[444,445,446],"code",{},"console.log"," per file, you're paying interest on a decision you never made. evlog is designed for the day-zero choice — pick it once, and the rest of the system inherits structured logs, structured errors, typed catalogs, AI SDK telemetry, an audit trail, and a drain pipeline you don't have to build later.",[449,450,453,454,456,457,461],"callout",{"color":451,"icon":452},"neutral","i-lucide-arrow-right","Already shipping with ",[444,455,446],{}," or pino? evlog still wins, but the case is different — see ",[458,459,460],"a",{"href":422},"evlog vs pino, winston, consola",".",[463,464,466],"h2",{"id":465},"what-you-get-from-day-one","What you get from day one",[435,468,469],{},"evlog isn't a small primitive you wrap. It's a single dependency that comes with a structured surface, an ecosystem of integrations, and an opinionated drain pipeline — all on by default.",[471,472,474],"h3",{"id":473},"logging-primitives","Logging primitives",[476,477,478,485,503,509,523,530],"card-group",{},[479,480,482,483,461],"card",{"icon":296,"title":481},"Auto-redaction","PII (emails, cards, IPs, phone numbers, JWTs, Bearer tokens, IBANs) is masked before console output and before any drain. See ",[458,484,66],{"href":67},[479,486,488,489,492,493,496,497,500,501,461],{"icon":54,"title":487},"Structured errors","Every error already carries ",[444,490,491],{},"why",", ",[444,494,495],{},"fix",", and ",[444,498,499],{},"link"," for your on-call (and your future AI agent). See ",[458,502,51],{"href":52},[479,504,506,507,461],{"icon":49,"title":505},"Wide events","Accumulate context across an operation and emit one typed event when it ends — the observability pattern that makes requests, jobs, and workflows queryable end-to-end. See ",[458,508,46],{"href":47},[479,510,513,516,517,520,521,461],{"icon":511,"title":512},"i-lucide-book-marked","Typed catalogs",[444,514,515],{},"defineErrorCatalog"," and ",[444,518,519],{},"defineAuditCatalog"," give you enum-like, refactor-safe codes and actions. Start with two entries, grow to a published package. See ",[458,522,76],{"href":77},[479,524,527,528,461],{"icon":525,"title":526},"i-lucide-percent","Head + tail sampling","Drop low-importance events at emit time, force-keep slow requests and errors. Configure once, scale forever. See ",[458,529,61],{"href":62},[479,531,532],{"icon":272,"title":394},"Built-in batching, retry with exponential backoff, fan-out to multiple destinations. No transport glue to write yourself.",[471,534,536],{"id":535},"beyond-the-logger","Beyond the logger",[435,538,539],{},"The primitives are table stakes — every modern logger has some flavour of them. Where evlog earns its place on day 1 is everything wired around them, for problems you haven't had yet.",[435,541,542,545,546,549,550,552],{},[439,543,544],{},"Imagine you add AI to your app."," Sooner or later you wire the Vercel AI SDK into a route. Token costs surprise you, a model hangs mid-stream, a tool returns garbage. With the ",[458,547,548],{"href":256},"AI SDK integration",", every model call becomes a wide event with prompt, tools, tokens, latency, and cost — automatically. And if you're using ",[458,551,279],{"href":285},", evlog ties the actor identity to those events for you, so you can answer \"which user just burned $14 in a single conversation?\" without writing a line of plumbing.",[435,554,555,558,559,562,563,492,566,492,569,572],{},[439,556,557],{},"Imagine your stack spans more than one framework."," A Nuxt frontend, a Hono internal service, an AWS Lambda webhook — most teams end up with this kind of mix. evlog has ",[458,560,561],{"href":158},"13+ framework integrations"," and each one exposes the same logging primitives (",[444,564,565],{},"useLogger",[444,567,568],{},"log.set",[444,570,571],{},"createError","). The handlers themselves stay framework-shaped — that part is on you — but you don't relearn a logger every time you cross a runtime, and the drain pipeline behind them stays the same.",[435,574,575,578,579,582,583,586,587,590],{},[439,576,577],{},"Imagine you want noisier logs in dev than in production."," During local development you sprinkle ",[444,580,581],{},"log.debug"," calls — full request bodies, every retry, every guard — to actually see what's happening. None of that should ship. The ",[458,584,585],{"href":413},"Vite plugin"," strips selected log levels at build time, so dev has the verbose context you want and production stays clean. As a bonus, every surviving call gets its source location (",[444,588,589],{},"file.ts:42",") injected automatically, so when an event lands in your dashboard you know exactly which line emitted it.",[435,592,593,596,597,600,601,604],{},[439,594,595],{},"Imagine a user reports a bug from their browser."," The error happened in their session, deep inside a fetch you can't reproduce. evlog's ",[458,598,599],{"href":246},"browser logger"," ships client events to your server, where they merge into the same wide event as the rest of the request — one typed event, regardless of where the error originated. Combine it with the ",[458,602,603],{"href":340},"built-in enrichers"," and you also get UA, GeoIP, and W3C trace context attached for free.",[435,606,607,610,611,614,615,618,619,621],{},[439,608,609],{},"Imagine your stack changes vendor."," You started with stdout, signed Axiom for queries, then your team wants Sentry for errors and PostHog for product analytics. With ",[458,612,613],{"href":95},"9+ drain adapters"," and built-in fan-out, those events land everywhere in parallel — the application code never moves. Self-hosting is a swap-in too, via the ",[458,616,617],{"href":144},"filesystem"," or ",[458,620,148],{"href":149}," adapters.",[435,623,624,625,628],{},"None of this is a \"v2 feature\" — it's the same package, on the same ",[444,626,627],{},"log"," API, on day 1.",[463,630,632],{"id":631},"catalogs-grow-with-you","Catalogs grow with you",[435,634,635],{},"The smallest useful catalog is two entries:",[637,638,644],"pre",{"className":639,"code":640,"filename":641,"language":642,"meta":643,"style":643},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { defineErrorCatalog } from 'evlog'\n\nexport const errors = defineErrorCatalog('billing', {\n  PAYMENT_DECLINED: { status: 402, message: 'Payment declined' },\n  INVOICE_NOT_FOUND: { status: 404, message: 'Invoice not found' },\n})\n","src\u002Ferrors.ts","typescript","",[444,645,646,679,686,722,760,792],{"__ignoreMap":643},[647,648,651,655,659,663,666,669,672,676],"span",{"class":649,"line":650},"line",1,[647,652,654],{"class":653},"s7zQu","import",[647,656,658],{"class":657},"sMK4o"," {",[647,660,662],{"class":661},"sTEyZ"," defineErrorCatalog",[647,664,665],{"class":657}," }",[647,667,668],{"class":653}," from",[647,670,671],{"class":657}," '",[647,673,675],{"class":674},"sfazB","evlog",[647,677,678],{"class":657},"'\n",[647,680,682],{"class":649,"line":681},2,[647,683,685],{"emptyLinePlaceholder":684},true,"\n",[647,687,689,692,696,699,702,705,708,711,714,716,719],{"class":649,"line":688},3,[647,690,691],{"class":653},"export",[647,693,695],{"class":694},"spNyl"," const",[647,697,698],{"class":661}," errors ",[647,700,701],{"class":657},"=",[647,703,662],{"class":704},"s2Zo4",[647,706,707],{"class":661},"(",[647,709,710],{"class":657},"'",[647,712,713],{"class":674},"billing",[647,715,710],{"class":657},[647,717,718],{"class":657},",",[647,720,721],{"class":657}," {\n",[647,723,725,729,732,734,737,739,743,745,748,750,752,755,757],{"class":649,"line":724},4,[647,726,728],{"class":727},"swJcz","  PAYMENT_DECLINED",[647,730,731],{"class":657},":",[647,733,658],{"class":657},[647,735,736],{"class":727}," status",[647,738,731],{"class":657},[647,740,742],{"class":741},"sbssI"," 402",[647,744,718],{"class":657},[647,746,747],{"class":727}," message",[647,749,731],{"class":657},[647,751,671],{"class":657},[647,753,754],{"class":674},"Payment declined",[647,756,710],{"class":657},[647,758,759],{"class":657}," },\n",[647,761,763,766,768,770,772,774,777,779,781,783,785,788,790],{"class":649,"line":762},5,[647,764,765],{"class":727},"  INVOICE_NOT_FOUND",[647,767,731],{"class":657},[647,769,658],{"class":657},[647,771,736],{"class":727},[647,773,731],{"class":657},[647,775,776],{"class":741}," 404",[647,778,718],{"class":657},[647,780,747],{"class":727},[647,782,731],{"class":657},[647,784,671],{"class":657},[647,786,787],{"class":674},"Invoice not found",[647,789,710],{"class":657},[647,791,759],{"class":657},[647,793,795,798],{"class":649,"line":794},6,[647,796,797],{"class":657},"}",[647,799,800],{"class":661},")\n",[435,802,803,804,807,808],{},"Six months later it has thirty entries, type augmentation gives you autocomplete on ",[444,805,806],{},"createError({ code })"," everywhere, and you ship it as a private npm package across your monorepo. ",[439,809,810],{},"Same pattern. No rewrite.",[435,812,813,814,816,817,461],{},"The same applies to audit catalogs (",[444,815,519],{},") — start with one action, grow into your compliance map. See ",[458,818,76],{"href":77},[463,820,822],{"id":821},"built-for-the-ai-coding-agent-era","Built for the AI-coding-agent era",[435,824,825,826],{},"More and more applications are built with AI coding agents — Cursor, Codex, Windsurf, Claude Code, Copilot. They're good at writing handlers; they're worse at debugging them. ",[439,827,828],{},"What they need is context.",[830,831,832,854,860,873,879],"ul",{},[833,834,835,845,846,849,850,853],"li",{},[439,836,837,838,840,841,840,843,461],{},"Structured errors with ",[444,839,491],{}," \u002F ",[444,842,495],{},[444,844,499],{}," A vague ",[444,847,848],{},"Error: failed"," is opaque; ",[444,851,852],{},"createError({ message, why, fix, link })"," is something an agent can read, summarise, or surface to the user without you wiring a translation layer.",[833,855,856,859],{},[439,857,858],{},"Wide events as a single source of truth per request."," One typed event the agent can reason about end-to-end — not log lines to grep across.",[833,861,862,865,866,492,869,872],{},[439,863,864],{},"Typed catalogs as an enum-like surface."," The agent doesn't invent error codes; it picks from ",[444,867,868],{},"errors.PAYMENT_DECLINED",[444,870,871],{},"audit.INVOICE_REFUND",", etc., with autocomplete from the catalog.",[833,874,875,878],{},[439,876,877],{},"AI SDK telemetry on every LLM call."," When the agent's own model calls fail, hallucinate, or burn budget, the wide event tells you which prompt, which tools, how many tokens, how much it cost.",[833,880,881,884,885,888],{},[439,882,883],{},"Agent skills built in."," evlog ships ",[458,886,887],{"href":427},"agent skills"," so Cursor \u002F Claude \u002F Windsurf already know how to wire it up — no manual prompt-engineering.",[449,890,893,894,898],{"color":891,"icon":892},"info","i-lucide-bot","If your team's velocity comes from AI coding agents, the quality of your logs ",[895,896,897],"em",{},"is"," the quality of their context window. Day 0 is when you set that ceiling.",[463,900,902],{"id":901},"audit-and-compliance-cheap-now-expensive-later","Audit and compliance: cheap now, expensive later",[435,904,905,906,909],{},"Every product eventually meets one of: GDPR data-export requests, SOC 2 readiness, HIPAA in healthtech, PCI in payments, or simply an incident review where someone asks ",[439,907,908],{},"\"who deleted that?\"",". There are two ways to get a trail:",[911,912,913,919],"ol",{},[833,914,915,918],{},[439,916,917],{},"The day-1000 way."," Stand up a parallel system. Decide on a schema. Backfill what you can. Reverse-engineer actor identity from request headers. Ship under deadline pressure. Hope nothing was missed.",[833,920,921,924,925,928,929,932],{},[439,922,923],{},"The day-0 way."," Add ",[444,926,927],{},"auditEnricher()"," and call ",[444,930,931],{},"log.audit({ action, actor, target })"," from any handler that touches state. evlog ships hash-chain integrity, retention, and force-keep past sampling — on top of the wide events you were already emitting.",[435,934,935,936,939,940,942,943,946,947,461],{},"evlog's audit layer is ",[439,937,938],{},"not a parallel system"," — it's the same ",[444,941,627],{}," you already use, with a reserved ",[444,944,945],{},"audit"," field. See ",[458,948,307],{"href":313},[449,950,952],{"color":951,"icon":308},"success","Teams in regulated verticals — fintech, healthtech, B2B SaaS — should treat day-0 audit logging as table stakes, not a v2 feature.",[463,954,956],{"id":955},"drain-agnostic-from-day-one","Drain-agnostic from day one",[435,958,959,960,963],{},"Your application code never depends on a vendor — it emits to the drain pipeline. On day 0 that's stdout in dev and a ",[458,961,962],{"href":144},"filesystem drain"," in CI. The day you decide to query logs:",[637,965,968],{"className":639,"code":966,"filename":967,"language":642,"meta":643,"style":643},"import { createAxiomDrain } from 'evlog\u002Fadapters\u002Faxiom'\nimport { createSentryDrain } from 'evlog\u002Fadapters\u002Fsentry'\n\nexport default defineNuxtConfig({\n  evlog: {\n    drain: {\n      adapters: [\n        createAxiomDrain({ token: '...', dataset: 'app' }),\n        createSentryDrain({ dsn: '...' }),\n      ],\n    },\n  },\n})\n","nuxt.config.ts",[444,969,970,990,1010,1014,1029,1038,1047,1058,1103,1130,1138,1144,1150],{"__ignoreMap":643},[647,971,972,974,976,979,981,983,985,988],{"class":649,"line":650},[647,973,654],{"class":653},[647,975,658],{"class":657},[647,977,978],{"class":661}," createAxiomDrain",[647,980,665],{"class":657},[647,982,668],{"class":653},[647,984,671],{"class":657},[647,986,987],{"class":674},"evlog\u002Fadapters\u002Faxiom",[647,989,678],{"class":657},[647,991,992,994,996,999,1001,1003,1005,1008],{"class":649,"line":681},[647,993,654],{"class":653},[647,995,658],{"class":657},[647,997,998],{"class":661}," createSentryDrain",[647,1000,665],{"class":657},[647,1002,668],{"class":653},[647,1004,671],{"class":657},[647,1006,1007],{"class":674},"evlog\u002Fadapters\u002Fsentry",[647,1009,678],{"class":657},[647,1011,1012],{"class":649,"line":688},[647,1013,685],{"emptyLinePlaceholder":684},[647,1015,1016,1018,1021,1024,1026],{"class":649,"line":724},[647,1017,691],{"class":653},[647,1019,1020],{"class":653}," default",[647,1022,1023],{"class":704}," defineNuxtConfig",[647,1025,707],{"class":661},[647,1027,1028],{"class":657},"{\n",[647,1030,1031,1034,1036],{"class":649,"line":762},[647,1032,1033],{"class":727},"  evlog",[647,1035,731],{"class":657},[647,1037,721],{"class":657},[647,1039,1040,1043,1045],{"class":649,"line":794},[647,1041,1042],{"class":727},"    drain",[647,1044,731],{"class":657},[647,1046,721],{"class":657},[647,1048,1050,1053,1055],{"class":649,"line":1049},7,[647,1051,1052],{"class":727},"      adapters",[647,1054,731],{"class":657},[647,1056,1057],{"class":661}," [\n",[647,1059,1061,1064,1066,1069,1072,1074,1076,1079,1081,1083,1086,1088,1090,1093,1095,1097,1100],{"class":649,"line":1060},8,[647,1062,1063],{"class":704},"        createAxiomDrain",[647,1065,707],{"class":661},[647,1067,1068],{"class":657},"{",[647,1070,1071],{"class":727}," token",[647,1073,731],{"class":657},[647,1075,671],{"class":657},[647,1077,1078],{"class":674},"...",[647,1080,710],{"class":657},[647,1082,718],{"class":657},[647,1084,1085],{"class":727}," dataset",[647,1087,731],{"class":657},[647,1089,671],{"class":657},[647,1091,1092],{"class":674},"app",[647,1094,710],{"class":657},[647,1096,665],{"class":657},[647,1098,1099],{"class":661},")",[647,1101,1102],{"class":657},",\n",[647,1104,1106,1109,1111,1113,1116,1118,1120,1122,1124,1126,1128],{"class":649,"line":1105},9,[647,1107,1108],{"class":704},"        createSentryDrain",[647,1110,707],{"class":661},[647,1112,1068],{"class":657},[647,1114,1115],{"class":727}," dsn",[647,1117,731],{"class":657},[647,1119,671],{"class":657},[647,1121,1078],{"class":674},[647,1123,710],{"class":657},[647,1125,665],{"class":657},[647,1127,1099],{"class":661},[647,1129,1102],{"class":657},[647,1131,1133,1136],{"class":649,"line":1132},10,[647,1134,1135],{"class":661},"      ]",[647,1137,1102],{"class":657},[647,1139,1141],{"class":649,"line":1140},11,[647,1142,1143],{"class":657},"    },\n",[647,1145,1147],{"class":649,"line":1146},12,[647,1148,1149],{"class":657},"  },\n",[647,1151,1153,1155],{"class":649,"line":1152},13,[647,1154,797],{"class":657},[647,1156,800],{"class":661},[435,1158,1159,1160,492,1162,492,1164,492,1166,492,1168,492,1170,1172,1173,1175,1176,461],{},"Zero handler changes. The same events land in ",[458,1161,103],{"href":104},[458,1163,128],{"href":129},[458,1165,113],{"href":114},[458,1167,118],{"href":119},[458,1169,123],{"href":124},[458,1171,133],{"href":134},", or ",[458,1174,108],{"href":109}," — or all of them, with ",[458,1177,1178],{"href":95},"fan-out",[463,1180,1182],{"id":1181},"what-later-actually-costs","What \"later\" actually costs",[435,1184,1185,1186,1188],{},"When teams ship with ",[444,1187,446],{}," and decide to add proper logging \"when we need it\", the bill comes due:",[830,1190,1191,1210,1216,1222],{},[833,1192,1193,1196,1197,492,1200,492,1203,1172,1206,1209],{},[439,1194,1195],{},"Settling field-name conventions after the fact."," Is it ",[444,1198,1199],{},"userId",[444,1201,1202],{},"user_id",[444,1204,1205],{},"uid",[444,1207,1208],{},"actor.id","? Once thirty services log it differently, you're writing migration scripts inside your observability vendor.",[833,1211,1212,1215],{},[439,1213,1214],{},"Bolting on redaction post-incident."," Auto-redaction is trivial when no log exists yet. It's a P1 audit when six months of logs already contain PII.",[833,1217,1218,1221],{},[439,1219,1220],{},"Choosing a drain under pressure."," Picking Datadog vs Axiom vs Sentry while you're already on fire is the worst time to evaluate vendors.",[833,1223,1224,1227,1228,1231,1232,1234,1235,1237],{},[439,1225,1226],{},"Adding actionable error context retroactively."," Every ",[444,1229,1230],{},"throw new Error('failed')"," you wrote is one less ",[444,1233,491],{},", one less ",[444,1236,495],{},", one less link your on-call (or your AI agent) can use.",[435,1239,1240],{},"evlog removes the \"later\" entirely — the structured surface, the wide event lifecycle, and the drain pipeline are all there from day 1.",[1242,1243,1244,1257],"table",{},[1245,1246,1247],"thead",{},[1248,1249,1250,1254],"tr",{},[1251,1252,1253],"th",{},"Decision day",[1251,1255,1256],{},"Cost to adopt evlog",[1258,1259,1260,1269,1277],"tbody",{},[1248,1261,1262,1266],{},[1263,1264,1265],"td",{},"Day 0 (greenfield)",[1263,1267,1268],{},"Add the framework module. Done.",[1248,1270,1271,1274],{},[1263,1272,1273],{},"Day 30 (small app)",[1263,1275,1276],{},"Switch the logger surface — about a day of work.",[1248,1278,1279,1282],{},[1263,1280,1281],{},"Day 365 (production app)",[1263,1283,1284],{},"Walk the codebase to swap loggers, settle field-name conventions, fold in audit and redaction. The same cost as migrating between any two structured loggers.",[435,1286,1287,1288],{},"The asymmetry is the point. ",[439,1289,1290],{},"Start with evlog because the cost is zero. Stay with evlog because the cost of leaving is higher than building any of this yourself.",[463,1292,1294],{"id":1293},"day-0-in-practice","Day 0, in practice",[1296,1297,1300,1303,1332],"prompt",{":actions":1298,"description":1299,"icon":18},"[\"copy\",\"cursor\",\"windsurf\"]","Start a new project with evlog wired in from the first commit",[435,1301,1302],{},"I'm starting a new project. Wire in evlog from the first commit so I never have to retrofit logging.",[830,1304,1305,1308,1311,1314,1317,1320,1323,1326,1329],{},[833,1306,1307],{},"Detect my framework and install the matching evlog integration (Nuxt, Next.js, SvelteKit, Hono, Express, etc.)",[833,1309,1310],{},"Set evlog.env.service to my app name and enable redact: true",[833,1312,1313],{},"Add a useLogger(event) call in one route handler with log.set({ user, action }) so I have a working wide event from the start",[833,1315,1316],{},"Throw one createError({ message, status, why, fix }) for an invalid input case",[833,1318,1319],{},"Create a tiny errors catalog with defineErrorCatalog('app', { ... }) — start with two entries, grow over time",[833,1321,1322],{},"If the project uses Vercel AI SDK, wire the AI SDK middleware so every LLM call records tokens, tools, and cost",[833,1324,1325],{},"If the project uses Better Auth, install the Better Auth plugin so auth events are typed from day 1",[833,1327,1328],{},"Configure a filesystem drain for local dev (.evlog\u002Flogs) and leave the cloud drain commented out, ready to enable",[833,1330,1331],{},"If my project is in a regulated vertical (fintech \u002F healthtech \u002F B2B SaaS), also wire the audit enricher with defineAuditCatalog",[435,1333,1334,1335,1340,1341,1345,1346,1350,1351,1355,1356],{},"Docs: ",[458,1336,1337],{"href":1337,"rel":1338},"https:\u002F\u002Fwww.evlog.dev\u002Fstart\u002Fwhy-evlog",[1339],"nofollow","\nFrameworks: ",[458,1342,1343],{"href":1343,"rel":1344},"https:\u002F\u002Fwww.evlog.dev\u002Fintegrate\u002Fframeworks\u002Foverview",[1339],"\nCatalogs: ",[458,1347,1348],{"href":1348,"rel":1349},"https:\u002F\u002Fwww.evlog.dev\u002Flearn\u002Fcatalogs",[1339],"\nAI SDK: ",[458,1352,1353],{"href":1353,"rel":1354},"https:\u002F\u002Fwww.evlog.dev\u002Fuse-cases\u002Fai-sdk\u002Foverview",[1339],"\nAudit: ",[458,1357,1358],{"href":1358,"rel":1359},"https:\u002F\u002Fwww.evlog.dev\u002Fuse-cases\u002Faudit\u002Foverview",[1339],[463,1361,1363],{"id":1362},"next-steps","Next steps",[830,1365,1366,1371,1384,1389,1394,1399,1404,1409],{},[833,1367,1368,1370],{},[458,1369,20],{"href":21}," — pick your framework",[833,1372,1373,1375,1376,492,1378,492,1381,1383],{},[458,1374,25],{"href":26}," — ",[444,1377,565],{},[444,1379,1380],{},"createLogger",[444,1382,571],{}," in 2 minutes",[833,1385,1386,1388],{},[458,1387,76],{"href":77}," — typed errors and audit actions, day-0 to monorepo-scale",[833,1390,1391,1393],{},[458,1392,307],{"href":313}," — day-0 compliance posture",[833,1395,1396,1398],{},[458,1397,250],{"href":256}," — token usage, tool calls, streaming metrics",[833,1400,1401,1403],{},[458,1402,279],{"href":285}," — auth events with one-line install",[833,1405,1406,1408],{},[458,1407,417],{"href":418}," — what not to log, redaction, sampling",[833,1410,1411,1413],{},[458,1412,460],{"href":422}," — feature parity matrix and migration snippets",[1415,1416,1417],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}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);}",{"title":643,"searchDepth":681,"depth":681,"links":1419},[1420,1424,1425,1426,1427,1428,1429,1430],{"id":465,"depth":681,"text":466,"children":1421},[1422,1423],{"id":473,"depth":688,"text":474},{"id":535,"depth":688,"text":536},{"id":631,"depth":681,"text":632},{"id":821,"depth":681,"text":822},{"id":901,"depth":681,"text":902},{"id":955,"depth":681,"text":956},{"id":1181,"depth":681,"text":1182},{"id":1293,"depth":681,"text":1294},{"id":1362,"depth":681,"text":1363},"The cheapest moment to add structured logging is before the first request. Pick evlog on day zero and your application inherits a structured surface, typed catalogs, an audit trail, AI SDK telemetry, and a drain pipeline you don't have to build later.","md",[1434,1436,1438],{"label":20,"icon":23,"to":21,"color":451,"variant":1435},"subtle",{"label":1437,"icon":308,"to":313,"color":451,"variant":1435},"Audit & Compliance",{"label":1439,"icon":424,"to":422,"color":451,"variant":1435},"vs pino, winston, consola",{},{"icon":18},{"title":15,"description":1431},"XSDB17RYXicBBOef0zqvtAq_b8dAfAFlwk4cWN5xncg",[1445,1447],{"title":10,"path":11,"stem":12,"description":1446,"icon":13,"children":-1},"A modern TypeScript logger built for everything you ship. Simple structured logs, wide events, and structured errors in one API — drop-in for console.log, pino, or consola.",{"title":20,"path":21,"stem":22,"description":1448,"icon":23,"children":-1},"Install evlog in your TypeScript project. Supports Nuxt, Next.js, SvelteKit, Hono, Express, Fastify, Elysia, NestJS, and standalone scripts.",1778406543675]