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