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