yx_tracking_flutter/0.总体目标与边界.md

13 KiB
Raw Permalink Blame History

一、总体目标与边界

1.1 目标

基于现有后端接口,建设一套统一的埋点 SDK覆盖

  • 技术栈:
    • Flutter独立纯 Dart SDK
    • Android原生 Kotlin SDK
    • iOS原生 Swift SDK
  • 对齐后端接口:
    • GET /api/ExternalEventlogs/GetSystemAllDimInfo
    • POST /api/ExternalEventlogs/AddEventListLog
    • POST /api/ExternalEventlogs/AddEventLog
  • 三阶段演进:
    • Phase 1可用性 + 安全稳定性
    • Phase 2可维护性 + 配置化 + 调试
    • Phase 3可观测性 + 动态策略 + 插件化

不绑定具体业务逻辑,但要能支持 OA、教育等各类场景。

1.2 统一事件数据模型

请求结构(与后端对齐)

jsonc

{
  "system_code": "string",
  "eventType": "string",
  "userInfo": {
    "userId": 0,
    "userName": "string",
    "account": "string"
  },
  "clientType": 1,
  "clientTimestamp": 0,
  "timestamp": "2026-01-26T08:29:44.734Z",
  "deviceInfo": {
    "os": "string",
    "model": "string",
    "screenResolution": "string"
  },
  "eventParams": {
    // 事件上下文,例如 page、buttonId、url…
  },
  "customTags": {
    // 扩展维度,业务可自定义
  }
}

统一对外 API 设计(跨三端)

(伪接口,三端风格尽量保持一致)

ts

class Analytics {
  static init(config: SDKConfig): void | Future<void>

  static track(
    eventType: string,
    options?: {
      eventParams?: Map<string, any>
      customTags?: Map<string, any>
      timestamp?: number  // 毫秒级 client 时间,可不传
    }
  ): void | Future<void>

  static setUser(userInfo: UserInfo | null): void | Future<void>

  static setDeviceInfo(deviceInfo: DeviceInfo): void | Future<void>

  static flush(): void | Future<void>

  static setDebug(enabled: boolean): void
}

SDKConfig 关键字段(统一):

  • systemCode: string
  • endpointBaseUrl: string(如 https://host/api/ExternalEventlogs
  • clientType: int统一约定1=Android2=iOS3=Flutter
  • enableDebug: boolean
  • batchSize: int(默认 20
  • flushInterval: int(秒,默认 15
  • maxCacheSize: int(默认 5000
  • maxRetryCount: int(默认 3
  • connectTimeout, readTimeout

二、整体架构设计(通用视角)

SDK 内部统一分层:

  1. API 层Facade
    • 暴露 init / track / flush / setUser / setDebug
    • 做参数校验、线程切换(原生)。
  2. EventManager事件管理层
    • 构造标准事件对象(填充 system_code、userInfo、deviceInfo、时间
    • 写入本地队列;触发上传调度。
  3. Storage存储层
    • 事件持久化SQLite / 本地 KV
    • 控制队列长度、过期清理。
  4. NetworkClient网络层
    • 封装调用:AddEventListLog(优先)、AddEventLog(可选降级)。
    • 统一超时、重试、错误处理。
  5. Config / DimensionManager配置 & 维度)
    • 管理 SDKConfig。
    • Phase 2+:拉取 GetSystemAllDimInfo,存本地。
  6. Validator / Debug校验 & 调试)
    • Phase 2+:基于配置做事件参数校验。
    • 统一 debug 日志输出。
  7. Interceptors / Plugins插件层
    • Phase 3对事件发送前后提供 Hook。

三、三端实现策略

3.1 Flutter 独立 SDK纯 Dart

  • 语言Dart
  • 存储:推荐 sqfliteSQLitehiveKV
    • events(id, payload_json, retry_count, create_time)
  • 网络:diohttp
  • 调度:
    • Timer.periodic 实现定时 flush
    • 控制并发:用一个「上传中」标志避免并发多次 flush
  • 生命周期:
    • SDK 已实现 Analytics.bindLifecycleObserver(),自动在后台/销毁时 flush
    • 应用也可手动调用 flush()

3.2 Android SDK

  • 语言Kotlin对 Java 兼容)
  • 存储Room 或 SQLite 封装
  • 网络OkHttp + Retrofit
  • 线程Kotlin Coroutines + 单一上传协程
  • 生命周期:ProcessLifecycleOwner 监听前后台 → 后台前触发 flush

3.3 iOS SDK

  • 语言Swift暴露 ObjC 兼容 API
  • 存储SQLite 或 Core Data 轻量封装
  • 网络URLSession
  • 生命周期:监听 willResignActive / didEnterBackground 调用 flush

四、三阶段规划(含架构与验收)


Phase 1可用性 + 安全稳定性

4.1 目标

  • 提供稳定、可用的基础事件采集 & 批量上报能力。
  • 不影响业务性能和体验。
  • 基本安全HTTPS预留签名扩展

4.2 能力范围

  1. 初始化
    • 校验并保存 SDKConfig
    • 自动采集 DeviceInfo
    • 初始化本地存储;
    • 启动定时 flush 调度(根据 flushInterval
  2. 事件写入track
    • 检查 SDK 是否已 init
    • 构造 Event
      • system_code from config
      • eventType from 调用
      • userInfo from setUser
      • clientType from config
      • clientTimestamp = 当前毫秒时间戳
      • timestamp = ISO8601 字符串
      • deviceInfo from 初始化采集
      • eventParamscustomTags from 调用
    • 事件入内存队列 + 异步持久化保存。
  3. 缓存与发送策略
    • 存储:
      • SQLite / KV + 索引;
      • 最大缓存条数:maxCacheSize,超限则删除最旧事件。
    • 发送:
      • 定时器触发 flush
      • 队列长度 >= batchSize 可立即 flush
      • 调用 AddEventListLog 批量上传;
      • 如后端明确不支持,可选降级 AddEventLog
    • 重试:
      • 网络错误或 5xx 重试,最多 maxRetryCount,指数退避;
      • 4xx 视为业务失败,不重试,直接丢弃该批,并记录错误(日志)。
  4. 安全与稳定
    • endpoint 必须为 HTTPS
    • 预留请求 header 扩展(签名 / 时间戳 / nonce
    • 所有 IO 和网络在后台线程 / async不阻塞 UI
    • 所有异常在 SDK 内部捕获,不向上抛出导致崩溃。

4.3 开发要求

通用:

  • 核心逻辑单元测试覆盖率 ≥ 80%(事件构造、缓存、上传、重试)。
  • 使用统一的日志前缀(例如 [AnalyticsSDK])。
  • API 文档齐全,含参数说明和示例代码。

Flutter

  • 不引入过重依赖,确保兼容常见 Flutter stable 版本;
  • 高频 track 时(例如 10 次/秒)主 Isolate 无明显卡顿。

Android

  • 支持主流 Android 版本(按照公司基线,例如 API 21+
  • 在 debug 版开启详细日志release 版关闭。

iOS

  • 支持主流 iOS 版本(例如 iOS 12+
  • 保证在 App 退后台 / 杀进程前能尽可能 flush。

4.4 Phase 1 验收标准

功能:

  • 三端均可: init → setUser → track → flush 全流程成功;
  • 离线:
    • 断网时事件成功写入本地;
    • 恢复网络后自动/手动 flush可在后端查看到补发数据
  • 批量:
    • 实际调用 AddEventListLog
    • 后端数据结构与约定一致(字段正确)。

稳定:

  • 连续调用 track 1 万次以内无崩溃;
  • 事件缓存满时按预期丢弃最旧数据,不影响业务。

安全:

  • 所有请求通过 HTTPS
  • 默认不输出包含 userInfo 的敏感日志(除非显式 enableDebug

文档:

  • 各端接入指南(集成、初始化、上报示例);
  • 一份基础 FAQ常见错误、排查方式

Phase 2可维护性 + 配置化 + 调试能力

5.1 目标

  • 降低埋点维护成本;
  • 支持通过后端配置管理事件和维度;
  • 提供调试和校验工具,提高埋点正确率。

5.2 能力范围

  1. 利用 GetSystemAllDimInfo 下发配置
  • SDK 在 init 后或定期调用:
    • 获取 systemInfosystemEventTypessystemCustonTas
  • 转换成本地配置对象,缓存到本地(带 version / lastModified

ts

type EventDefinition = {
  eventCode: string
  eventName: string
  description?: string
}

type TagDefinition = {
  tagName: string
  tagType: string    // string/int/bool/enum
  isRequired: boolean
  description?: string
}
  • 失败不影响事件发送(降级为无配置模式)。
  1. 事件校验
  • track 时(主要在 debug 模式启用):
    • 校验 eventType 是否存在于 systemEventTypes
    • 使用 systemCustonTas 检查:
      • 必填 tag 是否存在;
      • 类型是否匹配(尝试容错转换)。
  • 错误处理:
    • Debug 模式:
      • 在日志中详细打印:未注册事件、缺失字段、类型错误;
      • 可配置:是否禁止发送这类事件。
    • Release 模式:
      • 仍发送,但在 customTags 中附加:
        • _sdk_invalid_event
        • _sdk_missing_tags
        • _sdk_type_error_fields
  1. 调试工具
  • 日志级:
    • setDebug(true) 时:
      • 打印每条事件的 JSON
      • 打印发送结果(状态码、错误内容)。
  • Demo 内调试页面(建议):
    • 支持:
      • 查看缓存事件数量 / 最近 N 条事件摘要;
      • 按钮触发 flush。
  1. 队列与策略优化(基本)
  • 事件过期时间(例如默认 7 天);
  • 网络状态感知(原生):
    • Wi-Fi 下更高频 / 大批次;
    • 蜂窝网络下减少频率 / 批量。

5.3 开发要求

  • 新增模块:
    • ConfigManager:拉取与缓存后端维度配置;
    • Validator:统一事件校验逻辑。
  • 兼容 Phase 1
    • 未取到配置时,一切行为回退到 Phase 1 模式;
  • 增加测试:
    • 事件存在 / 不存在;
    • 必填字段缺失;
    • 类型错误时的行为。

5.4 Phase 2 验收标准

功能:

  • 初始化后,可以成功调用 GetSystemAllDimInfo 并本地缓存;
  • 在 debug 模式下:
    • 未配置的 eventType 调用时有明确日志提示;
    • 缺失必填 tag / 类型错误能被检测并打印提示。

调试体验:

  • 开发可以在本地:
    • 看到完整事件 JSON
    • 根据提示迅速发现埋点错漏。

可维护性:

  • 后端新增事件配置systemEventTypes 中新增)后,不发版即可在客户端调用新事件;
  • 对关键事件,可以通过配置 + SDK 校验,显著减少埋点错误。

Phase 3可观测性 + 动态策略 + 插件化

6.1 目标

  • 让 SDK 自身「可被监控、可被远程控制」;
  • 支持高级使用场景:采样、动态开关、插件扩展。

6.2 能力范围

  1. SDK 自身监控埋点
  • 内部采集 SDK 运行指标(作为特殊事件上报):
    • 发送成功计数 / 失败计数 / 重试次数;
    • 平均延迟;
    • 队列当前长度 / 溢出丢弃数;
  • 周期性上报(如每 N 分钟一次)。
  1. 动态策略控制
  • 通过配置(可在 GetSystemAllDimInfo 扩展,或单独接口)下发策略,如:

jsonc

{
  "enabled": true,
  "eventSettings": {
    "EVENT_A": { "enabled": true, "sampleRate": 1.0 },
    "EVENT_B": { "enabled": false, "sampleRate": 0.0 },
    "EVENT_C": { "enabled": true, "sampleRate": 0.1 }
  }
}
  • SDK 在 track 时:
    • 若事件被标记 enabled=false → 直接丢弃;
    • sampleRate < 1 → 按采样率丢弃部分事件(哈希或随机)。
  1. 插件 / 拦截器机制
  • 接口示例(通用设计):

ts

interface EventInterceptor {
  beforeSend(event: Event): Event | null | Promise<Event | null>
  afterSend(event: Event, result: SendResult): void | Promise<void>
}
  • SDK 提供:
    • registerInterceptor(interceptor) / addInterceptor 方法;
    • 内置拦截器debug 打印、公共字段填充等。

典型用途:

  • 业务统一追加自定义 customTags(如租户 ID、业务线 ID
  • 将部分发送失败事件写入本地日志,便于问题排查。
  1. 版本管理
  • 事件级 schemaVersion 预留:
    • customTagseventParams 中加入 _schema_version
  • SDK 版本上报:
    • 每条事件默认携带 _sdk_version_platform,便于后端统计版本分布。

6.3 开发要求

  • 性能:
    • 插件链路运行开销可控(单条事件处理在毫秒级以内);
  • 隔离:
    • 单个插件抛出的异常不会影响主流程和其他插件;
  • 文档:
    • 清晰说明策略配置字段及含义;
    • 插件开发 & 使用指南。

6.4 Phase 3 验收标准

  • 自监控:
    • 后端可以查看 SDK 的发送成功率、失败率、队列长度等;
  • 动态控制:
    • 通过配置关闭某个 eventType 后,客户端不再上报该事件;
    • 调整 sampleRate 后,事件量按预期变化;
  • 插件:
    • 样例插件能实现:
      • 自动附加业务 tag
      • 记录失败事件到本地日志。

这版方案已经:

  • 明确Flutter 为独立纯 Dart SDK与 Android/iOS 平行;
  • 统一:三端对外 API、数据结构、阶段目标和验收标准
  • 预留:维度配置、校验、动态策略、插件机制的扩展空间。