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