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