[{"data":1,"prerenderedAt":1181},["ShallowReactive",2],{"navigation_docs":3,"-use-cases-telemetry-overview":464,"-use-cases-telemetry-overview-surround":1176},[4,30,80,245,379,434],{"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},"Integrate","\u002Fintegrate","3.integrate",[85,89,157],{"title":36,"path":86,"stem":87,"icon":88},"\u002Fintegrate\u002Foverview","3.integrate\u002F0.overview","i-lucide-plug",{"title":90,"path":91,"stem":92,"children":93,"page":29},"Adapters","\u002Fintegrate\u002Fadapters","3.integrate\u002Fadapters",[94,97,137],{"title":36,"path":95,"stem":96,"icon":39},"\u002Fintegrate\u002Fadapters\u002Foverview","3.integrate\u002Fadapters\u002F01.overview",{"title":98,"path":99,"stem":100,"children":101,"page":29},"Cloud","\u002Fintegrate\u002Fadapters\u002Fcloud","3.integrate\u002Fadapters\u002Fcloud",[102,107,112,117,122,127,132],{"title":103,"path":104,"stem":105,"icon":106},"Axiom","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Faxiom","3.integrate\u002Fadapters\u002Fcloud\u002F01.axiom","i-custom-axiom",{"title":108,"path":109,"stem":110,"icon":111},"OTLP","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fotlp","3.integrate\u002Fadapters\u002Fcloud\u002F02.otlp","i-simple-icons-opentelemetry",{"title":113,"path":114,"stem":115,"icon":116},"PostHog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fposthog","3.integrate\u002Fadapters\u002Fcloud\u002F03.posthog","i-simple-icons-posthog",{"title":118,"path":119,"stem":120,"icon":121},"Sentry","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fsentry","3.integrate\u002Fadapters\u002Fcloud\u002F04.sentry","i-simple-icons-sentry",{"title":123,"path":124,"stem":125,"icon":126},"Better Stack","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fbetter-stack","3.integrate\u002Fadapters\u002Fcloud\u002F05.better-stack","i-simple-icons-betterstack",{"title":128,"path":129,"stem":130,"icon":131},"Datadog","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fdatadog","3.integrate\u002Fadapters\u002Fcloud\u002F06.datadog","i-simple-icons-datadog",{"title":133,"path":134,"stem":135,"icon":136},"HyperDX","\u002Fintegrate\u002Fadapters\u002Fcloud\u002Fhyperdx","3.integrate\u002Fadapters\u002Fcloud\u002F07.hyperdx","i-custom-hyperdx",{"title":138,"path":139,"stem":140,"children":141,"page":29},"Self-Hosted","\u002Fintegrate\u002Fadapters\u002Fself-hosted","3.integrate\u002Fadapters\u002Fself-hosted",[142,147,152],{"title":143,"path":144,"stem":145,"icon":146},"File System","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Ffs","3.integrate\u002Fadapters\u002Fself-hosted\u002F01.fs","i-lucide-hard-drive",{"title":148,"path":149,"stem":150,"icon":151},"NuxtHub","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fnuxthub","3.integrate\u002Fadapters\u002Fself-hosted\u002F02.nuxthub","i-simple-icons-nuxt",{"title":153,"path":154,"stem":155,"icon":156},"Memory","\u002Fintegrate\u002Fadapters\u002Fself-hosted\u002Fmemory","3.integrate\u002Fadapters\u002Fself-hosted\u002F03.memory","i-lucide-cpu",{"title":158,"path":159,"stem":160,"children":161,"page":29},"Frameworks","\u002Fintegrate\u002Fframeworks","3.integrate\u002Fframeworks",[162,166,171,176,181,186,191,196,201,206,211,216,221,226,230,235,240],{"title":36,"path":163,"stem":164,"icon":165},"\u002Fintegrate\u002Fframeworks\u002Foverview","3.integrate\u002Fframeworks\u002F00.overview","i-lucide-layout-grid",{"title":167,"path":168,"stem":169,"icon":170},"Nuxt","\u002Fintegrate\u002Fframeworks\u002Fnuxt","3.integrate\u002Fframeworks\u002F01.nuxt","i-simple-icons-nuxtdotjs",{"title":172,"path":173,"stem":174,"icon":175},"Next.js","\u002Fintegrate\u002Fframeworks\u002Fnextjs","3.integrate\u002Fframeworks\u002F02.nextjs","i-simple-icons-nextdotjs",{"title":177,"path":178,"stem":179,"icon":180},"SvelteKit","\u002Fintegrate\u002Fframeworks\u002Fsveltekit","3.integrate\u002Fframeworks\u002F03.sveltekit","i-simple-icons-svelte",{"title":182,"path":183,"stem":184,"icon":185},"Nitro","\u002Fintegrate\u002Fframeworks\u002Fnitro","3.integrate\u002Fframeworks\u002F04.nitro","i-custom-nitro",{"title":187,"path":188,"stem":189,"icon":190},"TanStack Start","\u002Fintegrate\u002Fframeworks\u002Ftanstack-start","3.integrate\u002Fframeworks\u002F05.tanstack-start","i-custom-tanstack",{"title":192,"path":193,"stem":194,"icon":195},"NestJS","\u002Fintegrate\u002Fframeworks\u002Fnestjs","3.integrate\u002Fframeworks\u002F06.nestjs","i-simple-icons-nestjs",{"title":197,"path":198,"stem":199,"icon":200},"Express","\u002Fintegrate\u002Fframeworks\u002Fexpress","3.integrate\u002Fframeworks\u002F07.express","i-simple-icons-express",{"title":202,"path":203,"stem":204,"icon":205},"Hono","\u002Fintegrate\u002Fframeworks\u002Fhono","3.integrate\u002Fframeworks\u002F08.hono","i-simple-icons-hono",{"title":207,"path":208,"stem":209,"icon":210},"Fastify","\u002Fintegrate\u002Fframeworks\u002Ffastify","3.integrate\u002Fframeworks\u002F09.fastify","i-simple-icons-fastify",{"title":212,"path":213,"stem":214,"icon":215},"Elysia","\u002Fintegrate\u002Fframeworks\u002Felysia","3.integrate\u002Fframeworks\u002F10.elysia","i-custom-elysia",{"title":217,"path":218,"stem":219,"icon":220},"React Router","\u002Fintegrate\u002Fframeworks\u002Freact-router","3.integrate\u002Fframeworks\u002F11.react-router","i-custom-reactrouter",{"title":222,"path":223,"stem":224,"icon":225},"Cloudflare Workers","\u002Fintegrate\u002Fframeworks\u002Fcloudflare-workers","3.integrate\u002Fframeworks\u002F12.cloudflare-workers","i-simple-icons-cloudflare",{"title":227,"path":228,"stem":229,"icon":74},"Standalone","\u002Fintegrate\u002Fframeworks\u002Fstandalone","3.integrate\u002Fframeworks\u002F13.standalone",{"title":231,"path":232,"stem":233,"icon":234},"Astro","\u002Fintegrate\u002Fframeworks\u002Fastro","3.integrate\u002Fframeworks\u002F14.astro","i-simple-icons-astro",{"title":236,"path":237,"stem":238,"icon":239},"oRPC","\u002Fintegrate\u002Fframeworks\u002Forpc","3.integrate\u002Fframeworks\u002F15.orpc","i-lucide-network",{"title":241,"path":242,"stem":243,"icon":244},"AWS Lambda","\u002Fintegrate\u002Fframeworks\u002Faws-lambda","3.integrate\u002Fframeworks\u002F16.aws-lambda","i-custom-lambda",{"title":246,"path":247,"stem":248,"children":249,"page":29},"Use Cases","\u002Fuse-cases","4.use-cases",[250,254,259,288,316,348,369,374],{"title":36,"path":251,"stem":252,"icon":253},"\u002Fuse-cases\u002Foverview","4.use-cases\u002F0.overview","i-lucide-list-checks",{"title":255,"path":256,"stem":257,"icon":258},"Client Logging","\u002Fuse-cases\u002Fclient-logging","4.use-cases\u002F1.client-logging","i-lucide-monitor",{"title":260,"icon":261,"path":262,"stem":263,"children":264,"page":29},"AI SDK","i-simple-icons-vercel","\u002Fuse-cases\u002Fai-sdk","4.use-cases\u002F2.ai-sdk",[265,268,273,278,283],{"title":36,"path":266,"stem":267,"icon":39},"\u002Fuse-cases\u002Fai-sdk\u002Foverview","4.use-cases\u002F2.ai-sdk\u002F01.overview",{"title":269,"path":270,"stem":271,"icon":272},"Usage","\u002Fuse-cases\u002Fai-sdk\u002Fusage","4.use-cases\u002F2.ai-sdk\u002F02.usage","i-lucide-code",{"title":274,"path":275,"stem":276,"icon":277},"Options","\u002Fuse-cases\u002Fai-sdk\u002Foptions","4.use-cases\u002F2.ai-sdk\u002F03.options","i-lucide-sliders",{"title":279,"path":280,"stem":281,"icon":282},"Metadata","\u002Fuse-cases\u002Fai-sdk\u002Fmetadata","4.use-cases\u002F2.ai-sdk\u002F04.metadata","i-lucide-database",{"title":284,"path":285,"stem":286,"icon":287},"Telemetry","\u002Fuse-cases\u002Fai-sdk\u002Ftelemetry","4.use-cases\u002F2.ai-sdk\u002F05.telemetry","i-lucide-activity",{"title":289,"icon":290,"path":291,"stem":292,"children":293,"page":29},"Better Auth","i-simple-icons-betterauth","\u002Fuse-cases\u002Fbetter-auth","4.use-cases\u002F3.better-auth",[294,297,302,307,311],{"title":36,"path":295,"stem":296,"icon":39},"\u002Fuse-cases\u002Fbetter-auth\u002Foverview","4.use-cases\u002F3.better-auth\u002F01.overview",{"title":298,"path":299,"stem":300,"icon":301},"Identify User","\u002Fuse-cases\u002Fbetter-auth\u002Fidentify-user","4.use-cases\u002F3.better-auth\u002F02.identify-user","i-lucide-user-check",{"title":303,"path":304,"stem":305,"icon":306},"Middleware","\u002Fuse-cases\u002Fbetter-auth\u002Fmiddleware","4.use-cases\u002F3.better-auth\u002F03.middleware","i-lucide-shield",{"title":308,"path":309,"stem":310,"icon":258},"Client Sync","\u002Fuse-cases\u002Fbetter-auth\u002Fclient-sync","4.use-cases\u002F3.better-auth\u002F04.client-sync",{"title":312,"path":313,"stem":314,"icon":315},"Performance","\u002Fuse-cases\u002Fbetter-auth\u002Fperformance","4.use-cases\u002F3.better-auth\u002F05.performance","i-lucide-gauge",{"title":317,"icon":318,"path":319,"stem":320,"children":321,"page":29},"Audit Logs","i-lucide-shield-check","\u002Fuse-cases\u002Faudit","4.use-cases\u002F4.audit",[322,325,330,335,340,344],{"title":36,"path":323,"stem":324,"icon":39},"\u002Fuse-cases\u002Faudit\u002Foverview","4.use-cases\u002F4.audit\u002F01.overview",{"title":326,"path":327,"stem":328,"icon":329},"Schema","\u002Fuse-cases\u002Faudit\u002Fschema","4.use-cases\u002F4.audit\u002F02.schema","i-lucide-file-text",{"title":331,"path":332,"stem":333,"icon":334},"Recording","\u002Fuse-cases\u002Faudit\u002Frecording","4.use-cases\u002F4.audit\u002F03.recording","i-lucide-pen-line",{"title":336,"path":337,"stem":338,"icon":339},"Drains","\u002Fuse-cases\u002Faudit\u002Fpipeline","4.use-cases\u002F4.audit\u002F04.pipeline","i-lucide-link",{"title":341,"path":342,"stem":343,"icon":318},"Compliance","\u002Fuse-cases\u002Faudit\u002Fcompliance","4.use-cases\u002F4.audit\u002F05.compliance",{"title":345,"path":346,"stem":347,"icon":79},"Recipes","\u002Fuse-cases\u002Faudit\u002Frecipes","4.use-cases\u002F4.audit\u002F06.recipes",{"title":284,"icon":315,"path":349,"stem":350,"children":351,"page":29},"\u002Fuse-cases\u002Ftelemetry","4.use-cases\u002F4.telemetry",[352,355,360,365],{"title":36,"path":353,"stem":354,"icon":39},"\u002Fuse-cases\u002Ftelemetry\u002Foverview","4.use-cases\u002F4.telemetry\u002F01.overview",{"title":356,"path":357,"stem":358,"icon":359},"Setup","\u002Fuse-cases\u002Ftelemetry\u002Fsetup","4.use-cases\u002F4.telemetry\u002F02.setup","i-lucide-wrench",{"title":361,"path":362,"stem":363,"icon":364},"Ingest","\u002Fuse-cases\u002Ftelemetry\u002Fingest","4.use-cases\u002F4.telemetry\u002F03.ingest","i-lucide-server",{"title":366,"path":367,"stem":368,"icon":79},"Reference","\u002Fuse-cases\u002Ftelemetry\u002Freference","4.use-cases\u002F4.telemetry\u002F04.reference",{"title":370,"path":371,"stem":372,"icon":373},"Enrichers","\u002Fuse-cases\u002Fenrichers","4.use-cases\u002F5.enrichers","i-lucide-sparkles",{"title":375,"path":376,"stem":377,"icon":378},"eve","\u002Fuse-cases\u002Feve","4.use-cases\u002F5.eve","i-custom-eve",{"title":380,"path":381,"stem":382,"children":383,"page":29},"Extend","\u002Fextend","5.extend",[384,388,393,398,403,407,411,415,419,424,429],{"title":36,"path":385,"stem":386,"icon":387},"\u002Fextend\u002Foverview","5.extend\u002F0.overview","i-lucide-blocks",{"title":389,"path":390,"stem":391,"icon":392},"Stream","\u002Fextend\u002Fstream","5.extend\u002F1.stream","i-lucide-radio-tower",{"title":394,"path":395,"stem":396,"icon":397},"Custom framework","\u002Fextend\u002Fcustom-framework","5.extend\u002F10.custom-framework","i-lucide-puzzle",{"title":399,"path":400,"stem":401,"icon":402},"FS reader","\u002Fextend\u002Ffs-reader","5.extend\u002F2.fs-reader","i-lucide-folder-search",{"title":345,"path":404,"stem":405,"icon":406},"\u002Fextend\u002Fconsumer-recipes","5.extend\u002F3.consumer-recipes","i-lucide-chef-hat",{"title":408,"path":409,"stem":410,"icon":387},"Plugins","\u002Fextend\u002Fplugins","5.extend\u002F4.plugins",{"title":412,"path":413,"stem":414,"icon":373},"Custom enrichers","\u002Fextend\u002Fcustom-enrichers","5.extend\u002F5.custom-enrichers",{"title":416,"path":417,"stem":418,"icon":64},"Tail sampling","\u002Fextend\u002Ftail-sampling","5.extend\u002F6.tail-sampling",{"title":420,"path":421,"stem":422,"icon":423},"Identity headers","\u002Fextend\u002Fidentity-headers","5.extend\u002F7.identity-headers","i-lucide-fingerprint",{"title":425,"path":426,"stem":427,"icon":428},"Custom drains","\u002Fextend\u002Fcustom-drains","5.extend\u002F8.custom-drains","i-lucide-share-2",{"title":430,"path":431,"stem":432,"icon":433},"Drain pipeline","\u002Fextend\u002Fdrain-pipeline","5.extend\u002F9.drain-pipeline","i-lucide-workflow",{"title":366,"path":435,"stem":436,"children":437,"page":29},"\u002Freference","6.reference",[438,443,446,451,455,460],{"title":439,"path":440,"stem":441,"icon":442},"Configuration","\u002Freference\u002Fconfiguration","6.reference\u002F1.configuration","i-lucide-settings",{"title":312,"path":444,"stem":445,"icon":315},"\u002Freference\u002Fperformance","6.reference\u002F2.performance",{"title":447,"path":448,"stem":449,"icon":450},"Vite Plugin","\u002Freference\u002Fvite-plugin","6.reference\u002F3.vite-plugin","i-custom-vite",{"title":452,"path":453,"stem":454,"icon":318},"Best Practices","\u002Freference\u002Fbest-practices","6.reference\u002F4.best-practices",{"title":456,"path":457,"stem":458,"icon":459},"vs Other Loggers","\u002Freference\u002Fvs-other-loggers","6.reference\u002F5.vs-other-loggers","i-lucide-scale",{"title":461,"path":462,"stem":463,"icon":373},"Agent Skills","\u002Freference\u002Fagent-skills","6.reference\u002F6.agent-skills",{"id":465,"title":466,"body":467,"description":1165,"extension":1166,"links":1167,"meta":1172,"navigation":1173,"path":353,"seo":1174,"stem":354,"__hash__":1175},"docs\u002F4.use-cases\u002F4.telemetry\u002F01.overview.md","telemetry",{"type":468,"value":469,"toc":1153},"minimark",[470,491,516,527,687,692,707,778,786,789,793,796,801,883,887,977,984,988,1033,1037,1040,1091,1094,1117,1121,1149],[471,472,473,477,478,485,486,490],"p",{},[474,475,476],"code",{},"@evlog\u002Ftelemetry"," brings ",[479,480,484],"a",{"href":481,"rel":482},"https:\u002F\u002Fevlog.dev",[483],"nofollow","evlog","'s wide-event model to tools that run on other people's machines — CLIs, GitHub Actions, dev scripts, and CI jobs. Same philosophy as HTTP logging: ",[487,488,489],"strong",{},"one command execution → one structured event",", not a stream of analytics calls.",[492,493,498],"pre",{"className":494,"code":495,"language":496,"meta":497,"style":497},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm add @evlog\u002Ftelemetry\n","bash","",[474,499,500],{"__ignoreMap":497},[501,502,505,509,513],"span",{"class":503,"line":504},"line",1,[501,506,508],{"class":507},"sBMFI","pnpm",[501,510,512],{"class":511},"sfazB"," add",[501,514,515],{"class":511}," @evlog\u002Ftelemetry\n",[471,517,518,519,522,523,526],{},"You get command name, sanitized flags, duration, and outcome automatically. Call ",[474,520,521],{},"telemetry.set()"," only when you have extra counters — numbers and booleans by default. Raw ",[474,524,525],{},"argv"," is never read; disclosure is generated from your runtime config so it cannot drift from what you actually collect.",[528,529,532,535,680],"prompt",{":actions":530,"description":531,"icon":315},"[\"copy\",\"cursor\",\"claude\"]","Add anonymous telemetry to my CLI or script",[471,533,534],{},"Add privacy-respecting telemetry to my CLI, script, or GitHub Action with @evlog\u002Ftelemetry.",[536,537,538,554,560,574,584,602,612,625,631,642,653],"ul",{},[539,540,541,542,545,546,549,550,553],"li",{},"Detect my entrypoint: citty CLI (",[474,543,544],{},"withTelemetry","), standalone script (",[474,547,548],{},"createTelemetry","), or GitHub Actions (",[474,551,552],{},"createGitHubActionsTelemetry",")",[539,555,556,557],{},"Install: ",[474,558,559],{},"pnpm add @evlog\u002Ftelemetry",[539,561,562,563,566,567,570,571],{},"Citty: wrap the root command in ",[474,564,565],{},"withTelemetry()"," in ",[474,568,569],{},"src\u002Findex.ts"," and add ",[474,572,573],{},"defineTelemetryCommands({ name: TOOL })",[539,575,576,577,580,581],{},"Script \u002F migrator: ",[474,578,579],{},"createTelemetry({ name, version })"," and wrap each logical unit with ",[474,582,583],{},"t.run('command', fn)",[539,585,586,587,590,591,594,595,598,599],{},"GitHub Actions: ",[474,588,589],{},"createGitHubActionsTelemetry()"," — only ",[474,592,593],{},"GITHUB_ACTION"," \u002F ",[474,596,597],{},"GITHUB_EVENT_NAME"," are injected into ",[474,600,601],{},"custom",[539,603,604,605,594,608,611],{},"Declare ",[474,606,607],{},"collect.flags",[474,609,610],{},"collect.fields"," for any string values you need beyond presence-only capture",[539,613,614,615,617,618,620,621],{},"Put your product schema in ",[474,616,601],{}," via ",[474,619,521],{}," — see ",[479,622,624],{"href":623},"\u002Fuse-cases\u002Ftelemetry\u002Freference#extending-the-schema","Extending the schema",[539,626,627,628,630],{},"Call ",[474,629,521],{}," for business counters (numbers\u002Fbooleans) inside handlers or helpers on the same async stack",[539,632,633,634,637,638,641],{},"Run ",[474,635,636],{},"generateDisclosure()"," and commit ",[474,639,640],{},"TELEMETRY.md"," beside the tool",[539,643,644,645,648,649,652],{},"Bake an ingestion URL in ",[474,646,647],{},"endpoint"," (or ",[474,650,651],{},"EVLOG_TELEMETRY_ENDPOINT",") — the local outbox is a buffer, not the destination",[539,654,655,656,659,660,663,664,667,668,671,672,675,676,679],{},"Ship ",[474,657,658],{},"POST \u002Fapi\u002Ftelemetry\u002Fingest"," on my app: use ",[474,661,662],{},"parseIngestBody()"," from ",[474,665,666],{},"@evlog\u002Ftelemetry\u002Fingest"," with ",[474,669,670],{},"allowedTools"," + ",[474,673,674],{},"allowedCustomKeys",", dedupe on ",[474,677,678],{},"idempotencyKey",", return 204 on success",[471,681,682,683],{},"Docs: ",[479,684,685],{"href":685,"rel":686},"https:\u002F\u002Fwww.evlog.dev\u002Fuse-cases\u002Ftelemetry\u002Foverview",[483],[688,689,691],"h2",{"id":690},"from-cli-to-your-backend","From CLI to your backend",[471,693,694,695,698,699,702,703,706],{},"The disk outbox (",[474,696,697],{},"~\u002F.config\u002F{toolName}\u002Ftelemetry\u002Foutbox.ndjson",") is a ",[487,700,701],{},"reliability buffer",", not where telemetry lives long-term. Each run appends one event locally, then the HTTP drain POSTs the backlog to ",[487,704,705],{},"your"," ingestion endpoint. Short-lived CI jobs and offline machines drain on the next invocation.",[708,709,710,720,731,739,749,759,768],"ol",{},[539,711,712,715,716,719],{},[487,713,714],{},"Run"," — ",[474,717,718],{},"my-tool doctor"," executes on the user's machine",[539,721,722,715,725,727,728],{},[487,723,724],{},"Capture",[474,726,476],{}," sanitizes flags, checks consent, and records one ",[474,729,730],{},"RunEvent",[539,732,733,736,737],{},[487,734,735],{},"Buffer"," — the event appends to ",[474,738,697],{},[539,740,741,744,745,748],{},[487,742,743],{},"Send"," — on flush, POST ",[474,746,747],{},"{ events: RunEvent[] }"," to your ingest URL",[539,750,751,715,754,756,757,553],{},[487,752,753],{},"Validate",[474,755,662],{}," allowlists tools and custom keys (",[479,758,361],{"href":362},[539,760,761,764,765,767],{},[487,762,763],{},"Store"," — dedupe on ",[474,766,678],{},", then DB \u002F warehouse \u002F evlog drain",[539,769,770,773,774,777],{},[487,771,772],{},"Ack"," — on ",[474,775,776],{},"2xx",", delivered keys are removed from the outbox",[492,779,784],{"className":780,"code":782,"language":783,"meta":497},[781],"language-text","CLI → @evlog\u002Ftelemetry → outbox.ndjson → POST \u002Fingest → validate → store\n","text",[474,785,782],{"__ignoreMap":497},[471,787,788],{},"Nothing is sent until you configure an endpoint and the server returns a success status. Until then, events stay in the outbox (or are purged on opt-out).",[688,790,792],{"id":791},"why-install-it","Why install it",[471,794,795],{},"You can wire anonymous usage telemetry yourself — outbox file, consent flags, flag sanitization, disclosure markdown, ingest validation, first-run notice. Or you add one dependency and get the evlog playbook baked in.",[797,798,800],"h3",{"id":799},"what-you-get-for-28-kb","What you get for ~28 KB",[802,803,804,815],"table",{},[805,806,807],"thead",{},[808,809,810,813],"tr",{},[811,812],"th",{},[811,814],{},[816,817,818,835,850,870],"tbody",{},[808,819,820,826],{},[821,822,823],"td",{},[487,824,825],{},"Published size",[821,827,828,829,831,832,834],{},"~28 KB ESM (",[474,830,476],{},"), ~8.6 KB gzip — standalone, no dependency on ",[474,833,484],{}," core",[808,836,837,842],{},[821,838,839],{},[487,840,841],{},"Server ingest only",[821,843,844,846,847,849],{},[474,845,666],{}," ~5 KB (~1.7 KB gzip) — ",[474,848,662],{}," without pulling citty wiring into your API",[808,851,852,857],{},[821,853,854],{},[487,855,856],{},"Runtime deps",[821,858,859,671,862,865,866,869],{},[474,860,861],{},"citty",[474,863,864],{},"std-env"," only — both ",[474,867,868],{},"sideEffects: false",", tree-shakeable ESM",[808,871,872,877],{},[821,873,874],{},[487,875,876],{},"Node",[821,878,879,880,882],{},"18+ · ESM · ",[474,881,868],{}," on the package",[797,884,886],{"id":885},"fits-wherever-your-code-runs","Fits wherever your code runs",[802,888,889,902],{},[805,890,891],{},[808,892,893,896,899],{},[811,894,895],{},"Surface",[811,897,898],{},"Entry",[811,900,901],{},"Lines of integration",[816,903,904,922,940,961],{},[808,905,906,911,916],{},[821,907,908],{},[487,909,910],{},"citty CLI",[821,912,913,915],{},[474,914,565],{}," on the root command",[821,917,918,919],{},"One wrapper + optional ",[474,920,921],{},"defineTelemetryCommands()",[808,923,924,929,937],{},[821,925,926],{},[487,927,928],{},"Script \u002F migrator",[821,930,931,671,934],{},[474,932,933],{},"createTelemetry()",[474,935,936],{},"t.run()",[821,938,939],{},"Wrap each logical run",[808,941,942,947,951],{},[821,943,944],{},[487,945,946],{},"GitHub Actions",[821,948,949],{},[474,950,589],{},[821,952,953,954,594,957,960],{},"Same as script; ",[474,955,956],{},"ghaAction",[474,958,959],{},"ghaEvent"," auto-injected",[808,962,963,968,974],{},[821,964,965],{},[487,966,967],{},"Your API (ingest)",[821,969,970,663,972],{},[474,971,662],{},[474,973,666],{},[821,975,976],{},"One validator + one POST route",[471,978,979,980,983],{},"No framework lock-in. No PostHog \u002F Segment \u002F custom analytics SDK. No second schema to maintain — disclosure is generated from the same ",[474,981,982],{},"collect"," config the CLI uses at runtime.",[797,985,987],{"id":986},"what-you-skip-building","What you skip building",[536,989,990,995,1004,1007,1015,1018,1024,1027],{},[539,991,992,993,553],{},"Privacy-safe flag capture (never reads raw ",[474,994,525],{},[539,996,997,594,1000,1003],{},[474,998,999],{},"DO_NOT_TRACK",[474,1001,1002],{},"EVLOG_TELEMETRY"," \u002F persisted opt-out with outbox purge",[539,1005,1006],{},"Disk outbox with lockfile, stale-lock recovery, and backlog drain",[539,1008,1009,1010,671,1012,553],{},"Auto-generated disclosure (",[474,1011,640],{},[474,1013,1014],{},"telemetry status",[539,1016,1017],{},"First-run notice with opt-out instructions",[539,1019,1020,1021,1023],{},"Typed ",[474,1022,521],{}," with allowlisted string fields",[539,1025,1026],{},"Server-side ingest validation aligned with the CLI envelope",[539,1028,1029,1030],{},"Hard guarantee: ",[487,1031,1032],{},"telemetry never throws, never blocks exit",[797,1034,1036],{"id":1035},"the-payoff","The payoff",[471,1038,1039],{},"Once ingest is live you can answer product questions that CLI authors usually guess at:",[536,1041,1042,1054,1065,1072,1079],{},[539,1043,1044,1045,1048,1049,1048,1052,553],{},"Which commands are actually used (",[474,1046,1047],{},"doctor"," vs ",[474,1050,1051],{},"sync",[474,1053,1014],{},[539,1055,1056,1057,1060,1061,1064],{},"Where runs fail (",[474,1058,1059],{},"outcome",", ",[474,1062,1063],{},"errorCode",", version breakdown)",[539,1066,1067,1068,1071],{},"How long operations take (",[474,1069,1070],{},"durationMs"," per command)",[539,1073,1074,1075,1078],{},"Which versions are still in the wild (",[474,1076,1077],{},"tool.version"," on every event)",[539,1080,1081,1082,1060,1085,1060,1088,553],{},"Whether CI or local dev dominates (",[474,1083,1084],{},"env.ci",[474,1086,1087],{},"env.agent",[474,1089,1090],{},"env.tty",[471,1092,1093],{},"All from one wide event per run — the same mental model as evlog on the server, without bolting a browser analytics stack onto a terminal tool.",[1095,1096,1099,1100,715,1107,1060,1110,1113,1114,1116],"callout",{"color":1097,"icon":1098},"neutral","i-lucide-package","Try it locally: ",[479,1101,1104],{"href":1102,"rel":1103},"https:\u002F\u002Fgithub.com\u002FHugoRCD\u002Fevlog\u002Ftree\u002Fmain\u002Fexamples\u002Ftelemetry-playground",[483],[474,1105,1106],{},"examples\u002Ftelemetry-playground",[474,1108,1109],{},"pnpm run cli -- doctor",[474,1111,1112],{},"EVLOG_TELEMETRY_DEBUG=1"," to inspect payloads, ",[474,1115,1014],{}," for disclosure.",[688,1118,1120],{"id":1119},"see-also","See also",[536,1122,1123,1128,1133,1138,1144],{},[539,1124,1125,1127],{},[479,1126,356],{"href":357}," — citty, scripts, GitHub Actions, delivery config",[539,1129,1130,1132],{},[479,1131,361],{"href":362}," — server endpoint, validation, storage",[539,1134,1135,1137],{},[479,1136,366],{"href":367}," — envelope, schema extensions, disclosure, consent",[539,1139,1140,1143],{},[479,1141,1142],{"href":323},"Audit"," — wide events for security-sensitive actions",[539,1145,1146,1148],{},[479,1147,430],{"href":431}," — forward ingested events into Axiom, Datadog, OTLP, or a custom store",[1150,1151,1152],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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);}",{"title":497,"searchDepth":1154,"depth":1154,"links":1155},2,[1156,1157,1164],{"id":690,"depth":1154,"text":691},{"id":791,"depth":1154,"text":792,"children":1158},[1159,1161,1162,1163],{"id":799,"depth":1160,"text":800},3,{"id":885,"depth":1160,"text":886},{"id":986,"depth":1160,"text":987},{"id":1035,"depth":1160,"text":1036},{"id":1119,"depth":1154,"text":1120},"Wide-event telemetry for CLIs and automation — evlog's one-event-per-run model for tools on user machines, with privacy-safe flags, consent, outbox, and auto-generated disclosure.","md",[1168,1170,1171],{"label":356,"icon":359,"to":357,"color":1097,"variant":1169},"subtle",{"label":361,"icon":364,"to":362,"color":1097,"variant":1169},{"label":366,"icon":79,"to":367,"color":1097,"variant":1169},{},{"title":36,"icon":39},{"title":466,"description":1165},"9SIZso9CV_inzTKLtjpwRFB6Qdav5RospbbkfI9nvQU",[1177,1179],{"title":345,"path":346,"stem":347,"description":1178,"icon":79,"children":-1},"File system, Axiom, and Postgres recipes for audit logs, plus mockAudit for tests and the full API reference.",{"title":356,"path":357,"stem":358,"description":1180,"icon":359,"children":-1},"Wire @evlog\u002Ftelemetry into citty CLIs, standalone scripts, and GitHub Actions — delivery config, automatic flag capture, telemetry.set(), and debug mode.",1784204017789]