[{"data":1,"prerenderedAt":1617},["ShallowReactive",2],{"navigation_docs":3,"-adapters-self-hosted-nuxthub":308,"-adapters-self-hosted-nuxthub-surround":1612},[4,35,80,124,212,292],{"title":5,"path":6,"stem":7,"children":8,"page":34},"Getting Started","\u002Fgetting-started","1.getting-started",[9,14,19,24,29],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-info",{"title":15,"path":16,"stem":17,"icon":18},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":20,"path":21,"stem":22,"icon":23},"Quick Start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-zap",{"title":25,"path":26,"stem":27,"icon":28},"Agent Skills","\u002Fgetting-started\u002Fagent-skills","1.getting-started\u002F4.agent-skills","i-lucide-sparkles",{"title":30,"path":31,"stem":32,"icon":33},"vs Other Loggers","\u002Fgetting-started\u002Fvs-other-loggers","1.getting-started\u002F5.vs-other-loggers","i-lucide-scale",false,{"title":36,"path":37,"stem":38,"children":39,"page":34},"Logging","\u002Flogging","2.logging",[40,45,50,55,60,65,70,75],{"title":41,"path":42,"stem":43,"icon":44},"Overview","\u002Flogging\u002Foverview","2.logging\u002F0.overview","i-lucide-list",{"title":46,"path":47,"stem":48,"icon":49},"Simple Logging","\u002Flogging\u002Fsimple-logging","2.logging\u002F1.simple-logging","i-lucide-terminal",{"title":51,"path":52,"stem":53,"icon":54},"Wide Events","\u002Flogging\u002Fwide-events","2.logging\u002F2.wide-events","i-lucide-layers",{"title":56,"path":57,"stem":58,"icon":59},"Structured Errors","\u002Flogging\u002Fstructured-errors","2.logging\u002F3.structured-errors","i-lucide-shield-alert",{"title":61,"path":62,"stem":63,"icon":64},"Client Logging","\u002Flogging\u002Fclient-logging","2.logging\u002F4.client-logging","i-lucide-monitor",{"title":66,"path":67,"stem":68,"icon":69},"AI SDK Integration","\u002Flogging\u002Fai-sdk","2.logging\u002F5.ai-sdk","i-simple-icons-vercel",{"title":71,"path":72,"stem":73,"icon":74},"Better Auth Integration","\u002Flogging\u002Fbetter-auth","2.logging\u002F6.better-auth","i-simple-icons-betterauth",{"title":76,"path":77,"stem":78,"icon":79},"Audit Logs","\u002Flogging\u002Faudit","2.logging\u002F7.audit","i-lucide-shield-check",{"title":81,"path":82,"stem":83,"children":84,"page":34},"Core Concepts","\u002Fcore-concepts","3.core-concepts",[85,90,95,100,105,109,114,119],{"title":86,"path":87,"stem":88,"icon":89},"Lifecycle","\u002Fcore-concepts\u002Flifecycle","3.core-concepts\u002F0.lifecycle","i-lucide-arrow-right-left",{"title":91,"path":92,"stem":93,"icon":94},"Configuration","\u002Fcore-concepts\u002Fconfiguration","3.core-concepts\u002F1.configuration","i-lucide-settings",{"title":96,"path":97,"stem":98,"icon":99},"Sampling","\u002Fcore-concepts\u002Fsampling","3.core-concepts\u002F2.sampling","i-lucide-filter",{"title":101,"path":102,"stem":103,"icon":104},"Typed Fields","\u002Fcore-concepts\u002Ftyped-fields","3.core-concepts\u002F3.typed-fields","i-simple-icons-typescript",{"title":106,"path":107,"stem":108,"icon":79},"Best Practices","\u002Fcore-concepts\u002Fbest-practices","3.core-concepts\u002F4.best-practices",{"title":110,"path":111,"stem":112,"icon":113},"Performance","\u002Fcore-concepts\u002Fperformance","3.core-concepts\u002F5.performance","i-lucide-gauge",{"title":115,"path":116,"stem":117,"icon":118},"Vite Plugin","\u002Fcore-concepts\u002Fvite-plugin","3.core-concepts\u002F6.vite-plugin","i-custom-vite",{"title":120,"path":121,"stem":122,"icon":123},"Auto-Redaction","\u002Fcore-concepts\u002Fredaction","3.core-concepts\u002F7.redaction","i-lucide-eye-off",{"title":125,"path":126,"stem":127,"children":128,"page":34},"Frameworks","\u002Fframeworks","4.frameworks",[129,133,138,143,148,153,158,163,168,173,178,183,188,193,197,202,207],{"title":41,"path":130,"stem":131,"icon":132},"\u002Fframeworks\u002Foverview","4.frameworks\u002F00.overview","i-lucide-layout-grid",{"title":134,"path":135,"stem":136,"icon":137},"Nuxt","\u002Fframeworks\u002Fnuxt","4.frameworks\u002F01.nuxt","i-simple-icons-nuxtdotjs",{"title":139,"path":140,"stem":141,"icon":142},"Next.js","\u002Fframeworks\u002Fnextjs","4.frameworks\u002F02.nextjs","i-simple-icons-nextdotjs",{"title":144,"path":145,"stem":146,"icon":147},"SvelteKit","\u002Fframeworks\u002Fsveltekit","4.frameworks\u002F03.sveltekit","i-simple-icons-svelte",{"title":149,"path":150,"stem":151,"icon":152},"Nitro","\u002Fframeworks\u002Fnitro","4.frameworks\u002F04.nitro","i-custom-nitro",{"title":154,"path":155,"stem":156,"icon":157},"TanStack Start","\u002Fframeworks\u002Ftanstack-start","4.frameworks\u002F05.tanstack-start","i-custom-tanstack",{"title":159,"path":160,"stem":161,"icon":162},"NestJS","\u002Fframeworks\u002Fnestjs","4.frameworks\u002F06.nestjs","i-simple-icons-nestjs",{"title":164,"path":165,"stem":166,"icon":167},"Express","\u002Fframeworks\u002Fexpress","4.frameworks\u002F07.express","i-simple-icons-express",{"title":169,"path":170,"stem":171,"icon":172},"Hono","\u002Fframeworks\u002Fhono","4.frameworks\u002F08.hono","i-simple-icons-hono",{"title":174,"path":175,"stem":176,"icon":177},"Fastify","\u002Fframeworks\u002Ffastify","4.frameworks\u002F09.fastify","i-simple-icons-fastify",{"title":179,"path":180,"stem":181,"icon":182},"Elysia","\u002Fframeworks\u002Felysia","4.frameworks\u002F10.elysia","i-custom-elysia",{"title":184,"path":185,"stem":186,"icon":187},"React Router","\u002Fframeworks\u002Freact-router","4.frameworks\u002F11.react-router","i-custom-reactrouter",{"title":189,"path":190,"stem":191,"icon":192},"Cloudflare Workers","\u002Fframeworks\u002Fcloudflare-workers","4.frameworks\u002F12.cloudflare-workers","i-simple-icons-cloudflare",{"title":194,"path":195,"stem":196,"icon":104},"Standalone","\u002Fframeworks\u002Fstandalone","4.frameworks\u002F13.standalone",{"title":198,"path":199,"stem":200,"icon":201},"Astro","\u002Fframeworks\u002Fastro","4.frameworks\u002F14.astro","i-simple-icons-astro",{"title":203,"path":204,"stem":205,"icon":206},"AWS Lambda","\u002Fframeworks\u002Faws-lambda","4.frameworks\u002F16.aws-lambda","i-custom-lambda",{"title":208,"path":209,"stem":210,"icon":211},"Custom Integration","\u002Fframeworks\u002Fcustom-integration","4.frameworks\u002F17.custom-integration","i-lucide-puzzle",{"title":213,"path":214,"stem":215,"children":216,"page":34},"Adapters","\u002Fadapters","6.adapters",[217,257,272],{"title":218,"path":219,"stem":220,"children":221,"page":34},"Cloud destinations","\u002Fadapters\u002Fcloud","6.adapters\u002F02.cloud",[222,227,232,237,242,247,252],{"title":223,"path":224,"stem":225,"icon":226},"Axiom","\u002Fadapters\u002Fcloud\u002Faxiom","6.adapters\u002F02.cloud\u002F01.axiom","i-custom-axiom",{"title":228,"path":229,"stem":230,"icon":231},"OTLP","\u002Fadapters\u002Fcloud\u002Fotlp","6.adapters\u002F02.cloud\u002F02.otlp","i-simple-icons-opentelemetry",{"title":233,"path":234,"stem":235,"icon":236},"PostHog","\u002Fadapters\u002Fcloud\u002Fposthog","6.adapters\u002F02.cloud\u002F03.posthog","i-simple-icons-posthog",{"title":238,"path":239,"stem":240,"icon":241},"Sentry","\u002Fadapters\u002Fcloud\u002Fsentry","6.adapters\u002F02.cloud\u002F04.sentry","i-simple-icons-sentry",{"title":243,"path":244,"stem":245,"icon":246},"Better Stack","\u002Fadapters\u002Fcloud\u002Fbetter-stack","6.adapters\u002F02.cloud\u002F05.better-stack","i-simple-icons-betterstack",{"title":248,"path":249,"stem":250,"icon":251},"Datadog","\u002Fadapters\u002Fcloud\u002Fdatadog","6.adapters\u002F02.cloud\u002F06.datadog","i-simple-icons-datadog",{"title":253,"path":254,"stem":255,"icon":256},"HyperDX","\u002Fadapters\u002Fcloud\u002Fhyperdx","6.adapters\u002F02.cloud\u002F07.hyperdx","i-custom-hyperdx",{"title":258,"path":259,"stem":260,"children":261,"page":34},"Self-hosted","\u002Fadapters\u002Fself-hosted","6.adapters\u002F03.self-hosted",[262,267],{"title":263,"path":264,"stem":265,"icon":266},"File System","\u002Fadapters\u002Fself-hosted\u002Ffs","6.adapters\u002F03.self-hosted\u002F01.fs","i-lucide-hard-drive",{"title":268,"path":269,"stem":270,"icon":271},"NuxtHub","\u002Fadapters\u002Fself-hosted\u002Fnuxthub","6.adapters\u002F03.self-hosted\u002F02.nuxthub","i-simple-icons-nuxt",{"title":273,"path":274,"stem":275,"children":276,"page":34},"Building blocks","\u002Fadapters\u002Fbuilding-blocks","6.adapters\u002F04.building-blocks",[277,282,287],{"title":278,"path":279,"stem":280,"icon":281},"Pipeline","\u002Fadapters\u002Fbuilding-blocks\u002Fpipeline","6.adapters\u002F04.building-blocks\u002F01.pipeline","i-lucide-workflow",{"title":283,"path":284,"stem":285,"icon":286},"HTTP","\u002Fadapters\u002Fbuilding-blocks\u002Fhttp","6.adapters\u002F04.building-blocks\u002F02.http","i-lucide-globe",{"title":288,"path":289,"stem":290,"icon":291},"Custom Adapters","\u002Fadapters\u002Fbuilding-blocks\u002Fcustom","6.adapters\u002F04.building-blocks\u002F03.custom","i-lucide-code",{"title":293,"path":294,"stem":295,"children":296,"page":34},"Enrichers","\u002Fenrichers","7.enrichers",[297,300,304],{"title":41,"path":298,"stem":299,"icon":28},"\u002Fenrichers\u002Foverview","7.enrichers\u002F1.overview",{"title":301,"path":302,"stem":303,"icon":211},"Built-in","\u002Fenrichers\u002Fbuilt-in","7.enrichers\u002F2.built-in",{"title":305,"path":306,"stem":307,"icon":291},"Custom","\u002Fenrichers\u002Fcustom","7.enrichers\u002F3.custom",{"id":309,"title":310,"body":311,"description":1598,"extension":1599,"links":1600,"meta":1608,"navigation":1609,"path":269,"seo":1610,"stem":270,"__hash__":1611},"docs\u002F6.adapters\u002F03.self-hosted\u002F02.nuxthub.md","NuxtHub Storage",{"type":312,"value":313,"toc":1580},"minimark",[314,322,369,374,377,404,409,413,493,500,523,527,533,647,660,663,693,708,712,720,730,735,745,964,981,985,988,1006,1013,1017,1025,1128,1132,1137,1140,1145,1227,1230,1293,1297,1304,1374,1383,1387,1390,1403,1410,1439,1442,1446,1457,1542,1548,1552,1559,1563,1576],[315,316,317,321],"p",{},[318,319,320],"code",{},"@evlog\u002Fnuxthub"," stores your evlog wide events directly in your NuxtHub database. No external logging service needed. Your logs live next to your data, with automatic cleanup based on a retention policy.",[323,324,327,330,355],"prompt",{":actions":325,"description":326,"icon":271},"[\"copy\",\"cursor\",\"windsurf\"]","Store evlog wide events in NuxtHub",[315,328,329],{},"Store evlog wide events in my NuxtHub database (self-hosted log retention).",[331,332,333,337,340,343,346,349,352],"ul",{},[334,335,336],"li",{},"Install both modules: pnpm add @nuxthub\u002Fcore @evlog\u002Fnuxthub",[334,338,339],{},"Add @nuxthub\u002Fcore and @evlog\u002Fnuxthub to nuxt.config.ts modules (in that order)",[334,341,342],{},"Enable hub.database = true in nuxt.config.ts",[334,344,345],{},"Configure evlog.nuxthub: { retentionDays, batchSize, ... } for retention and batching",[334,347,348],{},"Run database migrations so the wide-events table is created",[334,350,351],{},"Confirm wide events are written to my NuxtHub database after triggering a request",[334,353,354],{},"For production at scale, combine with an external drain (Axiom \u002F OTLP) for long-term storage",[315,356,357,358,364,365],{},"Docs: ",[359,360,361],"a",{"href":361,"rel":362},"https:\u002F\u002Fwww.evlog.dev\u002Fadapters\u002Fself-hosted\u002Fnuxthub",[363],"nofollow","\nNuxtHub: ",[359,366,367],{"href":367,"rel":368},"https:\u002F\u002Fhub.nuxt.com",[363],[370,371,373],"h2",{"id":372},"why-self-hosted-logs","Why Self-Hosted Logs?",[315,375,376],{},"External logging services (Axiom, Datadog, etc.) are great for production at scale. But sometimes you want:",[331,378,379,386,392,398],{},[334,380,381,385],{},[382,383,384],"strong",{},"Zero external dependencies"," - logs stored in the same database as your app",[334,387,388,391],{},[382,389,390],{},"Full data ownership"," - no third-party access to your log data",[334,393,394,397],{},[382,395,396],{},"Free tier friendly"," - no per-event pricing, just your existing database",[334,399,400,403],{},[382,401,402],{},"Development & staging"," - full log visibility without paying for a service",[315,405,406,408],{},[318,407,320],{}," works as a drop-in drain. Your existing evlog setup stays the same, you just get a database-backed storage layer on top.",[370,410,412],{"id":411},"install","Install",[414,415,416,444,460,476],"code-group",{},[417,418,424],"pre",{"className":419,"code":420,"filename":421,"language":422,"meta":423,"style":423},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm add @nuxthub\u002Fcore @evlog\u002Fnuxthub\n","pnpm","bash","",[318,425,426],{"__ignoreMap":423},[427,428,431,434,438,441],"span",{"class":429,"line":430},"line",1,[427,432,421],{"class":433},"sBMFI",[427,435,437],{"class":436},"sfazB"," add",[427,439,440],{"class":436}," @nuxthub\u002Fcore",[427,442,443],{"class":436}," @evlog\u002Fnuxthub\n",[417,445,448],{"className":419,"code":446,"filename":447,"language":422,"meta":423,"style":423},"bun add @nuxthub\u002Fcore @evlog\u002Fnuxthub\n","bun",[318,449,450],{"__ignoreMap":423},[427,451,452,454,456,458],{"class":429,"line":430},[427,453,447],{"class":433},[427,455,437],{"class":436},[427,457,440],{"class":436},[427,459,443],{"class":436},[417,461,464],{"className":419,"code":462,"filename":463,"language":422,"meta":423,"style":423},"yarn add @nuxthub\u002Fcore @evlog\u002Fnuxthub\n","yarn",[318,465,466],{"__ignoreMap":423},[427,467,468,470,472,474],{"class":429,"line":430},[427,469,463],{"class":433},[427,471,437],{"class":436},[427,473,440],{"class":436},[427,475,443],{"class":436},[417,477,480],{"className":419,"code":478,"filename":479,"language":422,"meta":423,"style":423},"npm install @nuxthub\u002Fcore @evlog\u002Fnuxthub\n","npm",[318,481,482],{"__ignoreMap":423},[427,483,484,486,489,491],{"class":429,"line":430},[427,485,479],{"class":433},[427,487,488],{"class":436}," install",[427,490,440],{"class":436},[427,492,443],{"class":436},[315,494,495,496,499],{},"Or with ",[318,497,498],{},"nuxi",":",[417,501,504],{"className":419,"code":502,"filename":503,"language":422,"meta":423,"style":423},"npx nuxi module add @nuxthub\u002Fcore @evlog\u002Fnuxthub\n","Terminal",[318,505,506],{"__ignoreMap":423},[427,507,508,511,514,517,519,521],{"class":429,"line":430},[427,509,510],{"class":433},"npx",[427,512,513],{"class":436}," nuxi",[427,515,516],{"class":436}," module",[427,518,437],{"class":436},[427,520,440],{"class":436},[427,522,443],{"class":436},[370,524,526],{"id":525},"setup","Setup",[315,528,529,530,499],{},"Add the module to your ",[318,531,532],{},"nuxt.config.ts",[417,534,538],{"className":535,"code":536,"filename":532,"language":537,"meta":423,"style":423},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","export default defineNuxtConfig({\n  modules: ['@nuxthub\u002Fcore', '@evlog\u002Fnuxthub'],\n\n  evlog: {\n    retention: '7d',\n  },\n})\n","typescript",[318,539,540,561,597,604,615,632,638],{"__ignoreMap":423},[427,541,542,546,549,553,557],{"class":429,"line":430},[427,543,545],{"class":544},"s7zQu","export",[427,547,548],{"class":544}," default",[427,550,552],{"class":551},"s2Zo4"," defineNuxtConfig",[427,554,556],{"class":555},"sTEyZ","(",[427,558,560],{"class":559},"sMK4o","{\n",[427,562,564,568,570,573,576,579,581,584,587,589,591,594],{"class":429,"line":563},2,[427,565,567],{"class":566},"swJcz","  modules",[427,569,499],{"class":559},[427,571,572],{"class":555}," [",[427,574,575],{"class":559},"'",[427,577,578],{"class":436},"@nuxthub\u002Fcore",[427,580,575],{"class":559},[427,582,583],{"class":559},",",[427,585,586],{"class":559}," '",[427,588,320],{"class":436},[427,590,575],{"class":559},[427,592,593],{"class":555},"]",[427,595,596],{"class":559},",\n",[427,598,600],{"class":429,"line":599},3,[427,601,603],{"emptyLinePlaceholder":602},true,"\n",[427,605,607,610,612],{"class":429,"line":606},4,[427,608,609],{"class":566},"  evlog",[427,611,499],{"class":559},[427,613,614],{"class":559}," {\n",[427,616,618,621,623,625,628,630],{"class":429,"line":617},5,[427,619,620],{"class":566},"    retention",[427,622,499],{"class":559},[427,624,586],{"class":559},[427,626,627],{"class":436},"7d",[427,629,575],{"class":559},[427,631,596],{"class":559},[427,633,635],{"class":429,"line":634},6,[427,636,637],{"class":559},"  },\n",[427,639,641,644],{"class":429,"line":640},7,[427,642,643],{"class":559},"}",[427,645,646],{"class":555},")\n",[315,648,649,650,652,653,655,656,659],{},"Even if ",[318,651,320],{}," can auto-register missing modules, we recommend explicitly installing ",[318,654,578],{}," and registering it in ",[318,657,658],{},"modules"," for a clearer and more predictable setup.",[315,661,662],{},"That's it. The module automatically:",[664,665,666,676,683,690],"ol",{},[334,667,668,669,672,673,675],{},"Installs ",[318,670,671],{},"evlog\u002Fnuxt"," and ",[318,674,578],{}," if not already registered",[334,677,678,679,682],{},"Registers the ",[318,680,681],{},"evlog_events"," database schema with NuxtHub",[334,684,685,686,689],{},"Hooks into ",[318,687,688],{},"evlog:drain"," to store every event in the database",[334,691,692],{},"Schedules a cleanup task based on your retention policy",[694,695,697,700,701,704,705,707],"callout",{"color":696,"icon":13},"info",[382,698,699],{},"Prerequisites:"," Your project must use ",[359,702,268],{"href":367,"rel":703},[363]," with a database configured. ",[318,706,320],{}," uses Drizzle ORM to interact with the database.",[370,709,711],{"id":710},"how-it-works","How It Works",[417,713,718],{"className":714,"code":716,"language":717},[715],"language-text","Request → evlog wide event → evlog:drain hook → INSERT into evlog_events table\n                                                          ↓\n                          Cron task (automatic) → DELETE events older than retention\n","text",[318,719,716],{"__ignoreMap":423},[315,721,722,723,725,726,729],{},"Every wide event emitted by evlog is stored as a row in the ",[318,724,681],{}," table. The drain plugin handles both single events and batches (when used with the ",[359,727,728],{"href":279},"pipeline",").",[731,732,734],"h3",{"id":733},"database-schema","Database Schema",[315,736,737,738,740,741,744],{},"The ",[318,739,681],{}," table stores indexed columns for fast querying and a ",[318,742,743],{},"data"," JSON column for all remaining fields:",[746,747,748,764],"table",{},[749,750,751],"thead",{},[752,753,754,758,761],"tr",{},[755,756,757],"th",{},"Column",[755,759,760],{},"Type",[755,762,763],{},"Description",[765,766,767,782,796,810,824,838,852,866,881,895,909,923,937,950],"tbody",{},[752,768,769,775,779],{},[770,771,772],"td",{},[318,773,774],{},"id",[770,776,777],{},[318,778,717],{},[770,780,781],{},"UUID primary key",[752,783,784,789,793],{},[770,785,786],{},[318,787,788],{},"timestamp",[770,790,791],{},[318,792,717],{},[770,794,795],{},"Event timestamp",[752,797,798,803,807],{},[770,799,800],{},[318,801,802],{},"level",[770,804,805],{},[318,806,717],{},[770,808,809],{},"Log level (info, warn, error, debug)",[752,811,812,817,821],{},[770,813,814],{},[318,815,816],{},"service",[770,818,819],{},[318,820,717],{},[770,822,823],{},"Service name",[752,825,826,831,835],{},[770,827,828],{},[318,829,830],{},"environment",[770,832,833],{},[318,834,717],{},[770,836,837],{},"Environment (production, staging, etc.)",[752,839,840,845,849],{},[770,841,842],{},[318,843,844],{},"method",[770,846,847],{},[318,848,717],{},[770,850,851],{},"HTTP method",[752,853,854,859,863],{},[770,855,856],{},[318,857,858],{},"path",[770,860,861],{},[318,862,717],{},[770,864,865],{},"Request path",[752,867,868,873,878],{},[770,869,870],{},[318,871,872],{},"status",[770,874,875],{},[318,876,877],{},"integer",[770,879,880],{},"HTTP status code",[752,882,883,888,892],{},[770,884,885],{},[318,886,887],{},"duration_ms",[770,889,890],{},[318,891,877],{},[770,893,894],{},"Request duration in milliseconds",[752,896,897,902,906],{},[770,898,899],{},[318,900,901],{},"request_id",[770,903,904],{},[318,905,717],{},[770,907,908],{},"Request correlation ID",[752,910,911,916,920],{},[770,912,913],{},[318,914,915],{},"source",[770,917,918],{},[318,919,717],{},[770,921,922],{},"Event source (server, client)",[752,924,925,930,934],{},[770,926,927],{},[318,928,929],{},"error",[770,931,932],{},[318,933,717],{},[770,935,936],{},"Error details (JSON string)",[752,938,939,943,947],{},[770,940,941],{},[318,942,743],{},[770,944,945],{},[318,946,717],{},[770,948,949],{},"All remaining event fields (JSON)",[752,951,952,957,961],{},[770,953,954],{},[318,955,956],{},"created_at",[770,958,959],{},[318,960,717],{},[770,962,963],{},"Row insertion timestamp",[315,965,966,967,969,970,969,972,969,974,969,976,969,978,980],{},"Indexed columns: ",[318,968,788],{},", ",[318,971,802],{},[318,973,816],{},[318,975,872],{},[318,977,901],{},[318,979,956],{},".",[731,982,984],{"id":983},"dialect-support","Dialect Support",[315,986,987],{},"The schema is automatically registered for your NuxtHub database dialect:",[331,989,990,996,1001],{},[334,991,992,995],{},[382,993,994],{},"SQLite"," (default for Cloudflare D1)",[334,997,998],{},[382,999,1000],{},"MySQL",[334,1002,1003],{},[382,1004,1005],{},"PostgreSQL",[315,1007,1008,1009,1012],{},"The correct schema is selected via the ",[318,1010,1011],{},"hub:db:schema:extend"," hook based on your NuxtHub configuration.",[370,1014,1016],{"id":1015},"combining-with-external-adapters","Combining with External Adapters",[315,1018,1019,1021,1022,1024],{},[318,1020,320],{}," doesn't replace external adapters, you can use both. The module registers its own ",[318,1023,688],{}," hook, so any other drain plugins you have will still work:",[417,1026,1029],{"className":535,"code":1027,"filename":1028,"language":537,"meta":423,"style":423},"import { createAxiomDrain } from 'evlog\u002Faxiom'\n\nexport default defineNitroPlugin((nitroApp) => {\n  \u002F\u002F This runs alongside @evlog\u002Fnuxthub's built-in drain\n  nitroApp.hooks.hook('evlog:drain', createAxiomDrain())\n})\n","server\u002Fplugins\u002Fevlog-drain.ts",[318,1030,1031,1056,1060,1086,1092,1122],{"__ignoreMap":423},[427,1032,1033,1036,1039,1042,1045,1048,1050,1053],{"class":429,"line":430},[427,1034,1035],{"class":544},"import",[427,1037,1038],{"class":559}," {",[427,1040,1041],{"class":555}," createAxiomDrain",[427,1043,1044],{"class":559}," }",[427,1046,1047],{"class":544}," from",[427,1049,586],{"class":559},[427,1051,1052],{"class":436},"evlog\u002Faxiom",[427,1054,1055],{"class":559},"'\n",[427,1057,1058],{"class":429,"line":563},[427,1059,603],{"emptyLinePlaceholder":602},[427,1061,1062,1064,1066,1069,1071,1073,1077,1080,1084],{"class":429,"line":599},[427,1063,545],{"class":544},[427,1065,548],{"class":544},[427,1067,1068],{"class":551}," defineNitroPlugin",[427,1070,556],{"class":555},[427,1072,556],{"class":559},[427,1074,1076],{"class":1075},"sHdIc","nitroApp",[427,1078,1079],{"class":559},")",[427,1081,1083],{"class":1082},"spNyl"," =>",[427,1085,614],{"class":559},[427,1087,1088],{"class":429,"line":606},[427,1089,1091],{"class":1090},"sHwdD","  \u002F\u002F This runs alongside @evlog\u002Fnuxthub's built-in drain\n",[427,1093,1094,1097,1099,1102,1104,1107,1109,1111,1113,1115,1117,1119],{"class":429,"line":617},[427,1095,1096],{"class":555},"  nitroApp",[427,1098,980],{"class":559},[427,1100,1101],{"class":555},"hooks",[427,1103,980],{"class":559},[427,1105,1106],{"class":551},"hook",[427,1108,556],{"class":566},[427,1110,575],{"class":559},[427,1112,688],{"class":436},[427,1114,575],{"class":559},[427,1116,583],{"class":559},[427,1118,1041],{"class":551},[427,1120,1121],{"class":566},"())\n",[427,1123,1124,1126],{"class":429,"line":634},[427,1125,643],{"class":559},[427,1127,646],{"class":555},[370,1129,1131],{"id":1130},"retention","Retention",[315,1133,1134,1136],{},[318,1135,320],{}," automatically deletes old events based on your retention policy. No manual cleanup needed.",[731,1138,91],{"id":1139},"configuration",[315,1141,1142,1143,499],{},"Set the retention period in your ",[318,1144,532],{},[417,1146,1148],{"className":535,"code":1147,"filename":532,"language":537,"meta":423,"style":423},"export default defineNuxtConfig({\n  modules: ['@nuxthub\u002Fcore', '@evlog\u002Fnuxthub'],\n\n  evlog: {\n    retention: '7d', \u002F\u002F default\n  },\n})\n",[318,1149,1150,1162,1188,1192,1200,1217,1221],{"__ignoreMap":423},[427,1151,1152,1154,1156,1158,1160],{"class":429,"line":430},[427,1153,545],{"class":544},[427,1155,548],{"class":544},[427,1157,552],{"class":551},[427,1159,556],{"class":555},[427,1161,560],{"class":559},[427,1163,1164,1166,1168,1170,1172,1174,1176,1178,1180,1182,1184,1186],{"class":429,"line":563},[427,1165,567],{"class":566},[427,1167,499],{"class":559},[427,1169,572],{"class":555},[427,1171,575],{"class":559},[427,1173,578],{"class":436},[427,1175,575],{"class":559},[427,1177,583],{"class":559},[427,1179,586],{"class":559},[427,1181,320],{"class":436},[427,1183,575],{"class":559},[427,1185,593],{"class":555},[427,1187,596],{"class":559},[427,1189,1190],{"class":429,"line":599},[427,1191,603],{"emptyLinePlaceholder":602},[427,1193,1194,1196,1198],{"class":429,"line":606},[427,1195,609],{"class":566},[427,1197,499],{"class":559},[427,1199,614],{"class":559},[427,1201,1202,1204,1206,1208,1210,1212,1214],{"class":429,"line":617},[427,1203,620],{"class":566},[427,1205,499],{"class":559},[427,1207,586],{"class":559},[427,1209,627],{"class":436},[427,1211,575],{"class":559},[427,1213,583],{"class":559},[427,1215,1216],{"class":1090}," \u002F\u002F default\n",[427,1218,1219],{"class":429,"line":634},[427,1220,637],{"class":559},[427,1222,1223,1225],{"class":429,"line":640},[427,1224,643],{"class":559},[427,1226,646],{"class":555},[315,1228,1229],{},"The retention value is a number followed by a unit:",[746,1231,1232,1244],{},[749,1233,1234],{},[752,1235,1236,1239,1241],{},[755,1237,1238],{},"Unit",[755,1240,763],{},[755,1242,1243],{},"Example",[765,1245,1246,1261,1277],{},[752,1247,1248,1253,1256],{},[770,1249,1250],{},[318,1251,1252],{},"d",[770,1254,1255],{},"Days",[770,1257,1258,1260],{},[318,1259,627],{}," = 7 days",[752,1262,1263,1268,1271],{},[770,1264,1265],{},[318,1266,1267],{},"h",[770,1269,1270],{},"Hours",[770,1272,1273,1276],{},[318,1274,1275],{},"24h"," = 24 hours",[752,1278,1279,1284,1287],{},[770,1280,1281],{},[318,1282,1283],{},"m",[770,1285,1286],{},"Minutes",[770,1288,1289,1292],{},[318,1290,1291],{},"60m"," = 60 minutes",[731,1294,1296],{"id":1295},"how-cleanup-works","How Cleanup Works",[315,1298,1299,1300,1303],{},"The module registers a Nitro scheduled task (",[318,1301,1302],{},"evlog:cleanup",") that runs on a cron schedule derived from your retention value. The cron frequency is set to roughly half the retention period:",[746,1305,1306,1317],{},[749,1307,1308],{},[752,1309,1310,1312,1315],{},[755,1311,1131],{},[755,1313,1314],{},"Cron Schedule",[755,1316,763],{},[765,1318,1319,1333,1347,1361],{},[752,1320,1321,1325,1330],{},[770,1322,1323],{},[318,1324,1291],{},[770,1326,1327],{},[318,1328,1329],{},"*\u002F30 * * * *",[770,1331,1332],{},"Every 30 minutes",[752,1334,1335,1339,1344],{},[770,1336,1337],{},[318,1338,1275],{},[770,1340,1341],{},[318,1342,1343],{},"0 *\u002F12 * * *",[770,1345,1346],{},"Every 12 hours",[752,1348,1349,1353,1358],{},[770,1350,1351],{},[318,1352,627],{},[770,1354,1355],{},[318,1356,1357],{},"0 3 * * *",[770,1359,1360],{},"Daily at 3:00 AM",[752,1362,1363,1368,1372],{},[770,1364,1365],{},[318,1366,1367],{},"30d",[770,1369,1370],{},[318,1371,1357],{},[770,1373,1360],{},[315,1375,1376,1377,1379,1380,1382],{},"The cleanup task deletes all rows in ",[318,1378,681],{}," where ",[318,1381,956],{}," is older than the retention period.",[731,1384,1386],{"id":1385},"manual-cleanup","Manual Cleanup",[315,1388,1389],{},"You can trigger cleanup manually via the API endpoint:",[417,1391,1393],{"className":419,"code":1392,"filename":503,"language":422,"meta":423,"style":423},"curl https:\u002F\u002Fyour-app.com\u002Fapi\u002F_cron\u002Fevlog-cleanup\n",[318,1394,1395],{"__ignoreMap":423},[427,1396,1397,1400],{"class":429,"line":430},[427,1398,1399],{"class":433},"curl",[427,1401,1402],{"class":436}," https:\u002F\u002Fyour-app.com\u002Fapi\u002F_cron\u002Fevlog-cleanup\n",[315,1404,1405,1406,1409],{},"If the ",[318,1407,1408],{},"CRON_SECRET"," environment variable is set, the endpoint requires a Bearer token:",[417,1411,1413],{"className":419,"code":1412,"filename":503,"language":422,"meta":423,"style":423},"curl -H \"Authorization: Bearer your-secret\" \\\n  https:\u002F\u002Fyour-app.com\u002Fapi\u002F_cron\u002Fevlog-cleanup\n",[318,1414,1415,1434],{"__ignoreMap":423},[427,1416,1417,1419,1422,1425,1428,1431],{"class":429,"line":430},[427,1418,1399],{"class":433},[427,1420,1421],{"class":436}," -H",[427,1423,1424],{"class":559}," \"",[427,1426,1427],{"class":436},"Authorization: Bearer your-secret",[427,1429,1430],{"class":559},"\"",[427,1432,1433],{"class":555}," \\\n",[427,1435,1436],{"class":429,"line":563},[427,1437,1438],{"class":436},"  https:\u002F\u002Fyour-app.com\u002Fapi\u002F_cron\u002Fevlog-cleanup\n",[315,1440,1441],{},"This is recommended for production deployments to prevent unauthorized cleanup triggers.",[731,1443,1445],{"id":1444},"vercel-cron","Vercel Cron",[315,1447,1448,1449,1452,1453,1456],{},"When installing the module with ",[318,1450,1451],{},"nuxi module add",", you'll be prompted to create a ",[318,1454,1455],{},"vercel.json"," with the appropriate cron schedule:",[417,1458,1462],{"className":1459,"code":1460,"filename":1455,"language":1461,"meta":423,"style":423},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"crons\": [\n    {\n      \"path\": \"\u002Fapi\u002F_cron\u002Fevlog-cleanup\",\n      \"schedule\": \"0 3 * * *\"\n    }\n  ]\n}\n","json",[318,1463,1464,1468,1483,1488,1508,1526,1531,1536],{"__ignoreMap":423},[427,1465,1466],{"class":429,"line":430},[427,1467,560],{"class":559},[427,1469,1470,1473,1476,1478,1480],{"class":429,"line":563},[427,1471,1472],{"class":559},"  \"",[427,1474,1475],{"class":1082},"crons",[427,1477,1430],{"class":559},[427,1479,499],{"class":559},[427,1481,1482],{"class":559}," [\n",[427,1484,1485],{"class":429,"line":599},[427,1486,1487],{"class":559},"    {\n",[427,1489,1490,1493,1495,1497,1499,1501,1504,1506],{"class":429,"line":606},[427,1491,1492],{"class":559},"      \"",[427,1494,858],{"class":433},[427,1496,1430],{"class":559},[427,1498,499],{"class":559},[427,1500,1424],{"class":559},[427,1502,1503],{"class":436},"\u002Fapi\u002F_cron\u002Fevlog-cleanup",[427,1505,1430],{"class":559},[427,1507,596],{"class":559},[427,1509,1510,1512,1515,1517,1519,1521,1523],{"class":429,"line":617},[427,1511,1492],{"class":559},[427,1513,1514],{"class":433},"schedule",[427,1516,1430],{"class":559},[427,1518,499],{"class":559},[427,1520,1424],{"class":559},[427,1522,1357],{"class":436},[427,1524,1525],{"class":559},"\"\n",[427,1527,1528],{"class":429,"line":634},[427,1529,1530],{"class":559},"    }\n",[427,1532,1533],{"class":429,"line":640},[427,1534,1535],{"class":559},"  ]\n",[427,1537,1539],{"class":429,"line":1538},8,[427,1540,1541],{"class":559},"}\n",[315,1543,1544,1545,1547],{},"On Vercel, the ",[318,1546,1408],{}," environment variable is automatically set and validated.",[731,1549,1551],{"id":1550},"cloudflare-other-platforms","Cloudflare & Other Platforms",[315,1553,1554,1555,1558],{},"On Cloudflare Workers and other platforms, the Nitro scheduled task handles cleanup automatically without any additional cron configuration. The task is registered with ",[318,1556,1557],{},"experimental.tasks"," enabled in the Nitro config.",[370,1560,1562],{"id":1561},"next-steps","Next Steps",[331,1564,1565,1571],{},[334,1566,1567,1570],{},[359,1568,213],{"href":1569},"\u002Fadapters\u002Foverview"," - Send logs to external services alongside NuxtHub storage",[334,1572,1573,1575],{},[359,1574,278],{"href":279}," - Batch events for better database performance",[1577,1578,1579],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}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}",{"title":423,"searchDepth":563,"depth":563,"links":1581},[1582,1583,1584,1585,1589,1590,1597],{"id":372,"depth":563,"text":373},{"id":411,"depth":563,"text":412},{"id":525,"depth":563,"text":526},{"id":710,"depth":563,"text":711,"children":1586},[1587,1588],{"id":733,"depth":599,"text":734},{"id":983,"depth":599,"text":984},{"id":1015,"depth":563,"text":1016},{"id":1130,"depth":563,"text":1131,"children":1591},[1592,1593,1594,1595,1596],{"id":1139,"depth":599,"text":91},{"id":1295,"depth":599,"text":1296},{"id":1385,"depth":599,"text":1386},{"id":1444,"depth":599,"text":1445},{"id":1550,"depth":599,"text":1551},{"id":1561,"depth":563,"text":1562},"Self-hosted log retention for evlog using NuxtHub database storage. Store, query, and automatically clean up your structured logs with zero external dependencies.","md",[1601,1606],{"label":268,"icon":1602,"to":367,"target":1603,"color":1604,"variant":1605},"i-lucide-external-link","_blank","neutral","subtle",{"label":213,"icon":1607,"to":1569,"color":1604,"variant":1605},"i-custom-plug",{},{"title":268,"icon":271},{"title":310,"description":1598},"7IAyh9YhgeYDG6zRJWByEW2QvSef3_48EfOsdchlpRY",[1613,1615],{"title":263,"path":264,"stem":265,"description":1614,"icon":266,"children":-1},"Write wide events to the local file system as NDJSON for local debugging, AI agent integration, and production backup.",{"title":278,"path":279,"stem":280,"description":1616,"icon":281,"children":-1},"Batch events, retry on failure, and protect against buffer overflow with the shared drain pipeline. Supports fan-out to multiple adapters.",1777667170460]