前端监控的设想
序言
2024年,年后上班的第一个周一,当我正在办公室把思绪从过年的喜悦转换到工作中时,车委会主任在工作群中反馈了一个关于驾驶员在小程序中无法提交加油记录的问题。
看到这个问题,我第一时间想的是如何去判断这个问题是如何发生的,是哪位驾驶员,什么时间,填写了哪些信息,上传了哪些图片,网络情况如何,发生的次数和频率大不大。
基于第一时间的判断,我开始了按图索骥,开始让车委会把截图发过来,从手机截图上看网络是没有问题的,并且图片上传是成功的,填写的表单也及其简单。
那么,问题处在哪里呢?
困境
于是开始查找那个时间在服务端发生的事情,通过查看日志,一无所获 ;更艰难的问题是,我们无法设身处地地调试驾驶员的微信小程序,这做不到。
更致命的是,过去的经历和经验,到现在,我们大都如此,一但前端用户出现了难以预测的问题,我们都难以判断为什么,甚至连基本的信息都没有。
基于以上困境,我们在设想一个解决我们当前困境的应用,这个应用能够让我们明白前端用户使用过程中问题是如何发生的。
这个目标在设想的时候是比较模糊的,我们只知道一些最基本想要达到的功能,并没有考虑实施路径,实施方法,、与之配套的开发工具、管理方法、管理办法和管理能力。
但是我们还是从最基本的设想开始,来满足当前需求、探索未知的领域。
设想
正如前面所描述的,我们有一个明晰的困境;我们至少可以通过分析去解决它。
基本需求
用一句话描述基本需求就是:安全可靠地让我们知道哪个应用的哪个用户用什么设备在哪个页面执行哪个操作时遇到了哪个错误和这个错误的堆栈信息。
1. 元数据
让我们来更具体地分析这句话,这个信息的元数据如下:
- 应用。
- 设备信息。
- 页面,也可以叫路由。
- 执行的操作。
- 错误信息。
- 错误堆栈。
- 发生时间。
2. 认证
另外一个关键的因素是“安全可靠”,即便是最简单的认知,我们也需要对接入这个系统的应用做认证。为了完成认证,我们也需要完成认证设计、认证实现和认证工具:
- 认证设计。我们使用最简单的token和签名模式,客户端使用服务端发布的Token结合内置的签名方法生成特定的认证信息,客户端向服务端报送错误信息时必须携带此认证信息,服务端按“内置的签名方法生成特定的认证信息”客户端传入的认证信息比对,比对成功则认为认证是有效的。
- 认证实现。认证实现的要素主要有四个:token、当前时间戳秒数、随机字符串、设备信息。使用按特定规则排序并生成字符串,使用MD5对该字符串进行处理得到签名。服务端在处理认证信息和认证要素时,主要判断token是否存在于服务端,客户端的当前时间戳秒数与服务端的当前时间戳秒数差在特定范围内,按照约定的签名方法生成的签名是否一致。
- 认证工具。认证工具是认证实现在编程语言层面的实现,主要提供Typescript SDK,服务端则无需提供SDK.
完成了认证,核心之一是如何将我们想要的内容存储、分析和展示。
3. 存储
存储的核心如何设计数据结构,基于上述对需求的分析,我们可以设计以下几张表:
应用表 - t_application
字段 | 类型 | 唯一 | 索引 | 说明 |
---|---|---|---|---|
id | int unsigned | Y | 自动 | 自增主键 |
name | varchar(64) | Y | 唯一索引 | 应用名称 |
token | varchar(32) | Y | 唯一索引 | 应用Token |
enable | boolean | N | N | 是否启用,默认启用 |
created_at | int unsigned | 创建时间戳 | ||
updated_at | int unsigned | 更新的时间戳 |
认证记录表 - t_auth_record
字段 | 类型 | 唯一 | 索引 | 说明 |
---|---|---|---|---|
id | int unsigned | Y | 自动 | 自增主键 |
application | id int unsigned | Y | 应用ID | |
application_name | varchar(64) | Y | 应用名称 | |
success | boolean | 是否成功 | ||
meta | json | 认证要素json | ||
created_at | int unsigned | 认证时间 |
错误日志表 - t_system_err
字段 | 类型 | 唯一 | 索引 | 说明 |
---|---|---|---|---|
id | int unsigned | Y | 自动 | 自增主键 |
application | id int unsigned | Y | 应用ID | |
application_name | varchar(64) | Y | 应用名称 | |
auth | int unsigned | 认证ID | ||
device_info | text | 设备信息 | ||
path | text | 页面或路由 | ||
action | varchar(64) | 操作名称 | ||
message | text | 错误信息 | ||
trace | long text | 错误堆栈 | ||
timestamp | int unsigned | 发生时间 | ||
created_at | int unsigned | 上传时间 |
对于数据存储,还需要有存储入口,那么对应的是服务端路由、中间件和控制器时间。
现假设:
- 上报错误信息的路由为:
/api/v1/record/error。
- 认证中间件名称为:
AuthApplication。
- 控制器名称为:
RecordError。
对于存储入,只需要实现认证中间件和控制器即可。
4. 分析和展示
分析和展示的目的在与管理,让我们清晰地从不同维度了解发生了什么错误,为运营、开发、运维提供支撑和支持。
基本地,必须有一个所有错误信息的列表。这个列表展示了系统上线至今客户端上报的所有错误信息。并且可以按元数据进行筛选。
进一步,要有分析功能,在与按元数据的维度对数据进行分类统计。例如,分析常上报问题的应用、常出现的问题、常出现问题的设备、常出现问题的页面、常出现问题的时段等等。分析功能通常以图表的形式展示。
5. 管理
除了以上所描述的,能够支撑系统运行的是对系统的管理。管理一般可以简单的分为:
- 应用管理。
- 数据管理。
- 提醒管理。
应用管理
应用管理的职能在于,能够让系统管理员完成应用的创建和更新。创建系统所需要的数据在存储章节中已有描述;除了数据和存储,还需要有两个页面实现对应用的管理:
- 应用列表页面。该页面展示的是存在于系统的应用信息,并可以实现对应用的编辑;可编辑的信息包括:应用名称、准入Token、是否启用。
- 创建应用页面。该页面是创建一个应用的表单页。
数据管理
数据管理主要实现应用开发者和运维的对于数据的需求。
运维人员需要定期了解应用的运行情况,以指定更有效的运维策略;而开发者则可以通过错误数据对应用做进一步开发和改进。
此部分应该和数据分析结合,结合数据导出功和其他能力,可以定期或不定期向对监控数据相关人进行报告。
提醒管理
提醒管理的重点在于,让开发者、运维人员及时了解、及时定位问题,为运营提供直接有效支持。
提醒的方式有多种:
- 短信提醒。
- 邮件提醒。
- 站内信提醒。
优先级而言,短信提醒是最高的,且是最有效的,特别是非工作时间。
5. 总结
应用源于需求,需求源于现实问题。线下运营还是线上运行皆如此。如果需求是设想出来的,那么设计来系统可能是逻辑自洽,用起来实际上很鸡肋的。
以模糊需求、明确需求、最小化开发、最小化应用、需求扩张、系统成型的逻辑来看,螺旋式开发是比较符合前端监控系统的开发方式。
一是需求明确,且暂无扩展。
二是开发周期短,明确可控。
三是对其他业务也系统的开发影响较小,对其形成的影响也是渐进式的。
作为一个技术管理者,应该清醒地认识到,技术设计和实现应该围绕三段式进行,即:运行基础、运营基础、运营。所有技术活动,都要有明确的运营目标和运营活动,因此有明确的需求,这种需求可能源于过往的经历和经验,也有可能是对当前和未来的判断。围绕明确的运营需求,才能构建有效的运营技术应用体系,即运营基础。以运营基础需求为基点,再反向构建运行基础,形成由基础设施、运营设施、业务运营三者螺旋关联的三段式结构。