# 全链路日志系统

## 概要

监控就是更好地理解系统，让我们可以根据实际情况做出最优的决策，提升产品的服务质量，最终提高用户的满意度。

**一条链路日志，不应该被过度设计**，遵循最少字段原则可以减少服务器端的存储空间，降低研发成本，从而实现得不偿失的效果。

## 信息结构

### 1. 基本日志信息

- 日志 ID (UUID) 该条日志的唯一标识（由客户端生成）
- 日志类型：
  - PV/UV
  - 事件
  - 性能
  - 资源
  - 交互（动作、行为）
  - 请求
  - 代码错误
  - 日志打印
  - 自定义
- 日志产生时间（客户端生成）
- 日志更新时间（客户端生成）

### 2. 浏览器信息

- UserAgent
- 浏览器类型:
  - PC
  - Mobile
  - webview
  - min program

### 3. 页面信息

- 页面 ID (UUID) 页面唯一标识（由客户端生成）
- 页面标题（根据需求填写）
- 页面 URL

### 4. 用户信息

- 用户指纹（由客户端生成，用于关联用户未登录到已登录的操作日志）
- 用户 ID （可选）
- 用户名称（可选）
- 用户邮箱（可选）
- 用户电话（可选）

### 5. 业务信息

- 业务 ID
- 业务名称（可选）
- 客户端类型
  - 安卓
  - iOS
  - PC
  - 浏览器
- 日志级别
  - 告警(error)
  - 预警(warn)
  - 普通(info)
  - 调试(debug)

## 数据模型

### 1. 异常信息

- 代码异常错误类型
- 请求类型
- Promise 类型
- 资源类型
- 普通日志类型
- PV/UV 类型

### 2. 操作行为

### 3. 页面性能

## 性能指标

### 1. 网加载速度指标页 (LCP) 

    是指可视区域最大元素呈现时间，可能是一张图片，一个视频、一段内容块。
    
    对于处在弱网环境下的用户很影响网页加载速度。

### 2. 网页可交互指标（FID）

    是指用户首次和 Web 应用互动到浏览器实际开始处理事件或者处理脚本，响应用户互动的这段时间。

  **LCP 是衡量感受 Web应用加载速度的第一印象的话，那么 FID 就是衡量你和 Web 应用互动的第一印象。一个侧重加载，一个侧重互动。**

  **Google 官方建议为了保证用户的良好体验，可以通过总记录量排序的第 75 百分位来衡量 LCP。**

    如果一个页面的总访问量是 1000PV，那么 LCP 一共会监测和收集到 1000 份指标数据。
    
    我们基于这 1000 份指标数据重新整理顺序，按从低到高进行排序。那么，第一条肯定是最少的时间，最后一条数据是最大值，假设我们的第一条数据是 500ms。最后一条的时间是 5000ms，也就是 5 秒。
    
    按照第 75 百分位来衡量的话，那么排在 750 位置的指标数据，就是判断的基准。我们假设这个位置的时间是 3.5s，按照我刚才说的判断性能好不好的方式，3.5s 说明当前的页面可能存在性能问题，就需要优化和改进。

### 3. 网页视觉稳定性指标（CLS）

    是指用户在交互期间，内容布局发生偏移，即在浏览器可视区内现有元素发生位置的改变。

    CLS 是衡量在一个 Web 应用的整个生命周期内，发生每次意外布局偏移的最大布局偏移分数。

  1. 不稳定的元素。元素是指在浏览器可视视口内可见的内容对应 DOM 节点，不稳定是指这个可见元素在上一帧和当前帧产生的起始位置的变化。所以，不稳定的元素，一定是首屏内第一眼可见的页面内容对应的一个或多个元素。
  2. 影响比例。它是衡量出现不稳定的元素对于前后变化，对可视视口区域的影响程度。
  3. 距离分数。它是测量这个不稳定元素相对于可视视口区域内的移动距离。

  **公式：布局偏移得分 = 影响比例 x 距离分数**

  **CLS = Max(布局偏移得分 1, 布局偏移得分 2, 布局偏移得分 3, ……)**

### 4. 首次内容绘制（FCP）

    是指用户初次可见的内容绘制时间，FCP 指标预示着用户从输入一个链接到真正看到第一个画面所花费的时间。立刻看到有内容渲染的时刻，能让用户清楚地知道 Web 应用是可访问的、可使用的、可以交互的。通过 FCP，我们也能粗略评估出当前页面的白屏时间。

  **FCP 的时间必定小于 LCP，在 FCP 和 LCP 之间的时间差里，就是浏览器持续性地渲染加载页面内容，又或者在执行脚本的过程。**

### 5. 互动响应速度（INP）

    用来监听用户交互互动到页面响应的延迟时间。如果用户在一个页面内的多次互动，那么 INP 会记录多个指标数据，并以最长延迟时间的那一次互动作为最终值。

    例如：手风琴折叠导航栏、多层级菜单、表单验证多层级菜单、表单验证等

    只有需出现交互场景才会监测和记录 INP，所以，像是页面已经加载完毕，但用户没有点击或操作表单的时候，或者是在移动端，网页加载完毕，但用户的手势在互动操作里不涉及点击、点按或输入框输入等操作的时候，就不会有 INP 值的记录。
    
    又例如搜索引擎收录页面、无头浏览器访问的时候，这种非实际用户访问的场景，基本上也不会存在 INP 值。

### 6. 可交互时间（TTI）

    衡量从网页开始加载到其主要子资源加载完成的时间。从定义上看，这个时间比 FCP 更靠前。

    目前仍然是一个实验性指标。

### 7. 总阻塞时间（TBT）

    在基于 FCP 时间之后，页面会发生很多不同场景的事件，比如渲染内容、请求接口、主线程脚本执行等。而在这个时间范围内，可以定义一个用于衡量事件或任务的总阻塞时间。

    比如请求接口次数太多、组件不断重新渲染、重排重绘、页面加载卡顿等等。

    这种性能问题，归根到底都是事件或任务运行时间很长，特别是在浏览器主线程上执行的代码。通常一个任务的执行时间建议不超过 50ms，如果超过，会被主线程视为“阻塞”。这种任务，我们可以理解为长任务。

    一个任务运行时间为 250ms，如果按 50ms 的标准去衡量，这就是一个长任务，最终这个任务的阻塞时间就是 200ms（阻塞时间 =250ms-50ms）。最终的 TBT 时间是取多个相邻任务减去 50ms 后的时间的总和。

    通常我们都是在开发环境下的 Google DevTool 上进行总阻塞时间 TBT 的分析，又或者是在 Lighthouse 性能工具中分析。目前还没有一套可行的通过脚本去分析和计算出这样的指标的方案。

### 8. 首字节时间（TTFB）

    是资源请求与响应的第一个字节开始到达之间的时间。TTFB 就是衡量 Performance.startTime 和 Performance.responseStart 之间的间隔时间。

    通常能影响到这个 TTFB 时间的因素有很多，比如多个页面的重定向时间，DNS 查找时间，连接和 TLS 协商时间等等。
    
    虽然 TTFB 并不是核心网页指标，但它是衡量 Web 应用可用性的 最重要的参考指标。它能帮助我们分析和评估在到达用户设备之前的网络状况。

## 指标衡量

|  指标 | 体验好|   需要改进    |  体验差  |
|------|-------|--------------|----------|
| LCP  |< 2.5s |  2.5s - 4s   |  > 4s    |
| FID  |< 100ms|100ms - 300ms | > 300ms  |
| CLS  |< 0.1  | 0.1 - 0.25   | > 0.25   |
| FCP  |< 1.8s | 1.8s - 3s    |  > 3s    |
| INP  |< 200ms|200ms - 500ms | > 500ms  |
| TTFB |< 800ms|800ms - 1800ms| > 1800ms |