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