---
title: "telemetry"
description: "为在他人机器上运行的 CLI 和自动化工具提供每次运行一个事件，并支持隐私安全的标志、同意机制、outbox，以及从同一配置生成的披露内容"
canonical_url: "https://evlog.zhcndoc.com/use-cases/telemetry/overview"
---
# telemetry

> 为在他人机器上运行的 CLI 和自动化工具提供每次运行一个事件，并支持隐私安全的标志、同意机制、outbox，以及从同一配置生成的披露内容

`@evlog/telemetry` 将 [evlog](https://evlog.dev) 的 wide-event 模型带到了在他人机器上运行的工具中：CLI、GitHub Actions、开发脚本和 CI 作业。理念与 HTTP 日志记录相同：**一次命令执行 → 一个结构化事件**，而不是一连串分析调用。

<code-group>

```bash [pnpm]
pnpm add @evlog/telemetry
```

```bash [bun]
bun add @evlog/telemetry
```

```bash [yarn]
yarn add @evlog/telemetry
```

```bash [npm]
npm install @evlog/telemetry
```

</code-group>

你会自动获得命令名称、经过清理的标志、持续时间和结果。只有在需要额外计数器时才调用 `telemetry.set()`，数字和布尔值默认即可。永远不会读取原始 `argv`；披露内容根据运行时配置生成，因此不会与实际收集的内容产生偏差。

<prompt :actions="["copy","cursor","claude"]" description="为我的 CLI 或脚本添加匿名遥测" icon="i-lucide-gauge">

使用 @evlog/telemetry 为我的 CLI、脚本或 GitHub Action 添加尊重隐私的遥测。

- 检测我的入口点：citty CLI（`withTelemetry`）、独立脚本（`createTelemetry`）或 GitHub Actions（`createGitHubActionsTelemetry`）
- 安装：`pnpm add @evlog/telemetry`（或 npm/yarn/bun）
- Citty：在 `src/index.ts` 中使用 `withTelemetry()` 包装根命令，并添加 `defineTelemetryCommands({ name: TOOL })`
- 脚本／迁移器：使用 `createTelemetry({ name, version })`，并使用 `t.run('command', fn)` 包装每个逻辑单元
- GitHub Actions：使用 `createGitHubActionsTelemetry()`。只有 `GITHUB_ACTION`／`GITHUB_EVENT_NAME` 会被注入 `custom`
- 为所有需要超出 `"<set>"` 标记的字符串值声明 `collect.flags`／`collect.fields`
- 通过 `telemetry.set()` 将你的产品 schema 放入 `custom`，参见 [扩展 schema](https://evlog.zhcndoc.com/use-cases/telemetry/reference#extending-the-schema)
- 在处理器或辅助函数中、同一异步调用栈内，使用 `telemetry.set()` 记录业务计数器（数字／布尔值）
- 运行 `generateDisclosure()`，并将 `TELEMETRY.md` 与工具放在一起提交
- 在 `endpoint` 中写入采集 URL（或使用 `EVLOG_TELEMETRY_ENDPOINT`）。本地 outbox 是缓冲区，而不是目标地址
- 在我的应用中提供 `POST /api/telemetry/ingest`：使用来自 `@evlog/telemetry/ingest` 的 `parseIngestBody()`，并配合 `allowedTools` + `allowedCustomKeys`，根据 `idempotencyKey` 去重，成功时返回 204

文档：[https://www.evlog.dev/use-cases/telemetry/overview](https://www.evlog.dev/use-cases/telemetry/overview)

</prompt>

## 从 CLI 到你的后端

磁盘 outbox（`~/.config/{toolName}/telemetry/outbox.ndjson`）是一个**可靠性缓冲区**，而不是遥测长期存放的位置。每次运行都会在本地追加一条事件，然后 HTTP drain 会将积压数据 POST 到**你的**采集端点。生命周期很短的 CI 作业和离线机器会在下次调用时继续排空。

1. **运行**：`my-tool doctor` 在用户的机器上执行
2. **捕获**：`@evlog/telemetry` 清理标志、检查同意状态，并记录一个 `RunEvent`
3. **缓冲**：事件追加到 `~/.config/{toolName}/telemetry/outbox.ndjson`
4. **发送**：刷新时，将 `{ events: RunEvent[] }` POST 到你的采集 URL
5. **验证**：`parseIngestBody()` 对工具和自定义键执行允许列表校验（[接收](https://evlog.zhcndoc.com/use-cases/telemetry/ingest)）
6. **存储**：根据 `idempotencyKey` 去重，然后写入 DB／warehouse／evlog drain
7. **确认**：收到 `2xx` 后，已交付的键会从 outbox 中移除

```text
CLI → @evlog/telemetry → outbox.ndjson → POST /ingest → validate → store
```

在你配置端点并且服务器返回成功状态之前，不会发送任何内容。在此之前，事件会保留在 outbox 中（或者在选择退出时被清除）。

## 为什么安装它

你可以自行接入匿名使用遥测：outbox 文件、同意标志、标志清理、披露 Markdown、接收验证、首次运行通知。或者添加一个依赖，直接获得内置 evlog 实践方案。

### 约 28 KB 你能得到什么

<table>
<thead>
  <tr>
    <th>
      
    </th>
    
    <th>
      
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <strong>
        发布体积
      </strong>
    </td>
    
    <td>
      ~28 KB ESM（<code>
        @evlog/telemetry
      </code>
      
      ），~8.6 KB gzip —— 独立运行，不依赖 <code>
        evlog
      </code>
      
       核心
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        仅服务器摄取
      </strong>
    </td>
    
    <td>
      <code>
        @evlog/telemetry/ingest
      </code>
      
       ~5 KB（~1.7 KB gzip）——在不把 citty 绑定引入你的 API 的情况下使用 <code>
        parseIngestBody()
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        运行时依赖
      </strong>
    </td>
    
    <td>
      仅 <code>
        citty
      </code>
      
       + <code>
        std-env
      </code>
      
       —— 二者均为 <code>
        sideEffects: false
      </code>
      
      ，可进行 ESM 树摇优化
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        Node
      </strong>
    </td>
    
    <td>
      18+ · ESM · 包级别 <code>
        sideEffects: false
      </code>
    </td>
  </tr>
</tbody>
</table>

### 适用于代码运行的任何地方

<table>
<thead>
  <tr>
    <th>
      使用场景
    </th>
    
    <th>
      入口
    </th>
    
    <th>
      集成行数
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <strong>
        citty CLI
      </strong>
    </td>
    
    <td>
      根命令上的 <code>
        withTelemetry()
      </code>
    </td>
    
    <td>
      一个包装器 + 可选的 <code>
        defineTelemetryCommands()
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        脚本／迁移器
      </strong>
    </td>
    
    <td>
      <code>
        createTelemetry()
      </code>
      
       + <code>
        t.run()
      </code>
    </td>
    
    <td>
      为每次逻辑运行包一层
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        GitHub Actions
      </strong>
    </td>
    
    <td>
      <code>
        createGitHubActionsTelemetry()
      </code>
    </td>
    
    <td>
      与脚本相同；自动注入 <code>
        ghaAction
      </code>
      
      ／<code>
        ghaEvent
      </code>
    </td>
  </tr>
  
  <tr>
    <td>
      <strong>
        你的 API（摄取）
      </strong>
    </td>
    
    <td>
      来自 <code>
        @evlog/telemetry/ingest
      </code>
      
       的 <code>
        parseIngestBody()
      </code>
    </td>
    
    <td>
      一个校验器 + 一个 POST 路由
    </td>
  </tr>
</tbody>
</table>

不绑定任何框架。不使用 PostHog／Segment／自定义分析 SDK。无需维护第二套 schema，因为披露内容是从 CLI 在运行时使用的同一 `collect` 配置生成的。

### 你无需再构建的内容

- 隐私安全的标志采集（从不读取原始 `argv`）
- `DO_NOT_TRACK`／`EVLOG_TELEMETRY`／带出站文件清理的持久化退出
- 带锁文件、过期锁恢复和积压清空的磁盘出站文件
- 自动生成的披露（`TELEMETRY.md` + `telemetry status`）
- 带退出提示的首次运行通知
- 带允许列表字符串字段的类型化 `telemetry.set()`
- 与 CLI 信封保持一致的服务端摄取校验
- 硬性保证：**遥测永不抛错，永不阻塞退出**

### 价值回报

一旦摄取上线，你就能回答 CLI 作者通常只能猜测的产品问题：

- 实际使用了哪些命令（`doctor` vs `sync` vs `telemetry status`）
- 运行在哪些地方失败（`outcome`、`errorCode`、版本分布）
- 操作耗时多久（每个命令的 `durationMs`）
- 还有哪些版本仍在被使用（每个事件上的 `tool.version`）
- CI 还是本地开发占主导（`env.ci`、`env.agent`、`env.tty`）

所有信息都来自每次运行的一个 wide event，与服务器端的 evlog 使用相同的思维模型，无需将浏览器分析技术栈强行接入终端工具。

<callout color="neutral" icon="i-lucide-package">

在本地试用：[`examples/telemetry-playground`](https://github.com/evloghq/evlog/tree/main/examples/telemetry-playground)：`pnpm run cli -- doctor`，使用 `EVLOG_TELEMETRY_DEBUG=1` 检查负载，使用 `telemetry status` 查看披露内容

</callout>

## 另请参阅

- [设置](https://evlog.zhcndoc.com/use-cases/telemetry/setup)：citty、脚本、GitHub Actions、交付配置
- [接收](https://evlog.zhcndoc.com/use-cases/telemetry/ingest)：服务器端点、验证、存储
- [参考](https://evlog.zhcndoc.com/use-cases/telemetry/reference)：信封、schema 扩展、披露、同意
- [审计](https://evlog.zhcndoc.com/use-cases/audit/overview)：面向安全敏感操作的 wide event
- [Drain 管道](https://evlog.zhcndoc.com/extend/drain-pipeline)：将接收的事件转发到 Axiom、Datadog、OTLP 或自定义存储中

---

- [设置](https://evlog.zhcndoc.com/use-cases/telemetry/setup)
- [接收](https://evlog.zhcndoc.com/use-cases/telemetry/ingest)
- [参考](https://evlog.zhcndoc.com/use-cases/telemetry/reference)


## Sitemap

See the full [sitemap](https://evlog.zhcndoc.com/sitemap.md) for all pages.
