SDK 事件日志记录
整理 SDK 在无需用户代码的情况下自动收集并发送到平台的运行时事件。重点不是我应该埋点什么, 而是已经在埋点什么的文档。
如何开启
Runtime/Helpers/AIT.PerformanceLogger.cs中的 AITPerformanceLogger会 [RuntimeInitializeOnLoadMethod(BeforeSceneLoad)]会自动初始化。无需安装或调用。
发送仅在 WebGL 构建中 发生。在 Unity Editor 和其他平台中, SendLog会在进入后立即返回,因此既不会创建事件,也不会发送出去。因为桥接只存在于 WebGL 构建中。
所有事件的 log_type是 unity_runtime,事件类型则用 log_name区分。
事件类别
unity_scene_transition
SceneManager.sceneLoaded / sceneUnloaded
无
unity_first_interactive
原始首个场景加载完成
每个会话 1 次
unity_low_memory
Application.lowMemory
每 30 秒 1 次
unity_error
Application.logMessageReceived (Error/Exception/Assert)
每 60 秒 10 次 + 去重
unity_lifecycle
AITVisibilityHelper.OnVisibilityChanged, Application.quitting
focus_changed:每 5 秒 1 次
unity_frame_stall
Time.unscaledDeltaTime > 500ms
每 60 秒 5 次
unity_screen_change
Screen.width/height/orientation 检测到变化
每 2 秒 1 次
unity_gc_collection
GC.CollectionCount(0) 检测到变化
每 60 秒 5 次
unity_timescale_change
Time.timeScale 检测到变化
每 5 秒 1 次
通过轮询检测的项(frame_stall, screen_change, gc_collection, timescale_change)由专用的 AITPerformanceLoggerMonitor GameObject 的 Update中每帧检查。该对象因 HideAndDontSave + 、DontDestroyOnLoad而不会显示在 Hierarchy 中,并会在场景切换时存活。
注意:焦点事件不是来自
Application.focusChanged,而是来自 SDK 自身的AITVisibilityHelper。在 WebGL 中,这是因为浏览器标签页可见性才是真正的信号。
各事件参数
所有事件都包含以下公共参数。
event_type
同一 log_name 中区分细分类型
time_since_start_sec
应用启动后的经过时间(保留 1 位小数)
unity_first_interactive仅此例外, time_since_start_sec 改用 time_since_start_ms。
unity_scene_transition
event_type
scene_loaded 或 scene_unloaded
总计
scene_name
场景名称
总计
scene_build_index
Build Settings 索引
总计
load_mode
Single 或 Additive
仅 scene_loaded
previous_scene
之前加载的场景名称
仅 scene_loaded
total_loaded_scenes
当前已加载的场景数(SceneManager.sceneCount)
总计
unity_first_interactive
这是衡量原始首个场景加载完成时点、也就是游戏实际可操作的瞬间的事件。每个会话只发送一次。
触发判定有两个规则。
AITProxyBoot开头的场景会被跳过。 因为 SDK 注入的代理启动场景并不是游戏原本的首个场景。无论是否激活,都会在最初的目标场景中确定“首次”。 即使关闭日志记录,该场景中的标记也会被固定,因此之后加载的场景不会被事后报告为 first。
激活状态会在构建时先通过 jslib 查询一次模板中写入的值并缓存。查询失败时 视为已激活。
注意:启动首个场景的加载发生在 first-paint 之前,因此在没有额外优化的构建中,这个值几乎会与 first-paint 时间一致。若两项指标的间隔变大,则说明首个场景变重了。
unity_low_memory
unity_error
event_type
error, exception, assert
message
错误消息(截断为 500 字)
stack_trace
堆栈跟踪(截断为 200 字)
log_type
Unity LogType (Error, Exception, Assert)
去重是 在 60 秒窗口内按消息哈希进行的。相同消息在窗口内重复出现时,只发送第一条;窗口过去后哈希集合会清空并再次上报。即使堆栈跟踪不同,只要消息相同也视为相同。
unity_lifecycle
total_scenes_loaded是会话期间加载的 累计 场景数, unity_scene_transition中的 total_loaded_scenes(与当前同时加载数不同)。
unity_frame_stall
判定基准不是 Time.deltaTime,而是 Time.unscaledDeltaTime。将 Time.timeScale 设为 0 的暂停区间不会被算作卡顿。
unity_screen_change
当尺寸和方向同时变化时 orientation_change 只会发送一个事件。旋转通常会伴随尺寸变化,因此避免两个事件重叠发送。
unity_gc_collection
检测 只看 gen0 计数器变化 。 generation generation 值是通过 gen1/gen2 累计计数推算出来的,因此无法准确指出本次采集实际属于哪一代。而 gen*_total是自进程启动以来的累计值,因此这些值更值得信赖。
unity_timescale_change
在调试控制台中查看
开启调试控制台后,可通过屏幕左下角按钮打开控制台,并在 指标 标签中直接查看这些事件。会显示事件列表和按类别累计的计数,因此无需查看平台仪表盘也能立刻确认埋点是否在运行。
调试控制台在 Dev Server 配置文件中默认启用,在其他配置文件中也可通过 构建配置中的 AIT_DEBUG_CONSOLE 环境变量开启。
注意:类别计数表会以子字符串方式匹配上方 8 个类别名称。
unity_first_interactive它不会命中其中任何一项,因此会在表格下方作为单独一行显示。不是遗漏,而是分类方式不同。
安全措施
try-catch
包裹所有处理器,确保日志失败不会让游戏停止
防止重入
_isSending 作为守卫 logMessageReceived → SendLog → 警告日志 → logMessageReceived 阻止无限循环
限流
通过按类别固定上限防止过量发送
字符串截断
将错误消息·堆栈跟踪截断为固定长度
重入守卫尤其重要。 SendLog在 WebGL 以外环境中 Debug.LogWarning不使用它的原因也是一样——一旦记录警告,该警告又会再次 logMessageReceived通过它进入。
相关文档
这有帮助吗?