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