[{"data":1,"prerenderedAt":3428},["ShallowReactive",2],{"navigation_docs":3,"-integrate-adapters-hybrid-clickhouse":529,"-integrate-adapters-hybrid-clickhouse-surround":3423},[4,30,80,128,308,440,499],{"title":5,"path":6,"stem":7,"children":8,"page":29},"Start","\u002Fstart","1.start",[9,14,19,24],{"title":10,"path":11,"stem":12,"icon":13},"Introduction","\u002Fstart\u002Fintroduction","1.start\u002F1.introduction","i-lucide-info",{"title":15,"path":16,"stem":17,"icon":18},"Why start with evlog","\u002Fstart\u002Fwhy-evlog","1.start\u002F2.why-evlog","i-lucide-rocket",{"title":20,"path":21,"stem":22,"icon":23},"Installation","\u002Fstart\u002Finstallation","1.start\u002F3.installation","i-lucide-download",{"title":25,"path":26,"stem":27,"icon":28},"Quick Start","\u002Fstart\u002Fquick-start","1.start\u002F4.quick-start","i-lucide-zap",false,{"title":31,"path":32,"stem":33,"children":34,"page":29},"Learn","\u002Flearn","2.learn",[35,40,45,50,55,60,65,70,75],{"title":36,"path":37,"stem":38,"icon":39},"Overview","\u002Flearn\u002Foverview","2.learn\u002F0.overview","i-lucide-list",{"title":41,"path":42,"stem":43,"icon":44},"Simple Logging","\u002Flearn\u002Fsimple-logging","2.learn\u002F1.simple-logging","i-lucide-terminal",{"title":46,"path":47,"stem":48,"icon":49},"Wide Events","\u002Flearn\u002Fwide-events","2.learn\u002F2.wide-events","i-lucide-layers",{"title":51,"path":52,"stem":53,"icon":54},"Structured Errors","\u002Flearn\u002Fstructured-errors","2.learn\u002F3.structured-errors","i-lucide-shield-alert",{"title":56,"path":57,"stem":58,"icon":59},"Lifecycle","\u002Flearn\u002Flifecycle","2.learn\u002F4.lifecycle","i-lucide-arrow-right-left",{"title":61,"path":62,"stem":63,"icon":64},"Sampling","\u002Flearn\u002Fsampling","2.learn\u002F5.sampling","i-lucide-filter",{"title":66,"path":67,"stem":68,"icon":69},"Auto-Redaction","\u002Flearn\u002Fredaction","2.learn\u002F6.redaction","i-lucide-eye-off",{"title":71,"path":72,"stem":73,"icon":74},"Typed Fields","\u002Flearn\u002Ftyped-fields","2.learn\u002F7.typed-fields","i-simple-icons-typescript",{"title":76,"path":77,"stem":78,"icon":79},"Catalogs","\u002Flearn\u002Fcatalogs","2.learn\u002F8.catalogs","i-lucide-book-open",{"title":81,"path":82,"stem":83,"children":84,"page":29},"CLI","\u002Fcli","3.cli",[85,88,93,98,103,108,113,118,123],{"title":36,"path":86,"stem":87,"icon":44},"\u002Fcli\u002Foverview","3.cli\u002F0.overview",{"title":89,"path":90,"stem":91,"icon":92},"init","\u002Fcli\u002Finit","3.cli\u002F1.init","i-lucide-wand-sparkles",{"title":94,"path":95,"stem":96,"icon":97},"map","\u002Fcli\u002Fmap","3.cli\u002F2.map","i-lucide-radar",{"title":99,"path":100,"stem":101,"icon":102},"Rules","\u002Fcli\u002Frules","3.cli\u002F3.rules","i-lucide-list-checks",{"title":104,"path":105,"stem":106,"icon":107},"Scoring","\u002Fcli\u002Fscoring","3.cli\u002F4.scoring","i-lucide-gauge",{"title":109,"path":110,"stem":111,"icon":112},"CI","\u002Fcli\u002Fci","3.cli\u002F5.ci","i-lucide-git-pull-request",{"title":114,"path":115,"stem":116,"icon":117},"doctor","\u002Fcli\u002Fdoctor","3.cli\u002F6.doctor","i-lucide-stethoscope",{"title":119,"path":120,"stem":121,"icon":122},"telemetry","\u002Fcli\u002Ftelemetry","3.cli\u002F7.telemetry","i-lucide-bar-chart-3",{"title":124,"path":125,"stem":126,"icon":127},"agents","\u002Fcli\u002Fagents","3.cli\u002F8.agents","i-lucide-bot",{"title":129,"path":130,"stem":131,"children":132,"page":29},"Integrate","\u002Fintegrate","4.integrate",[133,137,220],{"title":36,"path":134,"stem":135,"icon":136},"\u002Fintegrate\u002Foverview","4.integrate\u002F0.overview","i-lucide-plug",{"title":138,"path":139,"stem":140,"children":141,"page":29},"Adapters","\u002Fintegrate\u002Fadapters","4.integrate\u002Fadapters",[142,145,175,200],{"title":36,"path":143,"stem":144,"icon":39},"\u002Fintegrate\u002Fadapters\u002Foverview","4.integrate\u002Fadapters\u002F01.overview",{"title":146,"path":147,"stem":148,"children":149,"page":29},"Cloud","\u002Fintegrate\u002Fadapters\u002Fcloud","4.integrate\u002Fadapters\u002Fcloud",[150,155,160,165,170],{"title":151,"path":152,"stem":153,"icon":154},"Axiom","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Faxiom","4.integrate\u002Fadapters\u002Fcloud\u002F01.axiom","i-custom-axiom",{"title":156,"path":157,"stem":158,"icon":159},"PostHog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fposthog","4.integrate\u002Fadapters\u002Fcloud\u002F02.posthog","i-simple-icons-posthog",{"title":161,"path":162,"stem":163,"icon":164},"Sentry","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fsentry","4.integrate\u002Fadapters\u002Fcloud\u002F03.sentry","i-simple-icons-sentry",{"title":166,"path":167,"stem":168,"icon":169},"Better Stack","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fbetter-stack","4.integrate\u002Fadapters\u002Fcloud\u002F04.better-stack","i-simple-icons-betterstack",{"title":171,"path":172,"stem":173,"icon":174},"Datadog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fdatadog","4.integrate\u002Fadapters\u002Fcloud\u002F05.datadog","i-simple-icons-datadog",{"title":176,"path":177,"stem":178,"children":179,"page":29},"Cloud or Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fhybrid","4.integrate\u002Fadapters\u002Fhybrid",[180,185,190,195],{"title":181,"path":182,"stem":183,"icon":184},"Grafana Loki","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Floki","4.integrate\u002Fadapters\u002Fhybrid\u002F01.loki","i-simple-icons-grafana",{"title":186,"path":187,"stem":188,"icon":189},"ClickHouse","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fclickhouse","4.integrate\u002Fadapters\u002Fhybrid\u002F02.clickhouse","i-simple-icons-clickhouse",{"title":191,"path":192,"stem":193,"icon":194},"OTLP","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fotlp","4.integrate\u002Fadapters\u002Fhybrid\u002F03.otlp","i-simple-icons-opentelemetry",{"title":196,"path":197,"stem":198,"icon":199},"HyperDX","\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fhyperdx","4.integrate\u002Fadapters\u002Fhybrid\u002F04.hyperdx","i-custom-hyperdx",{"title":201,"path":202,"stem":203,"children":204,"page":29},"Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fself-hosted","4.integrate\u002Fadapters\u002Fself-hosted",[205,210,215],{"title":206,"path":207,"stem":208,"icon":209},"File System","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Ffs","4.integrate\u002Fadapters\u002Fself-hosted\u002F01.fs","i-lucide-hard-drive",{"title":211,"path":212,"stem":213,"icon":214},"NuxtHub","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fnuxthub","4.integrate\u002Fadapters\u002Fself-hosted\u002F02.nuxthub","i-simple-icons-nuxt",{"title":216,"path":217,"stem":218,"icon":219},"Memory","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fmemory","4.integrate\u002Fadapters\u002Fself-hosted\u002F03.memory","i-lucide-cpu",{"title":221,"path":222,"stem":223,"children":224,"page":29},"Frameworks","\u002Fintegrate\u002Fframeworks","4.integrate\u002Fframeworks",[225,229,234,239,244,249,254,259,264,269,274,279,284,289,293,298,303],{"title":36,"path":226,"stem":227,"icon":228},"\u002Fintegrate\u002Fframeworks\u002Foverview","4.integrate\u002Fframeworks\u002F00.overview","i-lucide-layout-grid",{"title":230,"path":231,"stem":232,"icon":233},"Nuxt","\u002Fintegrate\u002Fframeworks\u002Fnuxt","4.integrate\u002Fframeworks\u002F01.nuxt","i-simple-icons-nuxtdotjs",{"title":235,"path":236,"stem":237,"icon":238},"Next.js","\u002Fintegrate\u002Fframeworks\u002Fnextjs","4.integrate\u002Fframeworks\u002F02.nextjs","i-simple-icons-nextdotjs",{"title":240,"path":241,"stem":242,"icon":243},"SvelteKit","\u002Fintegrate\u002Fframeworks\u002Fsveltekit","4.integrate\u002Fframeworks\u002F03.sveltekit","i-simple-icons-svelte",{"title":245,"path":246,"stem":247,"icon":248},"Nitro","\u002Fintegrate\u002Fframeworks\u002Fnitro","4.integrate\u002Fframeworks\u002F04.nitro","i-custom-nitro",{"title":250,"path":251,"stem":252,"icon":253},"TanStack Start","\u002Fintegrate\u002Fframeworks\u002Ftanstack-start","4.integrate\u002Fframeworks\u002F05.tanstack-start","i-custom-tanstack",{"title":255,"path":256,"stem":257,"icon":258},"NestJS","\u002Fintegrate\u002Fframeworks\u002Fnestjs","4.integrate\u002Fframeworks\u002F06.nestjs","i-simple-icons-nestjs",{"title":260,"path":261,"stem":262,"icon":263},"Express","\u002Fintegrate\u002Fframeworks\u002Fexpress","4.integrate\u002Fframeworks\u002F07.express","i-simple-icons-express",{"title":265,"path":266,"stem":267,"icon":268},"Hono","\u002Fintegrate\u002Fframeworks\u002Fhono","4.integrate\u002Fframeworks\u002F08.hono","i-simple-icons-hono",{"title":270,"path":271,"stem":272,"icon":273},"Fastify","\u002Fintegrate\u002Fframeworks\u002Ffastify","4.integrate\u002Fframeworks\u002F09.fastify","i-simple-icons-fastify",{"title":275,"path":276,"stem":277,"icon":278},"Elysia","\u002Fintegrate\u002Fframeworks\u002Felysia","4.integrate\u002Fframeworks\u002F10.elysia","i-custom-elysia",{"title":280,"path":281,"stem":282,"icon":283},"React Router","\u002Fintegrate\u002Fframeworks\u002Freact-router","4.integrate\u002Fframeworks\u002F11.react-router","i-custom-reactrouter",{"title":285,"path":286,"stem":287,"icon":288},"Cloudflare Workers","\u002Fintegrate\u002Fframeworks\u002Fcloudflare-workers","4.integrate\u002Fframeworks\u002F12.cloudflare-workers","i-simple-icons-cloudflare",{"title":290,"path":291,"stem":292,"icon":74},"Standalone","\u002Fintegrate\u002Fframeworks\u002Fstandalone","4.integrate\u002Fframeworks\u002F13.standalone",{"title":294,"path":295,"stem":296,"icon":297},"Astro","\u002Fintegrate\u002Fframeworks\u002Fastro","4.integrate\u002Fframeworks\u002F14.astro","i-simple-icons-astro",{"title":299,"path":300,"stem":301,"icon":302},"oRPC","\u002Fintegrate\u002Fframeworks\u002Forpc","4.integrate\u002Fframeworks\u002F15.orpc","i-lucide-network",{"title":304,"path":305,"stem":306,"icon":307},"AWS Lambda","\u002Fintegrate\u002Fframeworks\u002Faws-lambda","4.integrate\u002Fframeworks\u002F16.aws-lambda","i-custom-lambda",{"title":309,"path":310,"stem":311,"children":312,"page":29},"Use Cases","\u002Fuse-cases","5.use-cases",[313,316,321,350,377,409,430,435],{"title":36,"path":314,"stem":315,"icon":102},"\u002Fuse-cases\u002Foverview","5.use-cases\u002F0.overview",{"title":317,"path":318,"stem":319,"icon":320},"Client Logging","\u002Fuse-cases\u002Fclient-logging","5.use-cases\u002F1.client-logging","i-lucide-monitor",{"title":322,"icon":323,"path":324,"stem":325,"children":326,"page":29},"AI SDK","i-simple-icons-vercel","\u002Fuse-cases\u002Fai-sdk","5.use-cases\u002F2.ai-sdk",[327,330,335,340,345],{"title":36,"path":328,"stem":329,"icon":39},"\u002Fuse-cases\u002Fai-sdk\u002Foverview","5.use-cases\u002F2.ai-sdk\u002F01.overview",{"title":331,"path":332,"stem":333,"icon":334},"Usage","\u002Fuse-cases\u002Fai-sdk\u002Fusage","5.use-cases\u002F2.ai-sdk\u002F02.usage","i-lucide-code",{"title":336,"path":337,"stem":338,"icon":339},"Options","\u002Fuse-cases\u002Fai-sdk\u002Foptions","5.use-cases\u002F2.ai-sdk\u002F03.options","i-lucide-sliders",{"title":341,"path":342,"stem":343,"icon":344},"Metadata","\u002Fuse-cases\u002Fai-sdk\u002Fmetadata","5.use-cases\u002F2.ai-sdk\u002F04.metadata","i-lucide-database",{"title":346,"path":347,"stem":348,"icon":349},"Telemetry","\u002Fuse-cases\u002Fai-sdk\u002Ftelemetry","5.use-cases\u002F2.ai-sdk\u002F05.telemetry","i-lucide-activity",{"title":351,"icon":352,"path":353,"stem":354,"children":355,"page":29},"Better Auth","i-simple-icons-betterauth","\u002Fuse-cases\u002Fbetter-auth","5.use-cases\u002F3.better-auth",[356,359,364,369,373],{"title":36,"path":357,"stem":358,"icon":39},"\u002Fuse-cases\u002Fbetter-auth\u002Foverview","5.use-cases\u002F3.better-auth\u002F01.overview",{"title":360,"path":361,"stem":362,"icon":363},"Identify User","\u002Fuse-cases\u002Fbetter-auth\u002Fidentify-user","5.use-cases\u002F3.better-auth\u002F02.identify-user","i-lucide-user-check",{"title":365,"path":366,"stem":367,"icon":368},"Middleware","\u002Fuse-cases\u002Fbetter-auth\u002Fmiddleware","5.use-cases\u002F3.better-auth\u002F03.middleware","i-lucide-shield",{"title":370,"path":371,"stem":372,"icon":320},"Client Sync","\u002Fuse-cases\u002Fbetter-auth\u002Fclient-sync","5.use-cases\u002F3.better-auth\u002F04.client-sync",{"title":374,"path":375,"stem":376,"icon":107},"Performance","\u002Fuse-cases\u002Fbetter-auth\u002Fperformance","5.use-cases\u002F3.better-auth\u002F05.performance",{"title":378,"icon":379,"path":380,"stem":381,"children":382,"page":29},"Audit Logs","i-lucide-shield-check","\u002Fuse-cases\u002Faudit","5.use-cases\u002F4.audit",[383,386,391,396,401,405],{"title":36,"path":384,"stem":385,"icon":39},"\u002Fuse-cases\u002Faudit\u002Foverview","5.use-cases\u002F4.audit\u002F01.overview",{"title":387,"path":388,"stem":389,"icon":390},"Schema","\u002Fuse-cases\u002Faudit\u002Fschema","5.use-cases\u002F4.audit\u002F02.schema","i-lucide-file-text",{"title":392,"path":393,"stem":394,"icon":395},"Recording","\u002Fuse-cases\u002Faudit\u002Frecording","5.use-cases\u002F4.audit\u002F03.recording","i-lucide-pen-line",{"title":397,"path":398,"stem":399,"icon":400},"Drains","\u002Fuse-cases\u002Faudit\u002Fpipeline","5.use-cases\u002F4.audit\u002F04.pipeline","i-lucide-link",{"title":402,"path":403,"stem":404,"icon":379},"Compliance","\u002Fuse-cases\u002Faudit\u002Fcompliance","5.use-cases\u002F4.audit\u002F05.compliance",{"title":406,"path":407,"stem":408,"icon":79},"Recipes","\u002Fuse-cases\u002Faudit\u002Frecipes","5.use-cases\u002F4.audit\u002F06.recipes",{"title":346,"icon":107,"path":410,"stem":411,"children":412,"page":29},"\u002Fuse-cases\u002Ftelemetry","5.use-cases\u002F4.telemetry",[413,416,421,426],{"title":36,"path":414,"stem":415,"icon":39},"\u002Fuse-cases\u002Ftelemetry\u002Foverview","5.use-cases\u002F4.telemetry\u002F01.overview",{"title":417,"path":418,"stem":419,"icon":420},"Setup","\u002Fuse-cases\u002Ftelemetry\u002Fsetup","5.use-cases\u002F4.telemetry\u002F02.setup","i-lucide-wrench",{"title":422,"path":423,"stem":424,"icon":425},"Ingest","\u002Fuse-cases\u002Ftelemetry\u002Fingest","5.use-cases\u002F4.telemetry\u002F03.ingest","i-lucide-server",{"title":427,"path":428,"stem":429,"icon":79},"Reference","\u002Fuse-cases\u002Ftelemetry\u002Freference","5.use-cases\u002F4.telemetry\u002F04.reference",{"title":431,"path":432,"stem":433,"icon":434},"Enrichers","\u002Fuse-cases\u002Fenrichers","5.use-cases\u002F5.enrichers","i-lucide-sparkles",{"title":436,"path":437,"stem":438,"icon":439},"eve","\u002Fuse-cases\u002Feve","5.use-cases\u002F5.eve","i-custom-eve",{"title":441,"path":442,"stem":443,"children":444,"page":29},"Extend","\u002Fextend","6.extend",[445,449,454,459,463,468,472,476,480,484,489,494],{"title":36,"path":446,"stem":447,"icon":448},"\u002Fextend\u002Foverview","6.extend\u002F0.overview","i-lucide-blocks",{"title":450,"path":451,"stem":452,"icon":453},"Stream","\u002Fextend\u002Fstream","6.extend\u002F1.stream","i-lucide-radio-tower",{"title":455,"path":456,"stem":457,"icon":458},"Custom framework","\u002Fextend\u002Fcustom-framework","6.extend\u002F10.custom-framework","i-lucide-puzzle",{"title":460,"path":461,"stem":462,"icon":453},"Diagnostics channel","\u002Fextend\u002Fdiagnostics-channel","6.extend\u002F11.diagnostics-channel",{"title":464,"path":465,"stem":466,"icon":467},"FS reader","\u002Fextend\u002Ffs-reader","6.extend\u002F2.fs-reader","i-lucide-folder-search",{"title":406,"path":469,"stem":470,"icon":471},"\u002Fextend\u002Fconsumer-recipes","6.extend\u002F3.consumer-recipes","i-lucide-chef-hat",{"title":473,"path":474,"stem":475,"icon":448},"Plugins","\u002Fextend\u002Fplugins","6.extend\u002F4.plugins",{"title":477,"path":478,"stem":479,"icon":434},"Custom enrichers","\u002Fextend\u002Fcustom-enrichers","6.extend\u002F5.custom-enrichers",{"title":481,"path":482,"stem":483,"icon":64},"Tail sampling","\u002Fextend\u002Ftail-sampling","6.extend\u002F6.tail-sampling",{"title":485,"path":486,"stem":487,"icon":488},"Identity headers","\u002Fextend\u002Fidentity-headers","6.extend\u002F7.identity-headers","i-lucide-fingerprint",{"title":490,"path":491,"stem":492,"icon":493},"Custom drains","\u002Fextend\u002Fcustom-drains","6.extend\u002F8.custom-drains","i-lucide-share-2",{"title":495,"path":496,"stem":497,"icon":498},"Drain pipeline","\u002Fextend\u002Fdrain-pipeline","6.extend\u002F9.drain-pipeline","i-lucide-workflow",{"title":427,"path":500,"stem":501,"children":502,"page":29},"\u002Freference","7.reference",[503,508,511,516,520,525],{"title":504,"path":505,"stem":506,"icon":507},"Configuration","\u002Freference\u002Fconfiguration","7.reference\u002F1.configuration","i-lucide-settings",{"title":374,"path":509,"stem":510,"icon":107},"\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":379},"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":434},"Agent Skills","\u002Freference\u002Fagent-skills","7.reference\u002F6.agent-skills",{"id":530,"title":531,"body":532,"description":3408,"extension":3409,"links":3410,"meta":3419,"navigation":3420,"path":187,"seo":3421,"stem":188,"__hash__":3422},"docs\u002F4.integrate\u002Fadapters\u002Fhybrid\u002F02.clickhouse.md","ClickHouse Adapter",{"type":533,"value":534,"toc":3387},"minimark",[535,552,564,614,618,621,664,668,671,913,925,928,1707,1710,1715,1812,1815,2019,2023,2026,2030,2033,2063,2103,2118,2122,2125,2197,2229,2244,2264,2268,2271,2330,2350,2357,2386,2397,2401,2414,2422,2425,2439,2443,2449,2540,2672,2737,2820,2824,2830,2977,2983,2987,2990,3179,3183,3201,3221,3233,3248,3252,3340,3353,3357,3383],[536,537,538,539,546,547,551],"p",{},"The ClickHouse adapter inserts wide events over the ",[540,541,545],"a",{"href":542,"rel":543},"https:\u002F\u002Fclickhouse.com\u002Fdocs\u002Fen\u002Finterfaces\u002Fhttp",[544],"nofollow","HTTP interface"," in ",[548,549,550],"code",{},"JSONEachRow"," format. It works with a local instance, a self-managed cluster, and ClickHouse Cloud.",[536,553,554,555,559,560,563],{},"The default schema gives you ",[556,557,558],"strong",{},"typed columns"," for the fields you filter and aggregate on, plus the complete wide event as JSON in ",[548,561,562],{},"data"," — so no field is ever lost, and adding a field to your events never requires a migration.",[565,566,569,572,602],"prompt",{":actions":567,"description":568,"icon":189},"[\"copy\",\"cursor\",\"claude\"]","Add the ClickHouse drain adapter",[536,570,571],{},"Add the ClickHouse drain adapter to store evlog wide events in ClickHouse.",[573,574,575,579,582,585,588,591,599],"ol",{},[576,577,578],"li",{},"Identify which framework I'm using and follow its evlog integration pattern",[576,580,581],{},"Install evlog if not already installed",[576,583,584],{},"Create the evlog_events table using the CREATE TABLE from the adapter docs",[576,586,587],{},"Import createClickHouseDrain from 'evlog\u002Fclickhouse'",[576,589,590],{},"Wire createClickHouseDrain() into my framework's drain configuration",[576,592,593,594,598],{},"Set CLICKHOUSE_ENDPOINT (e.g. ",[540,595,596],{"href":596,"rel":597},"http:\u002F\u002Flocalhost:8123",[544],"), plus CLICKHOUSE_USER \u002F CLICKHOUSE_PASSWORD if authenticated",[576,600,601],{},"Test by triggering a request and running SELECT * FROM evlog_events ORDER BY timestamp DESC LIMIT 10",[536,603,604,605,609,610],{},"Adapter docs: ",[540,606,607],{"href":607,"rel":608},"https:\u002F\u002Fwww.evlog.dev\u002Fintegrate\u002Fadapters\u002Fhybrid\u002Fclickhouse",[544],"\nFramework setup: ",[540,611,612],{"href":612,"rel":613},"https:\u002F\u002Fwww.evlog.dev\u002Fintegrate\u002Fframeworks\u002Foverview",[544],[615,616,20],"h2",{"id":617},"installation",[536,619,620],{},"The ClickHouse adapter comes bundled with evlog:",[622,623,629],"pre",{"className":624,"code":625,"filename":626,"language":627,"meta":628,"style":628},"language-typescript shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { createClickHouseDrain } from 'evlog\u002Fclickhouse'\n","src\u002Findex.ts","typescript","",[548,630,631],{"__ignoreMap":628},[632,633,636,640,644,648,651,654,657,661],"span",{"class":634,"line":635},"line",1,[632,637,639],{"class":638},"s7zQu","import",[632,641,643],{"class":642},"sMK4o"," {",[632,645,647],{"class":646},"sTEyZ"," createClickHouseDrain",[632,649,650],{"class":642}," }",[632,652,653],{"class":638}," from",[632,655,656],{"class":642}," '",[632,658,660],{"class":659},"sfazB","evlog\u002Fclickhouse",[632,662,663],{"class":642},"'\n",[615,665,667],{"id":666},"create-the-table","Create the table",[536,669,670],{},"Run this once before wiring the drain:",[622,672,677],{"className":673,"code":674,"filename":675,"language":676,"meta":628,"style":628},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","CREATE TABLE IF NOT EXISTS evlog_events\n(\n  timestamp     DateTime64(3, 'UTC'),\n  level         LowCardinality(String),\n  service       LowCardinality(String),\n  environment   LowCardinality(String),\n  request_id    String,\n  trace_id      String,\n  span_id       String,\n  method        LowCardinality(String),\n  path          String,\n  status        Nullable(UInt16),\n  duration      String,\n  duration_ms   Nullable(UInt32),\n  error_name    String,\n  error_message String,\n  data          String\n)\nENGINE = MergeTree\nPARTITION BY toYYYYMM(timestamp)\nORDER BY (service, environment, timestamp)\nTTL toDateTime(timestamp) + INTERVAL 30 DAY;\n","schema.sql","sql",[548,678,679,701,707,734,743,752,758,764,770,776,782,791,800,806,812,818,824,833,839,851,868,887],{"__ignoreMap":628},[632,680,681,685,688,692,695,698],{"class":634,"line":635},[632,682,684],{"class":683},"sbssI","CREATE",[632,686,687],{"class":683}," TABLE",[632,689,691],{"class":690},"s2Zo4"," IF",[632,693,694],{"class":683}," NOT",[632,696,697],{"class":683}," EXISTS",[632,699,700],{"class":646}," evlog_events\n",[632,702,704],{"class":634,"line":703},2,[632,705,706],{"class":646},"(\n",[632,708,710,714,717,720,723,726,729,731],{"class":634,"line":709},3,[632,711,713],{"class":712},"spNyl","  timestamp",[632,715,716],{"class":646},"     DateTime64(",[632,718,719],{"class":683},"3",[632,721,722],{"class":646},", ",[632,724,725],{"class":642},"'",[632,727,728],{"class":659},"UTC",[632,730,725],{"class":642},[632,732,733],{"class":646},"),\n",[632,735,737,740],{"class":634,"line":736},4,[632,738,739],{"class":683},"  level",[632,741,742],{"class":646},"         LowCardinality(String),\n",[632,744,746,749],{"class":634,"line":745},5,[632,747,748],{"class":683},"  service",[632,750,751],{"class":646},"       LowCardinality(String),\n",[632,753,755],{"class":634,"line":754},6,[632,756,757],{"class":646},"  environment   LowCardinality(String),\n",[632,759,761],{"class":634,"line":760},7,[632,762,763],{"class":646},"  request_id    String,\n",[632,765,767],{"class":634,"line":766},8,[632,768,769],{"class":646},"  trace_id      String,\n",[632,771,773],{"class":634,"line":772},9,[632,774,775],{"class":646},"  span_id       String,\n",[632,777,779],{"class":634,"line":778},10,[632,780,781],{"class":646},"  method        LowCardinality(String),\n",[632,783,785,788],{"class":634,"line":784},11,[632,786,787],{"class":712},"  path",[632,789,790],{"class":646},"          String,\n",[632,792,794,797],{"class":634,"line":793},12,[632,795,796],{"class":683},"  status",[632,798,799],{"class":646},"        Nullable(UInt16),\n",[632,801,803],{"class":634,"line":802},13,[632,804,805],{"class":646},"  duration      String,\n",[632,807,809],{"class":634,"line":808},14,[632,810,811],{"class":646},"  duration_ms   Nullable(UInt32),\n",[632,813,815],{"class":634,"line":814},15,[632,816,817],{"class":646},"  error_name    String,\n",[632,819,821],{"class":634,"line":820},16,[632,822,823],{"class":646},"  error_message String,\n",[632,825,827,830],{"class":634,"line":826},17,[632,828,829],{"class":683},"  data",[632,831,832],{"class":646},"          String\n",[632,834,836],{"class":634,"line":835},18,[632,837,838],{"class":646},")\n",[632,840,842,845,848],{"class":634,"line":841},19,[632,843,844],{"class":646},"ENGINE ",[632,846,847],{"class":642},"=",[632,849,850],{"class":646}," MergeTree\n",[632,852,854,857,860,863,866],{"class":634,"line":853},20,[632,855,856],{"class":683},"PARTITION",[632,858,859],{"class":683}," BY",[632,861,862],{"class":646}," toYYYYMM(",[632,864,865],{"class":712},"timestamp",[632,867,838],{"class":646},[632,869,871,874,877,880,883,885],{"class":634,"line":870},21,[632,872,873],{"class":683},"ORDER BY",[632,875,876],{"class":646}," (",[632,878,879],{"class":683},"service",[632,881,882],{"class":646},", environment, ",[632,884,865],{"class":712},[632,886,838],{"class":646},[632,888,890,893,895,898,901,904,907,910],{"class":634,"line":889},22,[632,891,892],{"class":646},"TTL toDateTime(",[632,894,865],{"class":712},[632,896,897],{"class":646},") ",[632,899,900],{"class":642},"+",[632,902,903],{"class":646}," INTERVAL ",[632,905,906],{"class":683},"30",[632,908,909],{"class":683}," DAY",[632,911,912],{"class":646},";\n",[914,915,917,920,921,924],"callout",{"color":916,"icon":13},"info",[548,918,919],{},"ORDER BY (service, environment, timestamp)"," matches how you'll filter most often. Adjust the ",[548,922,923],{},"TTL"," to your retention policy — drop the clause entirely to keep events forever.",[615,926,25],{"id":927},"quick-start",[929,930,931,1037,1158,1262,1369,1474,1609],"code-group",{},[622,932,935],{"className":624,"code":933,"filename":934,"language":627,"meta":628,"style":628},"\u002F\u002F server\u002Fplugins\u002Fevlog.ts\nimport { createClickHouseDrain } from 'evlog\u002Fclickhouse'\n\nexport default defineNitroPlugin((nitroApp) => {\n  nitroApp.hooks.hook('evlog:drain', createClickHouseDrain())\n})\n","Nuxt \u002F Nitro",[548,936,937,943,961,967,996,1030],{"__ignoreMap":628},[632,938,939],{"class":634,"line":635},[632,940,942],{"class":941},"sHwdD","\u002F\u002F server\u002Fplugins\u002Fevlog.ts\n",[632,944,945,947,949,951,953,955,957,959],{"class":634,"line":703},[632,946,639],{"class":638},[632,948,643],{"class":642},[632,950,647],{"class":646},[632,952,650],{"class":642},[632,954,653],{"class":638},[632,956,656],{"class":642},[632,958,660],{"class":659},[632,960,663],{"class":642},[632,962,963],{"class":634,"line":709},[632,964,966],{"emptyLinePlaceholder":965},true,"\n",[632,968,969,972,975,978,981,983,987,990,993],{"class":634,"line":736},[632,970,971],{"class":638},"export",[632,973,974],{"class":638}," default",[632,976,977],{"class":690}," defineNitroPlugin",[632,979,980],{"class":646},"(",[632,982,980],{"class":642},[632,984,986],{"class":985},"sHdIc","nitroApp",[632,988,989],{"class":642},")",[632,991,992],{"class":712}," =>",[632,994,995],{"class":642}," {\n",[632,997,998,1001,1004,1007,1009,1012,1015,1017,1020,1022,1025,1027],{"class":634,"line":745},[632,999,1000],{"class":646},"  nitroApp",[632,1002,1003],{"class":642},".",[632,1005,1006],{"class":646},"hooks",[632,1008,1003],{"class":642},[632,1010,1011],{"class":690},"hook",[632,1013,980],{"class":1014},"swJcz",[632,1016,725],{"class":642},[632,1018,1019],{"class":659},"evlog:drain",[632,1021,725],{"class":642},[632,1023,1024],{"class":642},",",[632,1026,647],{"class":690},[632,1028,1029],{"class":1014},"())\n",[632,1031,1032,1035],{"class":634,"line":754},[632,1033,1034],{"class":642},"}",[632,1036,838],{"class":646},[622,1038,1040],{"className":624,"code":1039,"filename":265,"language":627,"meta":628,"style":628},"import { Hono } from 'hono'\nimport { evlog } from 'evlog\u002Fhono'\nimport { createClickHouseDrain } from 'evlog\u002Fclickhouse'\n\nconst app = new Hono()\napp.use(evlog({ drain: createClickHouseDrain() }))\n",[548,1041,1042,1062,1082,1100,1104,1122],{"__ignoreMap":628},[632,1043,1044,1046,1048,1051,1053,1055,1057,1060],{"class":634,"line":635},[632,1045,639],{"class":638},[632,1047,643],{"class":642},[632,1049,1050],{"class":646}," Hono",[632,1052,650],{"class":642},[632,1054,653],{"class":638},[632,1056,656],{"class":642},[632,1058,1059],{"class":659},"hono",[632,1061,663],{"class":642},[632,1063,1064,1066,1068,1071,1073,1075,1077,1080],{"class":634,"line":703},[632,1065,639],{"class":638},[632,1067,643],{"class":642},[632,1069,1070],{"class":646}," evlog",[632,1072,650],{"class":642},[632,1074,653],{"class":638},[632,1076,656],{"class":642},[632,1078,1079],{"class":659},"evlog\u002Fhono",[632,1081,663],{"class":642},[632,1083,1084,1086,1088,1090,1092,1094,1096,1098],{"class":634,"line":709},[632,1085,639],{"class":638},[632,1087,643],{"class":642},[632,1089,647],{"class":646},[632,1091,650],{"class":642},[632,1093,653],{"class":638},[632,1095,656],{"class":642},[632,1097,660],{"class":659},[632,1099,663],{"class":642},[632,1101,1102],{"class":634,"line":736},[632,1103,966],{"emptyLinePlaceholder":965},[632,1105,1106,1109,1112,1114,1117,1119],{"class":634,"line":745},[632,1107,1108],{"class":712},"const",[632,1110,1111],{"class":646}," app ",[632,1113,847],{"class":642},[632,1115,1116],{"class":642}," new",[632,1118,1050],{"class":690},[632,1120,1121],{"class":646},"()\n",[632,1123,1124,1127,1129,1132,1134,1137,1139,1142,1145,1148,1150,1153,1155],{"class":634,"line":754},[632,1125,1126],{"class":646},"app",[632,1128,1003],{"class":642},[632,1130,1131],{"class":690},"use",[632,1133,980],{"class":646},[632,1135,1136],{"class":690},"evlog",[632,1138,980],{"class":646},[632,1140,1141],{"class":642},"{",[632,1143,1144],{"class":1014}," drain",[632,1146,1147],{"class":642},":",[632,1149,647],{"class":690},[632,1151,1152],{"class":646},"() ",[632,1154,1034],{"class":642},[632,1156,1157],{"class":646},"))\n",[622,1159,1161],{"className":624,"code":1160,"filename":260,"language":627,"meta":628,"style":628},"import express from 'express'\nimport { evlog } from 'evlog\u002Fexpress'\nimport { createClickHouseDrain } from 'evlog\u002Fclickhouse'\n\nconst app = express()\napp.use(evlog({ drain: createClickHouseDrain() }))\n",[548,1162,1163,1180,1199,1217,1221,1234],{"__ignoreMap":628},[632,1164,1165,1167,1170,1173,1175,1178],{"class":634,"line":635},[632,1166,639],{"class":638},[632,1168,1169],{"class":646}," express ",[632,1171,1172],{"class":638},"from",[632,1174,656],{"class":642},[632,1176,1177],{"class":659},"express",[632,1179,663],{"class":642},[632,1181,1182,1184,1186,1188,1190,1192,1194,1197],{"class":634,"line":703},[632,1183,639],{"class":638},[632,1185,643],{"class":642},[632,1187,1070],{"class":646},[632,1189,650],{"class":642},[632,1191,653],{"class":638},[632,1193,656],{"class":642},[632,1195,1196],{"class":659},"evlog\u002Fexpress",[632,1198,663],{"class":642},[632,1200,1201,1203,1205,1207,1209,1211,1213,1215],{"class":634,"line":709},[632,1202,639],{"class":638},[632,1204,643],{"class":642},[632,1206,647],{"class":646},[632,1208,650],{"class":642},[632,1210,653],{"class":638},[632,1212,656],{"class":642},[632,1214,660],{"class":659},[632,1216,663],{"class":642},[632,1218,1219],{"class":634,"line":736},[632,1220,966],{"emptyLinePlaceholder":965},[632,1222,1223,1225,1227,1229,1232],{"class":634,"line":745},[632,1224,1108],{"class":712},[632,1226,1111],{"class":646},[632,1228,847],{"class":642},[632,1230,1231],{"class":690}," express",[632,1233,1121],{"class":646},[632,1235,1236,1238,1240,1242,1244,1246,1248,1250,1252,1254,1256,1258,1260],{"class":634,"line":754},[632,1237,1126],{"class":646},[632,1239,1003],{"class":642},[632,1241,1131],{"class":690},[632,1243,980],{"class":646},[632,1245,1136],{"class":690},[632,1247,980],{"class":646},[632,1249,1141],{"class":642},[632,1251,1144],{"class":1014},[632,1253,1147],{"class":642},[632,1255,647],{"class":690},[632,1257,1152],{"class":646},[632,1259,1034],{"class":642},[632,1261,1157],{"class":646},[622,1263,1265],{"className":624,"code":1264,"filename":270,"language":627,"meta":628,"style":628},"import Fastify from 'fastify'\nimport { evlog } from 'evlog\u002Ffastify'\nimport { createClickHouseDrain } from 'evlog\u002Fclickhouse'\n\nconst app = Fastify()\nawait app.register(evlog, { drain: createClickHouseDrain() })\n",[548,1266,1267,1283,1302,1320,1324,1337],{"__ignoreMap":628},[632,1268,1269,1271,1274,1276,1278,1281],{"class":634,"line":635},[632,1270,639],{"class":638},[632,1272,1273],{"class":646}," Fastify ",[632,1275,1172],{"class":638},[632,1277,656],{"class":642},[632,1279,1280],{"class":659},"fastify",[632,1282,663],{"class":642},[632,1284,1285,1287,1289,1291,1293,1295,1297,1300],{"class":634,"line":703},[632,1286,639],{"class":638},[632,1288,643],{"class":642},[632,1290,1070],{"class":646},[632,1292,650],{"class":642},[632,1294,653],{"class":638},[632,1296,656],{"class":642},[632,1298,1299],{"class":659},"evlog\u002Ffastify",[632,1301,663],{"class":642},[632,1303,1304,1306,1308,1310,1312,1314,1316,1318],{"class":634,"line":709},[632,1305,639],{"class":638},[632,1307,643],{"class":642},[632,1309,647],{"class":646},[632,1311,650],{"class":642},[632,1313,653],{"class":638},[632,1315,656],{"class":642},[632,1317,660],{"class":659},[632,1319,663],{"class":642},[632,1321,1322],{"class":634,"line":736},[632,1323,966],{"emptyLinePlaceholder":965},[632,1325,1326,1328,1330,1332,1335],{"class":634,"line":745},[632,1327,1108],{"class":712},[632,1329,1111],{"class":646},[632,1331,847],{"class":642},[632,1333,1334],{"class":690}," Fastify",[632,1336,1121],{"class":646},[632,1338,1339,1342,1345,1347,1350,1353,1355,1357,1359,1361,1363,1365,1367],{"class":634,"line":754},[632,1340,1341],{"class":638},"await",[632,1343,1344],{"class":646}," app",[632,1346,1003],{"class":642},[632,1348,1349],{"class":690},"register",[632,1351,1352],{"class":646},"(evlog",[632,1354,1024],{"class":642},[632,1356,643],{"class":642},[632,1358,1144],{"class":1014},[632,1360,1147],{"class":642},[632,1362,647],{"class":690},[632,1364,1152],{"class":646},[632,1366,1034],{"class":642},[632,1368,838],{"class":646},[622,1370,1372],{"className":624,"code":1371,"filename":275,"language":627,"meta":628,"style":628},"import { Elysia } from 'elysia'\nimport { evlog } from 'evlog\u002Felysia'\nimport { createClickHouseDrain } from 'evlog\u002Fclickhouse'\n\nconst app = new Elysia().use(evlog({ drain: createClickHouseDrain() }))\n",[548,1373,1374,1394,1413,1431,1435],{"__ignoreMap":628},[632,1375,1376,1378,1380,1383,1385,1387,1389,1392],{"class":634,"line":635},[632,1377,639],{"class":638},[632,1379,643],{"class":642},[632,1381,1382],{"class":646}," Elysia",[632,1384,650],{"class":642},[632,1386,653],{"class":638},[632,1388,656],{"class":642},[632,1390,1391],{"class":659},"elysia",[632,1393,663],{"class":642},[632,1395,1396,1398,1400,1402,1404,1406,1408,1411],{"class":634,"line":703},[632,1397,639],{"class":638},[632,1399,643],{"class":642},[632,1401,1070],{"class":646},[632,1403,650],{"class":642},[632,1405,653],{"class":638},[632,1407,656],{"class":642},[632,1409,1410],{"class":659},"evlog\u002Felysia",[632,1412,663],{"class":642},[632,1414,1415,1417,1419,1421,1423,1425,1427,1429],{"class":634,"line":709},[632,1416,639],{"class":638},[632,1418,643],{"class":642},[632,1420,647],{"class":646},[632,1422,650],{"class":642},[632,1424,653],{"class":638},[632,1426,656],{"class":642},[632,1428,660],{"class":659},[632,1430,663],{"class":642},[632,1432,1433],{"class":634,"line":736},[632,1434,966],{"emptyLinePlaceholder":965},[632,1436,1437,1439,1441,1443,1445,1447,1450,1452,1454,1456,1458,1460,1462,1464,1466,1468,1470,1472],{"class":634,"line":745},[632,1438,1108],{"class":712},[632,1440,1111],{"class":646},[632,1442,847],{"class":642},[632,1444,1116],{"class":642},[632,1446,1382],{"class":690},[632,1448,1449],{"class":646},"()",[632,1451,1003],{"class":642},[632,1453,1131],{"class":690},[632,1455,980],{"class":646},[632,1457,1136],{"class":690},[632,1459,980],{"class":646},[632,1461,1141],{"class":642},[632,1463,1144],{"class":1014},[632,1465,1147],{"class":642},[632,1467,647],{"class":690},[632,1469,1152],{"class":646},[632,1471,1034],{"class":642},[632,1473,1157],{"class":646},[622,1475,1477],{"className":624,"code":1476,"filename":255,"language":627,"meta":628,"style":628},"import { Module } from '@nestjs\u002Fcommon'\nimport { EvlogModule } from 'evlog\u002Fnestjs'\nimport { createClickHouseDrain } from 'evlog\u002Fclickhouse'\n\n@Module({\n  imports: [EvlogModule.forRoot({ drain: createClickHouseDrain() })],\n})\nexport class AppModule {}\n",[548,1478,1479,1499,1519,1537,1541,1554,1589,1595],{"__ignoreMap":628},[632,1480,1481,1483,1485,1488,1490,1492,1494,1497],{"class":634,"line":635},[632,1482,639],{"class":638},[632,1484,643],{"class":642},[632,1486,1487],{"class":646}," Module",[632,1489,650],{"class":642},[632,1491,653],{"class":638},[632,1493,656],{"class":642},[632,1495,1496],{"class":659},"@nestjs\u002Fcommon",[632,1498,663],{"class":642},[632,1500,1501,1503,1505,1508,1510,1512,1514,1517],{"class":634,"line":703},[632,1502,639],{"class":638},[632,1504,643],{"class":642},[632,1506,1507],{"class":646}," EvlogModule",[632,1509,650],{"class":642},[632,1511,653],{"class":638},[632,1513,656],{"class":642},[632,1515,1516],{"class":659},"evlog\u002Fnestjs",[632,1518,663],{"class":642},[632,1520,1521,1523,1525,1527,1529,1531,1533,1535],{"class":634,"line":709},[632,1522,639],{"class":638},[632,1524,643],{"class":642},[632,1526,647],{"class":646},[632,1528,650],{"class":642},[632,1530,653],{"class":638},[632,1532,656],{"class":642},[632,1534,660],{"class":659},[632,1536,663],{"class":642},[632,1538,1539],{"class":634,"line":736},[632,1540,966],{"emptyLinePlaceholder":965},[632,1542,1543,1546,1549,1551],{"class":634,"line":745},[632,1544,1545],{"class":642},"@",[632,1547,1548],{"class":690},"Module",[632,1550,980],{"class":646},[632,1552,1553],{"class":642},"{\n",[632,1555,1556,1559,1561,1564,1566,1569,1571,1573,1575,1577,1579,1581,1583,1586],{"class":634,"line":754},[632,1557,1558],{"class":1014},"  imports",[632,1560,1147],{"class":642},[632,1562,1563],{"class":646}," [EvlogModule",[632,1565,1003],{"class":642},[632,1567,1568],{"class":690},"forRoot",[632,1570,980],{"class":646},[632,1572,1141],{"class":642},[632,1574,1144],{"class":1014},[632,1576,1147],{"class":642},[632,1578,647],{"class":690},[632,1580,1152],{"class":646},[632,1582,1034],{"class":642},[632,1584,1585],{"class":646},")]",[632,1587,1588],{"class":642},",\n",[632,1590,1591,1593],{"class":634,"line":760},[632,1592,1034],{"class":642},[632,1594,838],{"class":646},[632,1596,1597,1599,1602,1606],{"class":634,"line":766},[632,1598,971],{"class":638},[632,1600,1601],{"class":712}," class",[632,1603,1605],{"class":1604},"sBMFI"," AppModule",[632,1607,1608],{"class":642}," {}\n",[622,1610,1612],{"className":624,"code":1611,"filename":290,"language":627,"meta":628,"style":628},"import { initLogger } from 'evlog'\nimport { createClickHouseDrain } from 'evlog\u002Fclickhouse'\n\ninitLogger({\n  env: { service: 'my-app' },\n  drain: createClickHouseDrain(),\n})\n",[548,1613,1614,1633,1651,1655,1664,1688,1701],{"__ignoreMap":628},[632,1615,1616,1618,1620,1623,1625,1627,1629,1631],{"class":634,"line":635},[632,1617,639],{"class":638},[632,1619,643],{"class":642},[632,1621,1622],{"class":646}," initLogger",[632,1624,650],{"class":642},[632,1626,653],{"class":638},[632,1628,656],{"class":642},[632,1630,1136],{"class":659},[632,1632,663],{"class":642},[632,1634,1635,1637,1639,1641,1643,1645,1647,1649],{"class":634,"line":703},[632,1636,639],{"class":638},[632,1638,643],{"class":642},[632,1640,647],{"class":646},[632,1642,650],{"class":642},[632,1644,653],{"class":638},[632,1646,656],{"class":642},[632,1648,660],{"class":659},[632,1650,663],{"class":642},[632,1652,1653],{"class":634,"line":709},[632,1654,966],{"emptyLinePlaceholder":965},[632,1656,1657,1660,1662],{"class":634,"line":736},[632,1658,1659],{"class":690},"initLogger",[632,1661,980],{"class":646},[632,1663,1553],{"class":642},[632,1665,1666,1669,1671,1673,1676,1678,1680,1683,1685],{"class":634,"line":745},[632,1667,1668],{"class":1014},"  env",[632,1670,1147],{"class":642},[632,1672,643],{"class":642},[632,1674,1675],{"class":1014}," service",[632,1677,1147],{"class":642},[632,1679,656],{"class":642},[632,1681,1682],{"class":659},"my-app",[632,1684,725],{"class":642},[632,1686,1687],{"class":642}," },\n",[632,1689,1690,1693,1695,1697,1699],{"class":634,"line":754},[632,1691,1692],{"class":1014},"  drain",[632,1694,1147],{"class":642},[632,1696,647],{"class":690},[632,1698,1449],{"class":646},[632,1700,1588],{"class":642},[632,1702,1703,1705],{"class":634,"line":760},[632,1704,1034],{"class":642},[632,1706,838],{"class":646},[615,1708,504],{"id":1709},"configuration",[1711,1712,1714],"h3",{"id":1713},"environment-variables","Environment variables",[1716,1717,1718,1734],"table",{},[1719,1720,1721],"thead",{},[1722,1723,1724,1728,1731],"tr",{},[1725,1726,1727],"th",{},"Variable",[1725,1729,1730],{},"Required",[1725,1732,1733],{},"Description",[1735,1736,1737,1755,1771,1783,1797],"tbody",{},[1722,1738,1739,1745,1748],{},[1740,1741,1742],"td",{},[548,1743,1744],{},"CLICKHOUSE_ENDPOINT",[1740,1746,1747],{},"Yes",[1740,1749,1750,1751,1754],{},"HTTP interface URL (",[548,1752,1753],{},"CLICKHOUSE_URL"," also accepted)",[1722,1756,1757,1762,1765],{},[1740,1758,1759],{},[548,1760,1761],{},"CLICKHOUSE_USER",[1740,1763,1764],{},"No",[1740,1766,1767,1768],{},"Username. Default ",[548,1769,1770],{},"default",[1722,1772,1773,1778,1780],{},[1740,1774,1775],{},[548,1776,1777],{},"CLICKHOUSE_PASSWORD",[1740,1779,1764],{},[1740,1781,1782],{},"Password. Omit for an unauthenticated local instance",[1722,1784,1785,1790,1792],{},[1740,1786,1787],{},[548,1788,1789],{},"CLICKHOUSE_DATABASE",[1740,1791,1764],{},[1740,1793,1794,1795],{},"Database. Default ",[548,1796,1770],{},[1722,1798,1799,1804,1806],{},[1740,1800,1801],{},[548,1802,1803],{},"CLICKHOUSE_TABLE",[1740,1805,1764],{},[1740,1807,1808,1809],{},"Table. Default ",[548,1810,1811],{},"evlog_events",[1711,1813,336],{"id":1814},"options",[1716,1816,1817,1832],{},[1719,1818,1819],{},[1722,1820,1821,1824,1827,1830],{},[1725,1822,1823],{},"Option",[1725,1825,1826],{},"Type",[1725,1828,1829],{},"Default",[1725,1831,1733],{},[1735,1833,1834,1852,1870,1887,1905,1921,1941,1960,1980,2000],{},[1722,1835,1836,1841,1846,1849],{},[1740,1837,1838],{},[548,1839,1840],{},"endpoint",[1740,1842,1843],{},[548,1844,1845],{},"string",[1740,1847,1848],{},"—",[1740,1850,1851],{},"HTTP interface URL",[1722,1853,1854,1859,1863,1867],{},[1740,1855,1856],{},[548,1857,1858],{},"database",[1740,1860,1861],{},[548,1862,1845],{},[1740,1864,1865],{},[548,1866,1770],{},[1740,1868,1869],{},"Target database",[1722,1871,1872,1876,1880,1884],{},[1740,1873,1874],{},[548,1875,1716],{},[1740,1877,1878],{},[548,1879,1845],{},[1740,1881,1882],{},[548,1883,1811],{},[1740,1885,1886],{},"Target table",[1722,1888,1889,1894,1898,1902],{},[1740,1890,1891],{},[548,1892,1893],{},"username",[1740,1895,1896],{},[548,1897,1845],{},[1740,1899,1900],{},[548,1901,1770],{},[1740,1903,1904],{},"Username",[1722,1906,1907,1912,1916,1918],{},[1740,1908,1909],{},[548,1910,1911],{},"password",[1740,1913,1914],{},[548,1915,1845],{},[1740,1917,1848],{},[1740,1919,1920],{},"Password",[1722,1922,1923,1928,1933,1938],{},[1740,1924,1925],{},[548,1926,1927],{},"asyncInsert",[1740,1929,1930],{},[548,1931,1932],{},"boolean",[1740,1934,1935],{},[548,1936,1937],{},"true",[1740,1939,1940],{},"Batch inserts server-side",[1722,1942,1943,1948,1952,1957],{},[1740,1944,1945],{},[548,1946,1947],{},"waitForAsyncInsert",[1740,1949,1950],{},[548,1951,1932],{},[1740,1953,1954],{},[548,1955,1956],{},"false",[1740,1958,1959],{},"Wait for the flush before responding",[1722,1961,1962,1967,1972,1977],{},[1740,1963,1964],{},[548,1965,1966],{},"transform",[1740,1968,1969],{},[548,1970,1971],{},"(event) => Record\u003Cstring, unknown>",[1740,1973,1974],{},[548,1975,1976],{},"toClickHouseRow",[1740,1978,1979],{},"Map an event to a row",[1722,1981,1982,1987,1992,1997],{},[1740,1983,1984],{},[548,1985,1986],{},"timeout",[1740,1988,1989],{},[548,1990,1991],{},"number",[1740,1993,1994],{},[548,1995,1996],{},"5000",[1740,1998,1999],{},"Request timeout in ms",[1722,2001,2002,2007,2011,2016],{},[1740,2003,2004],{},[548,2005,2006],{},"retries",[1740,2008,2009],{},[548,2010,1991],{},[1740,2012,2013],{},[548,2014,2015],{},"2",[1740,2017,2018],{},"Retry attempts",[615,2020,2022],{"id":2021},"deployment","Deployment",[536,2024,2025],{},"The adapter is identical either way — only the endpoint and credentials change.",[1711,2027,2029],{"id":2028},"self-hosted","Self-hosted",[536,2031,2032],{},"A local or self-managed instance, with or without auth:",[622,2034,2037],{"className":624,"code":2035,"filename":2036,"language":627,"meta":628,"style":628},"createClickHouseDrain({ endpoint: 'http:\u002F\u002Flocalhost:8123' })\n","server\u002Fplugins\u002Fevlog.ts",[548,2038,2039],{"__ignoreMap":628},[632,2040,2041,2044,2046,2048,2051,2053,2055,2057,2059,2061],{"class":634,"line":635},[632,2042,2043],{"class":690},"createClickHouseDrain",[632,2045,980],{"class":646},[632,2047,1141],{"class":642},[632,2049,2050],{"class":1014}," endpoint",[632,2052,1147],{"class":642},[632,2054,656],{"class":642},[632,2056,596],{"class":659},[632,2058,725],{"class":642},[632,2060,650],{"class":642},[632,2062,838],{"class":646},[622,2064,2069],{"className":2065,"code":2066,"filename":2067,"language":2068,"meta":628,"style":628},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","CLICKHOUSE_ENDPOINT=http:\u002F\u002Flocalhost:8123\n# Only if your instance requires auth:\nCLICKHOUSE_USER=evlog\nCLICKHOUSE_PASSWORD=your-password\n",".env","bash",[548,2070,2071,2080,2085,2094],{"__ignoreMap":628},[632,2072,2073,2075,2077],{"class":634,"line":635},[632,2074,1744],{"class":646},[632,2076,847],{"class":642},[632,2078,2079],{"class":659},"http:\u002F\u002Flocalhost:8123\n",[632,2081,2082],{"class":634,"line":703},[632,2083,2084],{"class":941},"# Only if your instance requires auth:\n",[632,2086,2087,2089,2091],{"class":634,"line":709},[632,2088,1761],{"class":646},[632,2090,847],{"class":642},[632,2092,2093],{"class":659},"evlog\n",[632,2095,2096,2098,2100],{"class":634,"line":736},[632,2097,1777],{"class":646},[632,2099,847],{"class":642},[632,2101,2102],{"class":659},"your-password\n",[536,2104,2105,2106,2108,2109,2111,2112,2114,2115,2117],{},"A fresh container runs as ",[548,2107,1770],{}," with no password, which is why ",[548,2110,1893],{},"\ndefaults to ",[548,2113,1770],{}," and ",[548,2116,1911],{}," is optional.",[1711,2119,2121],{"id":2120},"clickhouse-cloud","ClickHouse Cloud",[536,2123,2124],{},"Cloud services always require credentials and speak HTTPS on port 8443:",[622,2126,2128],{"className":624,"code":2127,"filename":2036,"language":627,"meta":628,"style":628},"createClickHouseDrain({\n  endpoint: 'https:\u002F\u002Fabc123.eu-west-1.aws.clickhouse.cloud:8443',\n  password: process.env.CLICKHOUSE_PASSWORD,\n  database: 'logs',\n})\n",[548,2129,2130,2138,2154,2175,2191],{"__ignoreMap":628},[632,2131,2132,2134,2136],{"class":634,"line":635},[632,2133,2043],{"class":690},[632,2135,980],{"class":646},[632,2137,1553],{"class":642},[632,2139,2140,2143,2145,2147,2150,2152],{"class":634,"line":703},[632,2141,2142],{"class":1014},"  endpoint",[632,2144,1147],{"class":642},[632,2146,656],{"class":642},[632,2148,2149],{"class":659},"https:\u002F\u002Fabc123.eu-west-1.aws.clickhouse.cloud:8443",[632,2151,725],{"class":642},[632,2153,1588],{"class":642},[632,2155,2156,2159,2161,2164,2166,2169,2171,2173],{"class":634,"line":709},[632,2157,2158],{"class":1014},"  password",[632,2160,1147],{"class":642},[632,2162,2163],{"class":646}," process",[632,2165,1003],{"class":642},[632,2167,2168],{"class":646},"env",[632,2170,1003],{"class":642},[632,2172,1777],{"class":646},[632,2174,1588],{"class":642},[632,2176,2177,2180,2182,2184,2187,2189],{"class":634,"line":736},[632,2178,2179],{"class":1014},"  database",[632,2181,1147],{"class":642},[632,2183,656],{"class":642},[632,2185,2186],{"class":659},"logs",[632,2188,725],{"class":642},[632,2190,1588],{"class":642},[632,2192,2193,2195],{"class":634,"line":745},[632,2194,1034],{"class":642},[632,2196,838],{"class":646},[622,2198,2200],{"className":2065,"code":2199,"filename":2067,"language":2068,"meta":628,"style":628},"CLICKHOUSE_ENDPOINT=https:\u002F\u002Fabc123.eu-west-1.aws.clickhouse.cloud:8443\nCLICKHOUSE_PASSWORD=your-service-password\nCLICKHOUSE_DATABASE=logs\n",[548,2201,2202,2211,2220],{"__ignoreMap":628},[632,2203,2204,2206,2208],{"class":634,"line":635},[632,2205,1744],{"class":646},[632,2207,847],{"class":642},[632,2209,2210],{"class":659},"https:\u002F\u002Fabc123.eu-west-1.aws.clickhouse.cloud:8443\n",[632,2212,2213,2215,2217],{"class":634,"line":703},[632,2214,1777],{"class":646},[632,2216,847],{"class":642},[632,2218,2219],{"class":659},"your-service-password\n",[632,2221,2222,2224,2226],{"class":634,"line":709},[632,2223,1789],{"class":646},[632,2225,847],{"class":642},[632,2227,2228],{"class":659},"logs\n",[914,2230,2231,2232,2236,2237,2240,2241,2243],{"color":916,"icon":13},"Copy the endpoint from ",[2233,2234,2235],"em",{},"Connect → HTTPS"," in the ClickHouse Cloud console —\nincluding the ",[548,2238,2239],{},":8443"," port. Cloud services idle-suspend, so the first insert\nafter a pause can take a few seconds; raise ",[548,2242,1986],{}," if you see aborts.",[914,2245,2247,2248,2251,2252,2255,2256,2259,2260,2263],{"color":2246,"icon":379},"success","Credentials are sent as ",[548,2249,2250],{},"X-ClickHouse-User"," \u002F ",[548,2253,2254],{},"X-ClickHouse-Key"," ",[556,2257,2258],{},"headers",",\nnever as query parameters, so they never reach ",[548,2261,2262],{},"system.query_log"," or an\nintermediate proxy's access log.",[615,2265,2267],{"id":2266},"verify-it-locally","Verify it locally",[536,2269,2270],{},"Spin up ClickHouse in Docker, create the table and push a real event:",[622,2272,2275],{"className":2065,"code":2273,"filename":2274,"language":2068,"meta":628,"style":628},"docker compose -f packages\u002Fevlog\u002Ftest\u002Fe2e\u002Fdocker-compose.yml up -d\nCLICKHOUSE_ENDPOINT=http:\u002F\u002Flocalhost:8123 pnpm run test:e2e\ndocker compose -f packages\u002Fevlog\u002Ftest\u002Fe2e\u002Fdocker-compose.yml down -v\n","Terminal",[548,2276,2277,2297,2314],{"__ignoreMap":628},[632,2278,2279,2282,2285,2288,2291,2294],{"class":634,"line":635},[632,2280,2281],{"class":1604},"docker",[632,2283,2284],{"class":659}," compose",[632,2286,2287],{"class":659}," -f",[632,2289,2290],{"class":659}," packages\u002Fevlog\u002Ftest\u002Fe2e\u002Fdocker-compose.yml",[632,2292,2293],{"class":659}," up",[632,2295,2296],{"class":659}," -d\n",[632,2298,2299,2301,2303,2305,2308,2311],{"class":634,"line":703},[632,2300,1744],{"class":646},[632,2302,847],{"class":642},[632,2304,596],{"class":659},[632,2306,2307],{"class":1604}," pnpm",[632,2309,2310],{"class":659}," run",[632,2312,2313],{"class":659}," test:e2e\n",[632,2315,2316,2318,2320,2322,2324,2327],{"class":634,"line":709},[632,2317,2281],{"class":1604},[632,2319,2284],{"class":659},[632,2321,2287],{"class":659},[632,2323,2290],{"class":659},[632,2325,2326],{"class":659}," down",[632,2328,2329],{"class":659}," -v\n",[536,2331,2332,2333,2336,2337,2340,2341,2343,2344,2346,2347,2349],{},"The suite is a ",[556,2334,2335],{},"round-trip",": it inserts events, reads them back with\n",[548,2338,2339],{},"SELECT",", and asserts the typed columns and the ",[548,2342,562],{}," JSON survived. The\ncompose file creates ",[548,2345,1811],{}," from the schema above on first boot.\nWithout ",[548,2348,1744],{}," it skips itself with a visible label.",[536,2351,2352,2353,2356],{},"To ",[2233,2354,2355],{},"see"," the events rather than assert on them, seed the sandbox and open the\nprovisioned dashboard — the stack ships a Grafana with the ClickHouse\ndatasource already wired up:",[622,2358,2360],{"className":2065,"code":2359,"filename":2274,"language":2068,"meta":628,"style":628},"pnpm run sandbox:up\npnpm run sandbox:seed\n# → http:\u002F\u002Flocalhost:3001\u002Fd\u002Fevlog-wide-events\n",[548,2361,2362,2372,2381],{"__ignoreMap":628},[632,2363,2364,2367,2369],{"class":634,"line":635},[632,2365,2366],{"class":1604},"pnpm",[632,2368,2310],{"class":659},[632,2370,2371],{"class":659}," sandbox:up\n",[632,2373,2374,2376,2378],{"class":634,"line":703},[632,2375,2366],{"class":1604},[632,2377,2310],{"class":659},[632,2379,2380],{"class":659}," sandbox:seed\n",[632,2382,2383],{"class":634,"line":709},[632,2384,2385],{"class":941},"# → http:\u002F\u002Flocalhost:3001\u002Fd\u002Fevlog-wide-events\n",[536,2387,2388,2389,2392,2393,2396],{},"ClickHouse's built-in ",[548,2390,2391],{},"\u002Fplay"," page at ",[548,2394,2395],{},"http:\u002F\u002Flocalhost:8123\u002Fplay"," also works\nfor raw SQL, but it is deliberately minimal — the dashboard is the better\nstarting point.",[615,2398,2400],{"id":2399},"async-inserts","Async inserts",[536,2402,2403,2404,2409,2410,2413],{},"Log ingestion means many small inserts, and one MergeTree part per request would quickly degrade a table. The adapter therefore enables ",[540,2405,2408],{"href":2406,"rel":2407},"https:\u002F\u002Fclickhouse.com\u002Fdocs\u002Fen\u002Foptimize\u002Fasynchronous-inserts",[544],"asynchronous inserts"," by default, and does ",[556,2411,2412],{},"not"," wait for the flush:",[622,2415,2420],{"className":2416,"code":2418,"language":2419},[2417],"language-text","async_insert=1&wait_for_async_insert=0\n","text",[548,2421,2418],{"__ignoreMap":628},[536,2423,2424],{},"ClickHouse buffers rows server-side and writes them in batches. Draining never blocks a request on disk writes.",[536,2426,2427,2428,2431,2432,2435,2436,1003],{},"Set ",[548,2429,2430],{},"waitForAsyncInsert: true"," if you need the insert acknowledged as durable before the drain resolves — at the cost of latency. Set ",[548,2433,2434],{},"asyncInsert: false"," to insert synchronously, which only makes sense when you already batch client-side with ",[548,2437,2438],{},"evlog\u002Fpipeline",[615,2440,2442],{"id":2441},"querying","Querying",[536,2444,2445,2446,2448],{},"Typed columns are indexed by the sort key; everything else lives in ",[548,2447,562],{}," and is reachable with ClickHouse's JSON functions:",[622,2450,2452],{"className":673,"code":2451,"language":676,"meta":628,"style":628},"-- Error rate per service over the last hour\nSELECT service, countIf(level = 'error') \u002F count() AS error_rate\nFROM evlog_events\nWHERE timestamp > now() - INTERVAL 1 HOUR\nGROUP BY service;\n",[548,2453,2454,2459,2497,2504,2531],{"__ignoreMap":628},[632,2455,2456],{"class":634,"line":635},[632,2457,2458],{"class":941},"-- Error rate per service over the last hour\n",[632,2460,2461,2463,2465,2468,2471,2474,2476,2479,2481,2483,2486,2489,2491,2494],{"class":634,"line":703},[632,2462,2339],{"class":683},[632,2464,1675],{"class":683},[632,2466,2467],{"class":646},", countIf(",[632,2469,2470],{"class":683},"level",[632,2472,2473],{"class":642}," =",[632,2475,656],{"class":642},[632,2477,2478],{"class":659},"error",[632,2480,725],{"class":642},[632,2482,897],{"class":646},[632,2484,2485],{"class":642},"\u002F",[632,2487,2488],{"class":690}," count",[632,2490,1152],{"class":646},[632,2492,2493],{"class":683},"AS",[632,2495,2496],{"class":646}," error_rate\n",[632,2498,2499,2502],{"class":634,"line":709},[632,2500,2501],{"class":683},"FROM",[632,2503,700],{"class":646},[632,2505,2506,2509,2512,2515,2518,2520,2523,2525,2528],{"class":634,"line":736},[632,2507,2508],{"class":683},"WHERE",[632,2510,2511],{"class":712}," timestamp",[632,2513,2514],{"class":642}," >",[632,2516,2517],{"class":683}," now",[632,2519,1449],{"class":642},[632,2521,2522],{"class":642}," -",[632,2524,903],{"class":646},[632,2526,2527],{"class":683},"1",[632,2529,2530],{"class":683}," HOUR\n",[632,2532,2533,2536,2538],{"class":634,"line":745},[632,2534,2535],{"class":683},"GROUP BY",[632,2537,1675],{"class":683},[632,2539,912],{"class":646},[622,2541,2543],{"className":673,"code":2542,"language":676,"meta":628,"style":628},"-- Slowest routes\nSELECT path, count() AS hits, avg(duration_ms) AS avg_ms, quantile(0.95)(duration_ms) AS p95_ms\nFROM evlog_events\nWHERE timestamp > now() - INTERVAL 1 DAY AND method = 'GET' AND duration_ms IS NOT NULL\nGROUP BY path\nORDER BY avg_ms DESC\nLIMIT 20;\n",[548,2544,2545,2550,2596,2602,2645,2652,2662],{"__ignoreMap":628},[632,2546,2547],{"class":634,"line":635},[632,2548,2549],{"class":941},"-- Slowest routes\n",[632,2551,2552,2554,2557,2559,2562,2564,2566,2569,2572,2575,2577,2580,2583,2585,2588,2591,2593],{"class":634,"line":703},[632,2553,2339],{"class":683},[632,2555,2556],{"class":712}," path",[632,2558,722],{"class":646},[632,2560,2561],{"class":690},"count",[632,2563,1152],{"class":646},[632,2565,2493],{"class":683},[632,2567,2568],{"class":646}," hits, ",[632,2570,2571],{"class":690},"avg",[632,2573,2574],{"class":646},"(duration_ms) ",[632,2576,2493],{"class":683},[632,2578,2579],{"class":646}," avg_ms, quantile(",[632,2581,2582],{"class":683},"0",[632,2584,1003],{"class":646},[632,2586,2587],{"class":683},"95",[632,2589,2590],{"class":646},")(duration_ms) ",[632,2592,2493],{"class":683},[632,2594,2595],{"class":646}," p95_ms\n",[632,2597,2598,2600],{"class":634,"line":709},[632,2599,2501],{"class":683},[632,2601,700],{"class":646},[632,2603,2604,2606,2608,2610,2612,2614,2616,2618,2620,2622,2625,2628,2630,2632,2635,2637,2639,2642],{"class":634,"line":736},[632,2605,2508],{"class":683},[632,2607,2511],{"class":712},[632,2609,2514],{"class":642},[632,2611,2517],{"class":683},[632,2613,1449],{"class":642},[632,2615,2522],{"class":642},[632,2617,903],{"class":646},[632,2619,2527],{"class":683},[632,2621,909],{"class":683},[632,2623,2624],{"class":683}," AND",[632,2626,2627],{"class":646}," method ",[632,2629,847],{"class":642},[632,2631,656],{"class":642},[632,2633,2634],{"class":659},"GET",[632,2636,725],{"class":642},[632,2638,2624],{"class":683},[632,2640,2641],{"class":646}," duration_ms ",[632,2643,2644],{"class":683},"IS NOT NULL\n",[632,2646,2647,2649],{"class":634,"line":745},[632,2648,2535],{"class":683},[632,2650,2651],{"class":712}," path\n",[632,2653,2654,2656,2659],{"class":634,"line":754},[632,2655,873],{"class":683},[632,2657,2658],{"class":646}," avg_ms ",[632,2660,2661],{"class":683},"DESC\n",[632,2663,2664,2667,2670],{"class":634,"line":760},[632,2665,2666],{"class":683},"LIMIT",[632,2668,2669],{"class":683}," 20",[632,2671,912],{"class":646},[622,2673,2675],{"className":673,"code":2674,"language":676,"meta":628,"style":628},"-- One request end to end\nSELECT timestamp, level, path, status, data\nFROM evlog_events\nWHERE request_id = '4a8ff3a8-...'\nORDER BY timestamp;\n",[548,2676,2677,2682,2707,2713,2729],{"__ignoreMap":628},[632,2678,2679],{"class":634,"line":635},[632,2680,2681],{"class":941},"-- One request end to end\n",[632,2683,2684,2686,2688,2690,2692,2694,2697,2699,2702,2704],{"class":634,"line":703},[632,2685,2339],{"class":683},[632,2687,2511],{"class":712},[632,2689,722],{"class":646},[632,2691,2470],{"class":683},[632,2693,722],{"class":646},[632,2695,2696],{"class":712},"path",[632,2698,722],{"class":646},[632,2700,2701],{"class":683},"status",[632,2703,722],{"class":646},[632,2705,2706],{"class":683},"data\n",[632,2708,2709,2711],{"class":634,"line":709},[632,2710,2501],{"class":683},[632,2712,700],{"class":646},[632,2714,2715,2717,2720,2722,2724,2727],{"class":634,"line":736},[632,2716,2508],{"class":683},[632,2718,2719],{"class":646}," request_id ",[632,2721,847],{"class":642},[632,2723,656],{"class":642},[632,2725,2726],{"class":659},"4a8ff3a8-...",[632,2728,663],{"class":642},[632,2730,2731,2733,2735],{"class":634,"line":745},[632,2732,873],{"class":683},[632,2734,2511],{"class":712},[632,2736,912],{"class":646},[622,2738,2740],{"className":673,"code":2739,"language":676,"meta":628,"style":628},"-- Reach into a custom field kept only in data\nSELECT JSONExtractString(data, 'user', 'plan') AS plan, count()\nFROM evlog_events\nWHERE timestamp > now() - INTERVAL 7 DAY\nGROUP BY plan;\n",[548,2741,2742,2747,2785,2791,2813],{"__ignoreMap":628},[632,2743,2744],{"class":634,"line":635},[632,2745,2746],{"class":941},"-- Reach into a custom field kept only in data\n",[632,2748,2749,2751,2754,2756,2758,2760,2763,2765,2767,2769,2772,2774,2776,2778,2781,2783],{"class":634,"line":703},[632,2750,2339],{"class":683},[632,2752,2753],{"class":646}," JSONExtractString(",[632,2755,562],{"class":683},[632,2757,722],{"class":646},[632,2759,725],{"class":642},[632,2761,2762],{"class":659},"user",[632,2764,725],{"class":642},[632,2766,722],{"class":646},[632,2768,725],{"class":642},[632,2770,2771],{"class":659},"plan",[632,2773,725],{"class":642},[632,2775,897],{"class":646},[632,2777,2493],{"class":683},[632,2779,2780],{"class":646}," plan, ",[632,2782,2561],{"class":690},[632,2784,1121],{"class":646},[632,2786,2787,2789],{"class":634,"line":709},[632,2788,2501],{"class":683},[632,2790,700],{"class":646},[632,2792,2793,2795,2797,2799,2801,2803,2805,2807,2810],{"class":634,"line":736},[632,2794,2508],{"class":683},[632,2796,2511],{"class":712},[632,2798,2514],{"class":642},[632,2800,2517],{"class":683},[632,2802,1449],{"class":642},[632,2804,2522],{"class":642},[632,2806,903],{"class":646},[632,2808,2809],{"class":683},"7",[632,2811,2812],{"class":683}," DAY\n",[632,2814,2815,2817],{"class":634,"line":745},[632,2816,2535],{"class":683},[632,2818,2819],{"class":646}," plan;\n",[615,2821,2823],{"id":2822},"custom-schema","Custom schema",[536,2825,2826,2827,2829],{},"Pass ",[548,2828,1966],{}," to target a table of your own shape:",[622,2831,2833],{"className":624,"code":2832,"filename":2036,"language":627,"meta":628,"style":628},"import { createClickHouseDrain } from 'evlog\u002Fclickhouse'\n\ncreateClickHouseDrain({\n  table: 'app_logs',\n  transform: event => ({\n    ts: event.timestamp,\n    lvl: event.level,\n    svc: event.service,\n    payload: JSON.stringify(event),\n  }),\n})\n",[548,2834,2835,2853,2857,2865,2881,2897,2912,2927,2942,2962,2971],{"__ignoreMap":628},[632,2836,2837,2839,2841,2843,2845,2847,2849,2851],{"class":634,"line":635},[632,2838,639],{"class":638},[632,2840,643],{"class":642},[632,2842,647],{"class":646},[632,2844,650],{"class":642},[632,2846,653],{"class":638},[632,2848,656],{"class":642},[632,2850,660],{"class":659},[632,2852,663],{"class":642},[632,2854,2855],{"class":634,"line":703},[632,2856,966],{"emptyLinePlaceholder":965},[632,2858,2859,2861,2863],{"class":634,"line":709},[632,2860,2043],{"class":690},[632,2862,980],{"class":646},[632,2864,1553],{"class":642},[632,2866,2867,2870,2872,2874,2877,2879],{"class":634,"line":736},[632,2868,2869],{"class":1014},"  table",[632,2871,1147],{"class":642},[632,2873,656],{"class":642},[632,2875,2876],{"class":659},"app_logs",[632,2878,725],{"class":642},[632,2880,1588],{"class":642},[632,2882,2883,2886,2888,2891,2893,2895],{"class":634,"line":745},[632,2884,2885],{"class":690},"  transform",[632,2887,1147],{"class":642},[632,2889,2890],{"class":985}," event",[632,2892,992],{"class":712},[632,2894,876],{"class":646},[632,2896,1553],{"class":642},[632,2898,2899,2902,2904,2906,2908,2910],{"class":634,"line":754},[632,2900,2901],{"class":1014},"    ts",[632,2903,1147],{"class":642},[632,2905,2890],{"class":646},[632,2907,1003],{"class":642},[632,2909,865],{"class":646},[632,2911,1588],{"class":642},[632,2913,2914,2917,2919,2921,2923,2925],{"class":634,"line":760},[632,2915,2916],{"class":1014},"    lvl",[632,2918,1147],{"class":642},[632,2920,2890],{"class":646},[632,2922,1003],{"class":642},[632,2924,2470],{"class":646},[632,2926,1588],{"class":642},[632,2928,2929,2932,2934,2936,2938,2940],{"class":634,"line":766},[632,2930,2931],{"class":1014},"    svc",[632,2933,1147],{"class":642},[632,2935,2890],{"class":646},[632,2937,1003],{"class":642},[632,2939,879],{"class":646},[632,2941,1588],{"class":642},[632,2943,2944,2947,2949,2952,2954,2957,2960],{"class":634,"line":772},[632,2945,2946],{"class":1014},"    payload",[632,2948,1147],{"class":642},[632,2950,2951],{"class":646}," JSON",[632,2953,1003],{"class":642},[632,2955,2956],{"class":690},"stringify",[632,2958,2959],{"class":646},"(event)",[632,2961,1588],{"class":642},[632,2963,2964,2967,2969],{"class":634,"line":778},[632,2965,2966],{"class":642},"  }",[632,2968,989],{"class":646},[632,2970,1588],{"class":642},[632,2972,2973,2975],{"class":634,"line":784},[632,2974,1034],{"class":642},[632,2976,838],{"class":646},[536,2978,2979,2980,2982],{},"Keys must match your column names — ClickHouse rejects a ",[548,2981,550],{}," insert containing unknown columns.",[615,2984,2986],{"id":2985},"batching","Batching",[536,2988,2989],{},"Pair with a pipeline to insert in larger batches:",[622,2991,2993],{"className":624,"code":2992,"filename":2036,"language":627,"meta":628,"style":628},"import { createDrainPipeline } from 'evlog\u002Fpipeline'\nimport { createClickHouseDrain } from 'evlog\u002Fclickhouse'\nimport type { DrainContext } from 'evlog'\n\nconst pipeline = createDrainPipeline\u003CDrainContext>({\n  batch: { size: 500, intervalMs: 5000 },\n})\n\nexport default defineNitroPlugin((nitroApp) => {\n  nitroApp.hooks.hook('evlog:drain', pipeline(createClickHouseDrain()))\n})\n",[548,2994,2995,3014,3032,3054,3058,3082,3111,3117,3121,3141,3173],{"__ignoreMap":628},[632,2996,2997,2999,3001,3004,3006,3008,3010,3012],{"class":634,"line":635},[632,2998,639],{"class":638},[632,3000,643],{"class":642},[632,3002,3003],{"class":646}," createDrainPipeline",[632,3005,650],{"class":642},[632,3007,653],{"class":638},[632,3009,656],{"class":642},[632,3011,2438],{"class":659},[632,3013,663],{"class":642},[632,3015,3016,3018,3020,3022,3024,3026,3028,3030],{"class":634,"line":703},[632,3017,639],{"class":638},[632,3019,643],{"class":642},[632,3021,647],{"class":646},[632,3023,650],{"class":642},[632,3025,653],{"class":638},[632,3027,656],{"class":642},[632,3029,660],{"class":659},[632,3031,663],{"class":642},[632,3033,3034,3036,3039,3041,3044,3046,3048,3050,3052],{"class":634,"line":709},[632,3035,639],{"class":638},[632,3037,3038],{"class":638}," type",[632,3040,643],{"class":642},[632,3042,3043],{"class":646}," DrainContext",[632,3045,650],{"class":642},[632,3047,653],{"class":638},[632,3049,656],{"class":642},[632,3051,1136],{"class":659},[632,3053,663],{"class":642},[632,3055,3056],{"class":634,"line":736},[632,3057,966],{"emptyLinePlaceholder":965},[632,3059,3060,3062,3065,3067,3069,3072,3075,3078,3080],{"class":634,"line":745},[632,3061,1108],{"class":712},[632,3063,3064],{"class":646}," pipeline ",[632,3066,847],{"class":642},[632,3068,3003],{"class":690},[632,3070,3071],{"class":642},"\u003C",[632,3073,3074],{"class":1604},"DrainContext",[632,3076,3077],{"class":642},">",[632,3079,980],{"class":646},[632,3081,1553],{"class":642},[632,3083,3084,3087,3089,3091,3094,3096,3099,3101,3104,3106,3109],{"class":634,"line":754},[632,3085,3086],{"class":1014},"  batch",[632,3088,1147],{"class":642},[632,3090,643],{"class":642},[632,3092,3093],{"class":1014}," size",[632,3095,1147],{"class":642},[632,3097,3098],{"class":683}," 500",[632,3100,1024],{"class":642},[632,3102,3103],{"class":1014}," intervalMs",[632,3105,1147],{"class":642},[632,3107,3108],{"class":683}," 5000",[632,3110,1687],{"class":642},[632,3112,3113,3115],{"class":634,"line":760},[632,3114,1034],{"class":642},[632,3116,838],{"class":646},[632,3118,3119],{"class":634,"line":766},[632,3120,966],{"emptyLinePlaceholder":965},[632,3122,3123,3125,3127,3129,3131,3133,3135,3137,3139],{"class":634,"line":772},[632,3124,971],{"class":638},[632,3126,974],{"class":638},[632,3128,977],{"class":690},[632,3130,980],{"class":646},[632,3132,980],{"class":642},[632,3134,986],{"class":985},[632,3136,989],{"class":642},[632,3138,992],{"class":712},[632,3140,995],{"class":642},[632,3142,3143,3145,3147,3149,3151,3153,3155,3157,3159,3161,3163,3166,3168,3170],{"class":634,"line":778},[632,3144,1000],{"class":646},[632,3146,1003],{"class":642},[632,3148,1006],{"class":646},[632,3150,1003],{"class":642},[632,3152,1011],{"class":690},[632,3154,980],{"class":1014},[632,3156,725],{"class":642},[632,3158,1019],{"class":659},[632,3160,725],{"class":642},[632,3162,1024],{"class":642},[632,3164,3165],{"class":690}," pipeline",[632,3167,980],{"class":1014},[632,3169,2043],{"class":690},[632,3171,3172],{"class":1014},"()))\n",[632,3174,3175,3177],{"class":634,"line":784},[632,3176,1034],{"class":642},[632,3178,838],{"class":646},[615,3180,3182],{"id":3181},"troubleshooting","Troubleshooting",[536,3184,3185,3190,3191,3193,3194,3196,3197,3200],{},[556,3186,3187],{},[548,3188,3189],{},"Missing endpoint"," — ",[548,3192,1744],{}," is unset and no ",[548,3195,1840],{}," was passed. The drain logs ",[548,3198,3199],{},"[evlog\u002Fclickhouse] Missing endpoint"," once and then does nothing, so requests are never blocked or failed.",[536,3202,3203,3208,3209,2251,3211,3213,3214,2251,3216,3218,3219,1003],{},[556,3204,3205],{},[548,3206,3207],{},"ClickHouse API error: 401"," — Check ",[548,3210,1761],{},[548,3212,1777],{},". Credentials are sent as ",[548,3215,2250],{},[548,3217,2254],{}," headers, never in the query string, so they never reach ",[548,3220,2262],{},[536,3222,3223,3229,3230,3232],{},[556,3224,3225,3228],{},[548,3226,3227],{},"ClickHouse API error: 400"," mentioning unknown column"," — Your table does not match the row shape. Either create the table from the DDL above, or supply a ",[548,3231,1966],{}," matching your columns.",[536,3234,3235,3240,3241,3243,3244,3247],{},[556,3236,3237],{},[548,3238,3239],{},"Cannot parse input"," — The table exists but a column type disagrees. ",[548,3242,2701],{}," is ",[548,3245,3246],{},"Nullable(UInt16)"," because it is absent on non-HTTP events.",[615,3249,3251],{"id":3250},"direct-api-usage","Direct API usage",[622,3253,3256],{"className":624,"code":3254,"filename":3255,"language":627,"meta":628,"style":628},"import { sendBatchToClickHouse, sendToClickHouse } from 'evlog\u002Fclickhouse'\n\nawait sendToClickHouse(event, { endpoint: 'http:\u002F\u002Flocalhost:8123' })\nawait sendBatchToClickHouse(events, { endpoint: 'http:\u002F\u002Flocalhost:8123' })\n","scripts\u002Fbackfill.ts",[548,3257,3258,3282,3286,3313],{"__ignoreMap":628},[632,3259,3260,3262,3264,3267,3269,3272,3274,3276,3278,3280],{"class":634,"line":635},[632,3261,639],{"class":638},[632,3263,643],{"class":642},[632,3265,3266],{"class":646}," sendBatchToClickHouse",[632,3268,1024],{"class":642},[632,3270,3271],{"class":646}," sendToClickHouse",[632,3273,650],{"class":642},[632,3275,653],{"class":638},[632,3277,656],{"class":642},[632,3279,660],{"class":659},[632,3281,663],{"class":642},[632,3283,3284],{"class":634,"line":703},[632,3285,966],{"emptyLinePlaceholder":965},[632,3287,3288,3290,3292,3295,3297,3299,3301,3303,3305,3307,3309,3311],{"class":634,"line":709},[632,3289,1341],{"class":638},[632,3291,3271],{"class":690},[632,3293,3294],{"class":646},"(event",[632,3296,1024],{"class":642},[632,3298,643],{"class":642},[632,3300,2050],{"class":1014},[632,3302,1147],{"class":642},[632,3304,656],{"class":642},[632,3306,596],{"class":659},[632,3308,725],{"class":642},[632,3310,650],{"class":642},[632,3312,838],{"class":646},[632,3314,3315,3317,3319,3322,3324,3326,3328,3330,3332,3334,3336,3338],{"class":634,"line":736},[632,3316,1341],{"class":638},[632,3318,3266],{"class":690},[632,3320,3321],{"class":646},"(events",[632,3323,1024],{"class":642},[632,3325,643],{"class":642},[632,3327,2050],{"class":1014},[632,3329,1147],{"class":642},[632,3331,656],{"class":642},[632,3333,596],{"class":659},[632,3335,725],{"class":642},[632,3337,650],{"class":642},[632,3339,838],{"class":646},[536,3341,3342,722,3345,3348,3349,3352],{},[548,3343,3344],{},"toClickHouseRow()",[548,3346,3347],{},"toJSONEachRow()",", and ",[548,3350,3351],{},"resolveClickHouseUrl()"," are also exported.",[615,3354,3356],{"id":3355},"next-steps","Next steps",[3358,3359,3360,3365,3370,3377],"ul",{},[576,3361,3362,3364],{},[540,3363,61],{"href":62}," — control volume before it reaches ClickHouse",[576,3366,3367,3369],{},[540,3368,431],{"href":432}," — add derived fields to every event",[576,3371,3372,3376],{},[540,3373,3375],{"href":3374},"\u002Flearn\u002Fpipeline","Pipeline"," — batching, retries, and fan-out",[576,3378,3379,3382],{},[540,3380,3381],{"href":143},"Adapters Overview"," — all available destinations",[3384,3385,3386],"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 .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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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}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 .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"title":628,"searchDepth":703,"depth":703,"links":3388},[3389,3390,3391,3392,3396,3400,3401,3402,3403,3404,3405,3406,3407],{"id":617,"depth":703,"text":20},{"id":666,"depth":703,"text":667},{"id":927,"depth":703,"text":25},{"id":1709,"depth":703,"text":504,"children":3393},[3394,3395],{"id":1713,"depth":709,"text":1714},{"id":1814,"depth":709,"text":336},{"id":2021,"depth":703,"text":2022,"children":3397},[3398,3399],{"id":2028,"depth":709,"text":2029},{"id":2120,"depth":709,"text":2121},{"id":2266,"depth":703,"text":2267},{"id":2399,"depth":703,"text":2400},{"id":2441,"depth":703,"text":2442},{"id":2822,"depth":703,"text":2823},{"id":2985,"depth":703,"text":2986},{"id":3181,"depth":703,"text":3182},{"id":3250,"depth":703,"text":3251},{"id":3355,"depth":703,"text":3356},"Insert wide events into ClickHouse over the HTTP interface — typed columns for what you aggregate, full JSON for everything else.","md",[3411,3417],{"label":3412,"icon":3413,"to":542,"target":3414,"color":3415,"variant":3416},"HTTP Interface","i-lucide-external-link","_blank","neutral","subtle",{"label":3418,"icon":3413,"to":2406,"target":3414,"color":3415,"variant":3416},"Async Inserts",{},{"title":186,"icon":189},{"title":531,"description":3408},"b8dc3NsIEn3tMsQl9dMtLg3wor7Drcv6CN6-KdXJv9g",[3424,3426],{"title":181,"path":182,"stem":183,"description":3425,"icon":184,"children":-1},"Push wide events to Grafana Loki — self-hosted, multi-tenant, or Grafana Cloud — with low-cardinality labels and full JSON querying.",{"title":191,"path":192,"stem":193,"description":3427,"icon":194,"children":-1},"Send logs via OpenTelemetry Protocol (OTLP) to Grafana, Datadog, Honeycomb, and any compatible backend. Supports gRPC and HTTP transports.",1785969335217]