尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

III 匿名使用遥测(iii-telemetry)内部 Worker 完全指南:数据收集、心跳上报与退出机制

III 匿名使用遥测(iii-telemetry)内部 Worker 完全指南:数据收集、心跳上报与退出机制 III 匿名使用遥测iii-telemetry内部 Worker 完全指南数据收集、心跳上报与退出机制【免费下载链接】iiiEffortlessly compose, extend, and observe every service in real-time for the first time ever.项目地址: https://gitcode.com/GitHub_Trending/mo/iii导读iii 引擎内置了一个名为iii-telemetry的匿名使用遥测 Worker。它负责在后台收集引擎与 SDK 的运行指标功能使用情况、错误率等将脱敏后的遥测载荷发送到 iii 遥测后端并严格遵循用户的退出opt-out设置。本文以 engine/src/workers/telemetry/README.md 为骨架结合 mod.rs、collector.rs、environment.rs 与 amplitude.rs 源码逐层讲解它的注册方式、启停判定、收集内容、发送通道、设备标识与心跳节流机制并给出用户如何查看与关闭该功能的实操方法。读完本文你将完整理解 iii 引擎匿名遥测的架构与数据流能够准确回答引擎在后台到底收集了什么、如何被关闭等问题。模块定位内部引擎 Worker用户不可配置iii-telemetry是引擎的内部 Worker这一点在 README 中写得非常明确它不是用户可配置的 Worker没有自己的iii.worker.yaml它不暴露任何函数或触发器类型纯粹在后台运行它被声明为mandatory必需的注册 Worker随引擎一同启动。源码证据位于 mod.rs 的注册段crate::register_worker!( iii-telemetry, TelemetryWorker, description Anonymous usage telemetry and heartbeat reporting for the engine., mandatory );从源码结构看它实现了引擎统一的Workertraitname/create/initialize/start_background_tasks/destroy并以 Telemetry 作为内部名称通过mandatory标记确保在引擎生命周期内被加载。它收集三类信息匿名运行时指标功能使用情况functions/triggers/workers 的注册与运行、错误率遥测载荷上报将采集到的匿名事件发送到 Amplitude 与 PostHog 后端尊重退出设置用户通过配置或环境变量选择退出后Worker 退化为空操作实现DisabledTelemetryWorker。启动判定什么情况下遥测被禁用TelemetryWorker::create的第一步是调用check_disabled做四重禁用判定任一命中即返回DisabledTelemetryWorker一个所有方法均为空操作的占位实现。四种禁用原因及其来源如下见 mod.rs 与 environment.rs禁用原因触发条件对应日志Config遥测配置中enabled: falseAnonymous telemetry disabled (config).UserOptOut环境变量III_TELEMETRY_ENABLEDfalse或0Anonymous telemetry disabled (user opt-out).CiDetected检测到 CI 环境变量CI、GITHUB_ACTIONS、GITLAB_CI、CIRCLECI、JENKINS_URL、TRAVIS、BUILDKITE、TF_BUILD、CODEBUILD_BUILD_ID、BITBUCKET_BUILD_NUMBER、DRONE、TEAMCITY_VERSION任一存在Anonymous telemetry disabled (CI detected).DevOptOut环境变量III_TELEMETRY_DEVtrue或~/.iii/telemetry_dev_optout文件存在Anonymous telemetry disabled (dev opt-out).其中is_ci_environment的实现逐项检查 12 个常见 CI 平台的环境变量environment.rs保证在 CI 流水线中不会产生开发机器上才有的遥测噪音。四个判定按顺序执行Config优先级最高对应的单元测试如test_check_disabled_returns_config_when_disabled、test_check_disabled_returns_user_optout_for_env_false等覆盖了全部组合场景。启用时引擎会打印一条提示日志并明确告知用户关闭方式mod.rsAnonymous telemetry enabled. Set III_TELEMETRY_ENABLEDfalse to disable.遥测配置结构TelemetryConfig 与默认值虽然该 Worker 对普通用户不可配置但引擎内部通过 JSON 配置注入TelemetryConfigserde(deny_unknown_fields)严格反序列化字段与默认值如下mod.rs字段类型默认值说明enabledbooltrue总开关sdk_api_keyOptionStringNoneSDK 专用 Amplitude key非空时成为活跃客户端posthog_api_keyOptionStringNone覆盖 PostHog 项目 keyposthog_hostOptionStringNone覆盖 PostHog hostheartbeat_interval_secsu64216006 小时心跳上报间隔PostHog key 与 host 的解析遵循配置 环境变量 内置默认值的优先级mod.rskeyposthog_api_key→POSTHOG_PROJECT_API_KEY→POSTHOG_API_KEY→ 内置公共项目 keyphc_mmRHNXK6hkykVuxVp3JPn7R7sbo3ckSpEZLUKjofCWn6定义于 amplitude.rshostposthog_host→POSTHOG_HOST→ 默认https://us.i.posthog.comAmplitude 侧使用引擎内置 API keya7182ac460dde671c8f2e1318b517228amplitude.rs同时被 mod.rs 引用。resolve_posthog_api_key对空字符串做了过滤最终 key 为空时客户端静默跳过发送——这为开发/测试环境提供了天然的空 key 即 no-op通道。全局收集器原子计数器与 CLI 命令聚合collector.rs实现了进程级全局单例TelemetryCollector全部采用AtomicU64Ordering::Relaxedzero overhead统计各模块操作量并用DashMap记录 CLI 命令调用次数collector.rsCroncron_executionsQueuequeue_emits、queue_consumesStatestate_sets、state_gets、state_deletes、state_updatesStreamstream_sets、stream_gets、stream_deletes、stream_lists、stream_updatesPubSubpubsub_publishes、pubsub_subscribesKVkv_sets、kv_gets、kv_deletesAPIapi_requests注册function_registrations、trigger_registrations、worker_registrationsWorkerpeak_active_workersCLIcli_commandsDashMapString, u64snapshot()把这些计数器输出为扁平 JSON。围绕它有一系列便捷跟踪函数track_cron_execution、track_queue_emit、track_state_get、track_pubsub_publish、track_worker_registered等被引擎各模块直接调用例如 engine/src/builtins/queue.rs 在队列消费时调用track_queue_consume()。CLI 命令聚合有专门的安全设计collector.rs命令路径先经过sanitize_cli_command转小写、仅保留字母数字与 、-、_、:、.、截断到 48 字符最多记录 64 个不同 keyCLI_COMMAND_MAX_KEYS防止客户端注入海量 key每次心跳发送时调用take_cli_commands()取出并清空保证计数不会跨两个心跳期累计引擎通过iii-cli:前缀CLI_WORKER_NAME_PREFIX识别 CLI 连接区分真实 Worker与CLI 命令调用。对应的单测test_track_cli_command_normalizes_and_bounds_the_key、test_track_cli_command_caps_distinct_keys、test_take_cli_commands_counts_and_then_clears覆盖了注入、截断与清理逻辑。事件模型与发送通道Amplitude PostHog 双路并行AmplitudeEvent 结构所有遥测事件统一建模为AmplitudeEventamplitude.rs核心字段包括device_id设备标识见下文设备标识小节event_type事件类型first_run、heartbeat、engine_stopped、template_success、template_failure等event_properties/user_properties事件属性与用户属性platform固定iii-engineapp_version来自env!(CARGO_PKG_VERSION)insert_id每次事件生成的 UUID保证幂等去重ip固定$remote由后端解析不发送真实 IP、country: None。发送路径fire-and-forgetsend_product_eventmod.rs使用tokio::join!将同一事件并行发送到 Amplitude 与 PostHog配置了 PostHog 客户端时任一失败均被忽略。发送层amplitude.rs具备以下特征HTTP 客户端超时 30 秒指数退避重试1s、2s、4s最多 3 次MAX_RETRIES 3所有重试耗尽后直接丢弃并返回Ok(())—— 遥测是 fire-and-forget绝不阻塞或失败调用方空 API key 或空事件列表时静默跳过。错误脱敏sanitize_erroramplitude.rs在发送层统一清洗错误字符串剔除/Users/name/、/home/name/、Windows 的\Users\name\、\home\name\路径中的用户名段替换为redacted并将字符串截断到 256 字符。sanitize_event_properties递归遍历 JSON对任何名为error的字段应用脱敏——因此无论错误来自哪个子系统只要被放进事件属性就会被清洗。相应单测sanitize_error_redacts_unix_users_path等验证了 Unix/Windows 路径与嵌套字段的脱敏行为。PostHog 差异映射build_posthog_eventamplitude.rs在把 Amplitude 事件转成 PostHog 批量事件时做了一些规范distinct_iddevice_id且$process_person_profilefalse不建立个人档案保持匿名user_mode按事件类型区分heartbeat/engine_stopped归为using其余安装、创建项目等归为building去重冗余字段iii_version已有app_version时跳过、version、废弃的function_names别名。事件采集内容引擎快照与会话属性每次心跳/停止事件引擎都会调用collect_engine_snapshotmod.rs采集三类数据再通过build_base_propertiesmod.rs组装为扁平属性1. 函数与触发器collect_functions_and_triggers从引擎注册表中枚举全部函数过滤掉内置函数is_iii_builtin_function_id识别engine::、state::、stream::、configuration::、iii::、iii-http::、iii-state::、iii-pubsub::、iii-stream::、iii-cron::、iii-queue::、iii-observability::、bridge.、motia::、publish、motia_step_get、steps::等前缀统计function_count与去重后的trigger_types、trigger_count。2. Worker 数据collect_worker_data遍历引擎的 worker 注册表统计worker_count_total、按运行时node/python/rust →iii-node/iii-py/iii-rust与框架如motia、iii-node分组的数量、worker 名称列表不报告主机名SDK 上报的hostname:pid回退名is_hostname_pid_fallback按 pid 后缀或冒号数字形状识别会被替换为fallback-generic-hostname-pid-N占位符GENERIC_WORKER_NAME_PREFIX避免泄露主机标识从携带 telemetry 元数据的连接中选取一个按 worker UUID 最小者作为 SDK 侧的项目名/语言/框架来源。3. 项目上下文resolve_project_context优先读取项目根目录.iii/project.ini通过III_PROJECT_ROOT或向上查找.iii/project.ini定位解析project_id、project_name、source字段回退到环境变量III_PROJECT_ID与 SDK 上报的项目名。心跳事件额外携带session_start首启为 true、functions_invoked进程内是否调用过用户函数、worker_count_by_language、period_secs、uptime_secs与cli_commands_total/cli_commands通过insert_cli_commands注入并清空。用户属性侧build_user_propertiesmod.rs包括environment.os、environment.arch、environment.cpu_cores、environment.timezone、environment.machine_id、iii_execution_context、env、install_method、iii_version以及可选的host_user_id来自III_HOST_USER_ID或 project.ini与project_id/project_name。模板生命周期事件当项目带有source如 quickstart时后台任务每 3 秒轮询一次指标累加器最长 1 小时在首个用户函数成功/失败时分别上报template_success/template_failuremod.rs。设备标识telemetry.yaml 与稳定匿名 ID设备标识由environment.rs负责核心文件为~/.iii/telemetry.yamltelemetry_config_path()当前 schema 版本为 2TELEMETRY_SCHEMA_VERSION 2。其结构为version: 2 identity: device_id: 生成的匿名设备ID state: first_run_sent: false iii_execution_context: ${III_EXECUTION_CONTEXT:user}生成逻辑environment.rs容器环境is_container_environment下优先使用 project.ini 中宿主写入的device_id与容器 hostname 做加盐 SHA-256盐为常量iii-machine-id否则使用III_HOST_USER_ID hostname 加盐哈希生成docker-hash形式 ID不依赖宿主机硬件信息宿主机环境通过machineid_rsSHA256 SystemID生成机器 ID均不可用时回退为fallback-uuid。文件写入采用临时文件 rename的原子写方式Unix 下权限为0o600并在非容器环境下把 device_id 同步追加到项目.iii/project.ini已存在device_id行则不覆盖。load_or_migrate_v2_state会对旧 schemaversion 1做迁移重置 device_id 并清空 first_run_sent 状态对应单测test_v1_yaml_resets_to_fresh_v2_state。心跳节流claim_heartbeat 与 last_heartbeat 时间戳为避免每次重启引擎都重复上报遥测模块实现了基于时间戳文件的节流门environment.rs心跳时间戳文件位于项目目录.iii/last_heartbeat而非~/.iii因为容器挂载项目目录时时间戳可以跨重启保留而镜像内的 home 目录不会判定逻辑时间戳缺失/不可读/早于interval_secs - HEARTBEAT_STAMP_SLACK_SECSslack 窗口为 600 秒容忍定时器漂移与引擎重启造成的提前触发即认为心跳到期写入当前时间戳并返回 trueFails open没有项目目录时无法持久化时间戳直接放行仅靠进程内定时器限流时间戳早于 now 的未来时间戳时钟回拨按过期处理防止坏值永久静默读-写不加锁源码注释直言若数据中出现问题再加锁文件两个引擎同时启动最坏多报一条事件对u64::MAX等超界 interval 做饱和转换避免负数反转比较逻辑。对应测试test_claim_heartbeat_suppresses_a_restart_within_the_interval、test_claim_heartbeat_sends_once_the_slack_window_is_reached、test_claim_heartbeat_fails_open_*等覆盖了重启抑制、窗口边界、损坏/未来/空白时间戳与无法写入等全部分支。后台任务生命周期boot 心跳、周期心跳与 engine_stoppedstart_background_tasksmod.rs启动三类异步任务1. Boot 心跳延迟 120 秒BOOT_HEARTBEAT_DELAY_SECS 120保证短生命周期引擎也能至少上报一次用tokio::select!的biased分支优先检查 shutdown避免Worker 已停止却在停止后上报首启时先上报first_run事件由check_and_mark_first_run通过~/.iii/telemetry.yaml的state.first_run_sent标记保证只发一次再通过claim_heartbeat判断并上报 bootheartbeatsession_start: true。2. 周期心跳默认 6 小时tokio::time::interval每heartbeat_interval_secstick 一次每次先过claim_heartbeat闸门被抑制则跳过组装session_start: false的心跳事件并发送。3. 停止事件engine_stopped监听到 shutdown 信号时采集最终快照附加uptime_secs并通过 5 秒超时tokio::time::timeout尽力发送后退出循环——保证停止上报不拖慢进程退出。注意源码中DeltaAccumulator增量指标累计整段处于注释状态TODO: Re-enable delta metrics reporting once more important dashboards are ready即当前版本不发送delta_*增量指标只发送快照式属性。用户视角查看与关闭匿名遥测查看遥测是否启用引擎启动时的日志即为最直接信号启用打印Anonymous telemetry enabled. Set III_TELEMETRY_ENABLEDfalse to disable.被禁用时打印对应的禁用原因config / user opt-out / CI detected / dev opt-out。本地遥测状态文件为~/.iii/telemetry.yamlschema v2含identity.device_id与state.first_run_sent心跳节流时间戳为项目目录下.iii/last_heartbeat。关闭匿名使用数据收集用户 opt-out按照 docs/0-11-0/api-reference/disable-telemetry.mdx 的官方步骤运行 iii 前设置环境变量export III_TELEMETRY_ENABLEDfalse永久生效可写入 shell 配置文件echo export III_TELEMETRY_ENABLEDfalse ~/.zshrc source ~/.zshrc设置后引擎将不再发送任何匿名使用数据源码层面该变量为false/0时命中UserOptOut判定Worker 退化为空操作。开发者场景下还可以通过III_TELEMETRY_DEVtrue或创建~/.iii/telemetry_dev_optout文件走DevOptOut通道CI 流水线则会被CiDetected自动抑制。重要区分该设置只控制 iii 引擎的匿名使用数据收集与 OpenTelemetry 可观测性埋点traces/metrics/logs是两套独立机制。若要关闭 OTEL 观测埋点需要设置OTEL_ENABLEDfalse或在OtelConfig中传enabledFalse详见仓库文档中的 OpenTelemetry 集成章节。与可观测性observability的关系遥测与 tracing 的边界从源码结构看遥测与可观测性是两个职责清晰的模块iii-telemetryengine/src/workers/telemetry面向产品改进的匿名使用统计而 observability workeriii-observability负责 trace/log/metric 的查询与摄取。两者存在一处精妙的联动——mod.rs 中的 span 抑制规则观测类函数永不生成引擎侧callspanis_observability_function_id识别engine::traces::*、engine::logs::*、engine::metrics::*、engine::health::*等否则观察观察者会把 span 反馈进正在读取的存储/流中造成无限循环带调用方 trace 上下文traceparent的内置函数调用才生成 span嵌套进调用方已有 trace无上下文的框架内置调用console 轮询、启动读取、引擎自身机制默认被抑制可通过III_OTEL_TRACE_BUILTINStrue强制开启trace_builtins_enabled。对应单测test_should_suppress_invocation_span、test_is_observability_function_id完整验证了这些边界条件。常见问题FAQQiii-telemetry会收集我的源代码或业务数据吗不会。它只统计函数 ID、触发器类型、worker 运行时/框架、计数器等聚合元数据错误字符串在发送层经过路径用户名脱敏与 256 字符截断IP 字段固定为$remote、country 为空、不采集user_id。Q每次启动引擎都会上报吗不会。启动 120 秒后的 boot 心跳也要先过claim_heartbeat闸门项目.iii/last_heartbeat时间戳 600 秒 slack周期心跳默认 6 小时一次重启不会造成重复上报洪峰。Q遥测发送失败会影响引擎吗不会。发送是 fire-and-forget最多 3 次指数退避重试全部失败即丢弃并返回成功绝不阻塞调用方engine_stopped上报还有 5 秒硬超时保护进程退出。Q遥测与 OpenTelemetry 是一回事吗不是。前者是 iii 自身的匿名使用统计本模块后者是面向用户的 traces/metrics/logs 可观测性管道。关闭方式不同III_TELEMETRY_ENABLEDfalsevsOTEL_ENABLEDfalse。深入阅读模块说明engine/src/workers/telemetry/README.md核心实现engine/src/workers/telemetry/mod.rsWorker 生命周期、事件组装、后台任务全局计数器engine/src/workers/telemetry/collector.rs设备标识与环境检测engine/src/workers/telemetry/environment.rs发送通道与脱敏engine/src/workers/telemetry/amplitude.rs用户退出指南docs/0-11-0/api-reference/disable-telemetry.mdx【免费下载链接】iiiEffortlessly compose, extend, and observe every service in real-time for the first time ever.项目地址: https://gitcode.com/GitHub_Trending/mo/iii创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表