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