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