撸了一个前端的日志工具

2016-12-08 01:07:42 +08:00
 latelx

项目:https://github.com/latel/logline,欢迎关注和 star 。

从事 Web 前端同学对此肯定深有体会,代码发出去之后,犹如脱缰的野马,运行在万千的客户终端上,等到产品和后台反馈问题到我们这边,很多时候定位问题只能靠猜,尤其是一些偶发诱因,因为根本不知道用户是如何操作的,真实环境遇到的问题通常是很多随机因素叠加的形成的,因此很难回放用户的操作来还原现场找到原因。

现在的痛点

经过一段时间经验的累积,我们想到,如果我们有一个同后台一样详实的可分类和检索的代码运行日志,无疑将会提供巨大的帮助。

我们的探索

一个健壮的日志系统大致包含日志记录、日志上传和日志分析三个主要部分,在这次的实践中,我们对这三方面都有所探索。

日志到底存哪里?

由于前端受到很多限制,不能同 APP 一样可以在文件沙箱内存取文件,因此如何持久化的存储日志成了一个问题。目前 H5 也支持若干种本地存储方案, cookie, localStorage, indexedDB 和 websql 等,其他的由插件提供的能力不在考虑的范围之类,如 flash ,移动端的可用性会是一个很大的问题。

什么样的日志格式堪称优雅?

日志怎么获取?

由于我们并不需要实时的获取来自客户端的大量日志,因此日志是存储在用户客户端本地的,我们需要后台配合开发一个用于接收客户端通过网络上传的日志内容并存储起来的接口。同时可能要考虑一些安全性问题,如引入 token 机制和验证登录态等等。目前我们腾讯微证券采用的方案为:用户在微信公众号中发送消息“问题反馈”(直接使用日志上报等关键词可能会引起用户的反感),后台会返回日志上传页面地址链接,用户点击链接进入后,在获取登录态后自动上报日志。大家可以微信关注腾讯微证券公众号尝试一下。

日志如何分析?

由于 Logline 上传的日志格式符合标准,具有良好的可阅读性,因此我们可以在某种程度上直接使用命令行工具或者编辑器来阅读。但是对命令行不熟悉的用户使用可能仍然有困难,因此有必要使用 Web 技术栈搭建一个易于使用并且视觉良好的工具。我们希望这套工具可以不依赖与后端,既可以部署在服务器端,也可以当做本地网页直接双击打开,也可以被简单的包一层外壳而当做桌面 APP 来使用。

作为日志,承载的最主要的内容便是大量的纯文本,在调研了一些方案后,我们认为 H5 规范中的 FileReader.readAsText 可以很好的做到这一点,结合拖放事件,我们便可以很大致构建出一个不错的方案:用户将一个或者多个日志文件拖放至网页中,即可对这些日志批量分析和检索。

我们构建了一个仅供体验的版本 logline-viewer

Logline

基于以上工作,我们腾讯微证券项目组推出了自己的解决方案:Logline,一个轻量,实用和客户端级的前端日志记录工具。

DEMO

http://kezhen.info/logline/example/

应用场景

特性支持

快速上手

1. 安装

通过 bower

bower install logline

直接下载

访问 https://github.com/latel/logline/releases,选择需要的版本下载,引入自己的项目。

2. 引入脚本

Logline 支持直接使用 script 标签引用,也支持 AMD 模块加载器.

// Script 标签引入方式
<script src="./mod/logline.min.js"></script>
<script>
	// 使用 indexedDB 协议
	Logline.using(Logline.PROTOCOL.INDEXEDDB);
</script>

// AMD 模块方式
var Logline = require('./mod/logline.min');

3. 选择日志协议

目前一共支持三个协议, 三个协议都被直接挂载在 Logline 对象上以便一些特殊的应用场景,也更好的符合语义化:

你可以在引入 Logline 之后,使用 using 主动选定一个期望使用的日志协议。

Logline.using(Logline.PROTOCOL.WEBSQL);

如果你没有提前选择一个日志协议,那么当你调用 Logline 的相关 API 时, Logline 会根据你在构建时给定的参数作为优先级来选择可用的优先级最高的协议。 比如你的自定义构建命令是npm run configure -- --with-indexeddb --with-websql --with-localstorage, 如果 indexeddb 协议可用,那么 indexeddb 将作为自动选择的协议。 如果 indexeddb 协议不可用但是 websql 协议可用,那么将选择 websql 协议,如此类推。 如果最后发现所有的协议都不可用,将会抛出错误。

4. 记录日志

// 不同的模块使用不同的日志会话
var spaLog = new Logline('spa'),
	sdkLog = new Logline('sdk');

// 不包含数据的,描述为 init.succeed 的记录
spaLog.info('init.succeed');

// 包含错误描述数据,描述为 init.failed 的记录
spaLog.error('init.failed', {
	retcode: 'EINIT',
	retmsg: 'invalid signature'
});

// 不包含数据的,描述为 outdated 的记录
sdkLog.warning('outdated');

// 包含错误描述数据,描述为 system.vanish 的记录
sdkLog.critical('system.vanish', {
    // debug infos here
});

5. 读取日志

Logline.getAll(function(logs) {
    // process logs here
});

6. 清理日志

Logline.keep(.5); // 保留半天以内的日志,如果不传参则清空日志
Logline.clean(); // 清空日志并删除数据库

7. 自定义数据库名

由于 indexeddb, websql 和 localStorage 都是同域共享的,这时候 Logline 默认的数据库名 logline 可能会已经被占用,需要指定一个新的数据库名。 可以通过下面 2 个方法指定数据库名。

// 调用`using`时,同时指定第二个参数作为数据库名
Logline.using(Logline.PROTOCOL.WEBSQL, 'newlogline');

// 调用`database`来指定数据库名
Logline.database('newlogline');

自定义构建

目前 Logline 一共实现了localstoragewebsqlindexeddb三个日志协议,默认是全部打包,可能你只想使用其中某个协议而已,你可以通过npm run configure来自定义构建你需要的版本。这样有利于减小包的大小。

// 不跟参数默认构建所有协议
npm run configure
// 配置你需要的协议,去掉不需要的协议申明--with-xxx
npm run configure -- --with-localstorage --with-websql --with-indexeddb
// 重新打包
npm run build
// 去 dist 目录寻找新构建的打包文件

我们都在用

在腾讯微证券中使用的案例

开户流程监控

开户流程作为核心的流程之一,一直以来都有着比较完善的监控数据,在某次改版之后,我们发现用户开户提交失败的比例有着显著的上升,很多用户在最终提交开户资料时,后端校验发现某些用户资料尚未被设置这种情况很让我们困惑。也是促使我们开发这个工具原因。在部署了 Logline 这套方案后,我们在开户流程的代码中添加了较为详实的日志记录,并在出错的情况下主动上报日志到后端。发现是在某些机型中,用户点击下一步后,全局的 loading 遮罩显示较慢,导致用户快速连续 2 次点击了下一步,导致开户流程控制器连续 2 次触发下一步操作,使得某些页面被跳过导致。

修复 JS 报错

目前和财付通很多前端产品一样,我们接入了财付通统一日志上报平台,但是我们上传的内容很有限,访问性能也不是很好,也没法看到 js 错误的调用队列,甚至没法看到用户的 useragent 。在使用我们自己的 Logline 上报系统后,这一切都得到了解决,发现了一些由微信 jssdk 自身产生的错误如 'WeixinJSBridge is not defined'和一些上报量比较大的 js 错误,有效的保证了代码的质量,甚至还可以做一个错误实时曲线统计。

基于配置的主动抓取

由于产品正处于快速的功能迭代中,目前不论是业务代码还是核心模块的代码都会经常被改动,不可避免的会产生一些意想不到的问题。有时候,我们会去找到用户希望用户配合帮忙定位问题,但是并不是所有的用户都会愿意配合。于是我们设计了一套主动抓取用户日志的策略:在我们的产品页面被打开后,会延时一定的时间去下载一个 logcat.json 的文件,文件中会包含我们期望可以主动上报日志的用户列表,当和用户吻合时,该用户的日志将会被自动上传。在需要的时候,我们只需要维护这样一个配置文件即可,当配置中的用户日志被上传后,我们将会受到一封邮件提醒。也可以使用此配置文件来配置客户端 JS 是否要自动上报 js 错误。

CONTRIBUTING

我们相信前端的社区应该是开放和合作的。

Logline - 日志记录和上报模块

logline

Logline-viewer - 日志分析平台

logline-viewer

WIP

[ ] 不使用 webpack 编译,以减小打包文件的大小 [√i] 加入 bower 包管理器 [ ] 丰富英文代码注释 [ ] 完善错误处理细节 [ ] 测试环境由 jsdom 迁移至 phantomjs [ ] 优化存取结构

未来规划

在这次的实践中,我们有意保持模块的独立性,并没有使用任何外部依赖,因此很容易复用到别的业务或者绑定自己的业务逻辑。不过在未来,我们更喜欢 Logline 作为前端日志的一整套解决方案提供,而无需业务在上传和分析部分要做出自己的实现。

更为可用的应用场景应该是业务放在我们的平台上申请一个 appid ,然后使用我们的统计脚本,所以日志将统一上报到我们的平台,业务方可以使用此 appid 在我们的系统中浏览、分析和检索所需的日志。

本方案使用的技术和实现难度并不困难,重要的是一种解决痛点的思路。

4202 次点击
所在节点    JavaScript
4 条回复
Laygle
2016-12-08 01:14:28 +08:00
很强大,解决了很多人的困扰啊,感谢分享。
peneazy
2016-12-08 06:44:45 +08:00
mark
wensonsmith
2016-12-08 09:11:56 +08:00
不错,正需要用到,研究下
jsq2627
2016-12-08 10:36:21 +08:00
mark

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/326064

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX